From 064c9472d79e2bef5ec4ebeba21a7da588ca83e3 Mon Sep 17 00:00:00 2001 From: drieseng Date: Sun, 3 Apr 2016 15:58:29 +0200 Subject: [PATCH] Introduced support for socket event-based async pattern. Added dispose of listener and waithandle introduced for EAP. --- src/Renci.SshNet/ForwardedPortLocal.NET.cs | 45 +++++++++++++++++++--- src/Renci.SshNet/ForwardedPortLocal.cs | 4 ++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/Renci.SshNet/ForwardedPortLocal.NET.cs b/src/Renci.SshNet/ForwardedPortLocal.NET.cs index 7ebb0016..c4d08751 100644 --- a/src/Renci.SshNet/ForwardedPortLocal.NET.cs +++ b/src/Renci.SshNet/ForwardedPortLocal.NET.cs @@ -16,6 +16,10 @@ namespace Renci.SshNet private Socket _listener; private int _pendingRequests; +#if FEATURE_SOCKET_EAP + private ManualResetEvent _stoppingListener; +#endif // FEATURE_SOCKET_EAP + partial void InternalStart() { var addr = BoundHost.GetIPAddress(); @@ -38,16 +42,23 @@ namespace Renci.SshNet { try { +#if FEATURE_SOCKET_EAP + _stoppingListener = new ManualResetEvent(false); + StartAccept(); + _stoppingListener.WaitOne(); +#elif FEATURE_SOCKET_APM while (true) { -#if FEATURE_SOCKET_EAP -#else // accept new inbound connection var asyncResult = _listener.BeginAccept(AcceptCallback, _listener); // wait for the connection to be established asyncResult.AsyncWaitHandle.WaitOne(); -#endif // FEATURE_SOCKET_EAP } +#elif FEATURE_SOCKET_TAP + #error Accepting new socket connections is not implemented. +#else + #error Accepting new socket connections is not implemented. +#endif } catch (ObjectDisposedException) { @@ -91,7 +102,7 @@ namespace Renci.SshNet ProcessAccept(acceptAsyncEventArgs.AcceptSocket); } -#else +#elif FEATURE_SOCKET_APM private void AcceptCallback(IAsyncResult ar) { // Get the socket that handles the client request @@ -112,7 +123,7 @@ namespace Renci.SshNet ProcessAccept(clientSocket); } -#endif // FEATURE_SOCKET_EAP +#endif private void ProcessAccept(Socket clientSocket) { @@ -193,12 +204,36 @@ namespace Renci.SshNet Session.Disconnected -= Session_Disconnected; Session.ErrorOccured -= Session_ErrorOccured; +#if FEATURE_SOCKET_EAP + _stoppingListener.Set(); +#endif // FEATURE_SOCKET_EAP + // close listener socket _listener.Dispose(); // wait for listener loop to finish _listenerTaskCompleted.WaitOne(); } + partial void InternalDispose(bool disposing) + { + if (disposing) + { + if (_listener != null) + { + _listener.Dispose(); + _listener = null; + } + +#if FEATURE_SOCKET_EAP + if (_stoppingListener != null) + { + _stoppingListener.Dispose(); + _stoppingListener = null; + } +#endif // FEATURE_SOCKET_EAP + } + } + private void Session_ErrorOccured(object sender, ExceptionEventArgs e) { StopListener(); diff --git a/src/Renci.SshNet/ForwardedPortLocal.cs b/src/Renci.SshNet/ForwardedPortLocal.cs index 26566172..ccd1194d 100644 --- a/src/Renci.SshNet/ForwardedPortLocal.cs +++ b/src/Renci.SshNet/ForwardedPortLocal.cs @@ -163,6 +163,8 @@ namespace Renci.SshNet GC.SuppressFinalize(this); } + partial void InternalDispose(bool disposing); + /// /// Releases unmanaged and - optionally - managed resources /// @@ -182,6 +184,8 @@ namespace Renci.SshNet } } + InternalDispose(disposing); + _isDisposed = true; } }