Commit 21061c57 authored by Marc Gravell's avatar Marc Gravell

better cleanup of socket / pipe

parent babd03cb
...@@ -73,7 +73,6 @@ private static readonly Message ...@@ -73,7 +73,6 @@ private static readonly Message
private IDuplexPipe _ioPipe; private IDuplexPipe _ioPipe;
private Socket _socket; private Socket _socket;
private SocketAsyncEventArgs _socketArgs;
public PhysicalConnection(PhysicalBridge bridge) public PhysicalConnection(PhysicalBridge bridge)
{ {
...@@ -105,25 +104,28 @@ internal async void BeginConnectAsync(TextWriter log) ...@@ -105,25 +104,28 @@ internal async void BeginConnectAsync(TextWriter log)
bridge.Multiplexer.LogLocked(log, "BeginConnect: {0}", Format.ToString(endpoint)); bridge.Multiplexer.LogLocked(log, "BeginConnect: {0}", Format.ToString(endpoint));
var awaitable = new SocketAwaitable();
_socketArgs = new SocketAsyncEventArgs
{
UserToken = awaitable,
RemoteEndPoint = endpoint,
};
_socketArgs.Completed += SocketAwaitable.Callback;
CancellationTokenSource timeoutSource = null; CancellationTokenSource timeoutSource = null;
try try
{ {
if (_socket.ConnectAsync(_socketArgs)) var awaitable = new SocketAwaitable();
{ // asynchronous operation is pending
timeoutSource = ConfigureTimeout(_socketArgs, bridge.Multiplexer.RawConfig.ConnectTimeout); using (var _socketArgs = new SocketAsyncEventArgs
} {
else UserToken = awaitable,
{ // completed synchronously RemoteEndPoint = endpoint,
SocketAwaitable.OnCompleted(_socketArgs); })
{
_socketArgs.Completed += SocketAwaitable.Callback;
if (_socket.ConnectAsync(_socketArgs))
{ // asynchronous operation is pending
timeoutSource = ConfigureTimeout(_socketArgs, bridge.Multiplexer.RawConfig.ConnectTimeout);
}
else
{ // completed synchronously
SocketAwaitable.OnCompleted(_socketArgs);
}
} }
// Complete connection // Complete connection
try try
{ {
...@@ -132,8 +134,11 @@ internal async void BeginConnectAsync(TextWriter log) ...@@ -132,8 +134,11 @@ internal async void BeginConnectAsync(TextWriter log)
if (ignoreConnect) return; if (ignoreConnect) return;
await awaitable; // wait for the connect to complete or fail (will throw) await awaitable; // wait for the connect to complete or fail (will throw)
timeoutSource?.Cancel(); if (timeoutSource != null)
{
timeoutSource.Cancel();
timeoutSource.Dispose();
}
if (await ConnectedAsync(_socket, log, bridge.Multiplexer.SocketManager).ForAwait()) if (await ConnectedAsync(_socket, log, bridge.Multiplexer.SocketManager).ForAwait())
{ {
bridge.Multiplexer.LogLocked(log, "Starting read"); bridge.Multiplexer.LogLocked(log, "Starting read");
...@@ -181,6 +186,10 @@ internal async void BeginConnectAsync(TextWriter log) ...@@ -181,6 +186,10 @@ internal async void BeginConnectAsync(TextWriter log)
} }
throw; throw;
} }
finally
{
if (timeoutSource != null) try { timeoutSource.Dispose(); } catch { }
}
} }
private static CancellationTokenSource ConfigureTimeout(SocketAsyncEventArgs args, int timeoutMilliseconds) private static CancellationTokenSource ConfigureTimeout(SocketAsyncEventArgs args, int timeoutMilliseconds)
...@@ -233,23 +242,14 @@ private bool IncludeDetailInExceptions ...@@ -233,23 +242,14 @@ private bool IncludeDetailInExceptions
partial void ShouldIgnoreConnect(ref bool ignore); partial void ShouldIgnoreConnect(ref bool ignore);
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
internal void Shutdown() internal void Shutdown()
{ {
var ioPipe = _ioPipe;
var socket = _socket; var socket = _socket;
_ioPipe = null;
socket = null; socket = null;
if (socket != null)
{
try { socket.Shutdown(SocketShutdown.Both); } catch { }
try { socket.Close(); } catch { }
try { socket.Dispose(); } catch { }
}
try { using (_socketArgs) { } } catch { }
}
public void Dispose()
{
var ioPipe = _ioPipe;
_ioPipe = null;
if (ioPipe != null) if (ioPipe != null)
{ {
Trace("Disconnecting..."); Trace("Disconnecting...");
...@@ -257,18 +257,28 @@ public void Dispose() ...@@ -257,18 +257,28 @@ public void Dispose()
try { ioPipe.Input?.Complete(); } catch { } try { ioPipe.Input?.Complete(); } catch { }
try { ioPipe.Output?.CancelPendingFlush(); } catch { } try { ioPipe.Output?.CancelPendingFlush(); } catch { }
try { ioPipe.Output?.Complete(); } catch { } try { ioPipe.Output?.Complete(); } catch { }
ioPipe.Output?.Complete();
try { using (ioPipe as IDisposable) { } } catch { }
}
if (socket != null)
{
try { socket.Shutdown(SocketShutdown.Both); } catch { }
try { socket.Close(); } catch { }
try { socket.Dispose(); } catch { }
} }
try { using (ioPipe as IDisposable) { } } catch { } }
if (_socket != null) public void Dispose()
{
bool markDisposed = _socket != null;
Shutdown();
if (markDisposed)
{ {
Shutdown();
Trace("Disconnected"); Trace("Disconnected");
RecordConnectionFailed(ConnectionFailureType.ConnectionDisposed); RecordConnectionFailed(ConnectionFailureType.ConnectionDisposed);
} }
OnCloseEcho(); OnCloseEcho();
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment