Parcourir la source

Replace SemaphoreLight with SemaphoreSlim (#1265)

This paves the way for asynchronous synchronisation via WaitAsync
(and eliminates a timing test which sometimes fails in CI)

Co-authored-by: Wojciech Nagórski <wojtpl2@gmail.com>
Rob Hague il y a 1 an
Parent
commit
f45af38628
23 fichiers modifiés avec 46 ajouts et 384 suppressions
  1. 1 1
      src/Renci.SshNet/Channels/Channel.cs
  2. 0 244
      src/Renci.SshNet/Common/SemaphoreLight.cs
  3. 1 1
      src/Renci.SshNet/ISession.cs
  4. 4 4
      src/Renci.SshNet/Session.cs
  5. 2 2
      src/Renci.SshNet/Sftp/SftpFileReader.cs
  6. 2 2
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_Disposed.cs
  7. 2 2
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_DisposeInEventHandler.cs
  8. 3 3
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure.cs
  9. 3 3
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess.cs
  10. 2 2
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure.cs
  11. 2 2
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess.cs
  12. 2 2
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure.cs
  13. 2 2
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess.cs
  14. 3 3
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs
  15. 2 2
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure.cs
  16. 2 2
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived.cs
  17. 2 2
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived.cs
  18. 2 2
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs
  19. 2 2
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen.cs
  20. 2 2
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_ExceptionWaitingOnOpenConfirmation.cs
  21. 2 2
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_NoRetriesAvailable.cs
  22. 3 3
      test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_RetriesAvalable.cs
  23. 0 94
      test/Renci.SshNet.Tests/Classes/Common/SemaphoreLightTest.cs

+ 1 - 1
src/Renci.SshNet/Channels/Channel.cs

@@ -285,7 +285,7 @@ namespace Renci.SshNet.Channels
         /// Gets the session semaphore to control number of session channels.
         /// </summary>
         /// <value>The session semaphore.</value>
-        protected SemaphoreLight SessionSemaphore
+        protected SemaphoreSlim SessionSemaphore
         {
             get { return _session.SessionSemaphore; }
         }

+ 0 - 244
src/Renci.SshNet/Common/SemaphoreLight.cs

@@ -1,244 +0,0 @@
-using System;
-using System.Threading;
-
-namespace Renci.SshNet.Common
-{
-    /// <summary>
-    /// Light implementation of SemaphoreSlim.
-    /// </summary>
-    public sealed class SemaphoreLight : IDisposable
-    {
-        private readonly object _lock = new object();
-        private ManualResetEvent _waitHandle;
-
-        private int _currentCount;
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="SemaphoreLight"/> class, specifying the initial number of requests that can
-        /// be granted concurrently.
-        /// </summary>
-        /// <param name="initialCount">The initial number of requests for the semaphore that can be granted concurrently.</param>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="initialCount"/> is a negative number.</exception>
-        public SemaphoreLight(int initialCount)
-        {
-            if (initialCount < 0)
-            {
-                throw new ArgumentOutOfRangeException(nameof(initialCount), "The value cannot be negative.");
-            }
-
-            _currentCount = initialCount;
-        }
-
-        /// <summary>
-        /// Gets the current count of the <see cref="SemaphoreLight"/>.
-        /// </summary>
-        public int CurrentCount
-        {
-            get { return _currentCount; }
-        }
-
-        /// <summary>
-        /// Gets a <see cref="WaitHandle"/> that can be used to wait on the semaphore.
-        /// </summary>
-        /// <value>
-        /// A <see cref="WaitHandle"/> that can be used to wait on the semaphore.
-        /// </value>
-        /// <remarks>
-        /// A successful wait on the <see cref="AvailableWaitHandle"/> does not imply a successful
-        /// wait on the <see cref="SemaphoreLight"/> itself. It should be followed by a true wait
-        /// on the semaphore.
-        /// </remarks>
-        public WaitHandle AvailableWaitHandle
-        {
-            get
-            {
-                if (_waitHandle is null)
-                {
-                    lock (_lock)
-                    {
-                        _waitHandle ??= new ManualResetEvent(_currentCount > 0);
-                    }
-                }
-
-                return _waitHandle;
-            }
-        }
-
-        /// <summary>
-        /// Exits the <see cref="SemaphoreLight"/> once.
-        /// </summary>
-        /// <returns>The previous count of the <see cref="SemaphoreLight"/>.</returns>
-        public int Release()
-        {
-            return Release(1);
-        }
-
-        /// <summary>
-        /// Exits the <see cref="SemaphoreLight"/> a specified number of times.
-        /// </summary>
-        /// <param name="releaseCount">The number of times to exit the semaphore.</param>
-        /// <returns>
-        /// The previous count of the <see cref="SemaphoreLight"/>.
-        /// </returns>
-        public int Release(int releaseCount)
-        {
-            lock (_lock)
-            {
-                var oldCount = _currentCount;
-
-                _currentCount += releaseCount;
-
-                // signal waithandle when the original semaphore count was zero
-                if (_waitHandle != null && oldCount == 0)
-                {
-                    _ = _waitHandle.Set();
-                }
-
-                Monitor.PulseAll(_lock);
-
-                return oldCount;
-            }
-        }
-
-        /// <summary>
-        /// Blocks the current thread until it can enter the <see cref="SemaphoreLight"/>.
-        /// </summary>
-        public void Wait()
-        {
-            lock (_lock)
-            {
-                while (_currentCount < 1)
-                {
-                    _ = Monitor.Wait(_lock);
-                }
-
-                _currentCount--;
-
-                // unsignal waithandle when the semaphore count reaches zero
-                if (_waitHandle != null && _currentCount == 0)
-                {
-                    _ = _waitHandle.Reset();
-                }
-
-                Monitor.PulseAll(_lock);
-            }
-        }
-
-        /// <summary>
-        /// Blocks the current thread until it can enter the <see cref="SemaphoreLight"/>, using a 32-bit signed
-        /// integer that specifies the timeout.
-        /// </summary>
-        /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Infinite(-1) to wait indefinitely.</param>
-        /// <returns>
-        /// <see langword="true"/> if the current thread successfully entered the <see cref="SemaphoreLight"/>; otherwise, <see langword="false"/>.
-        /// </returns>
-        public bool Wait(int millisecondsTimeout)
-        {
-            if (millisecondsTimeout < -1)
-            {
-                throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), "The timeout must represent a value between -1 and Int32.MaxValue, inclusive.");
-            }
-
-            return WaitWithTimeout(millisecondsTimeout);
-        }
-
-        /// <summary>
-        /// Blocks the current thread until it can enter the <see cref="SemaphoreLight"/>, using a <see cref="TimeSpan"/>
-        /// to specify the timeout.
-        /// </summary>
-        /// <param name="timeout">A <see cref="TimeSpan"/> that represents the number of milliseconds to wait, or a <see cref="TimeSpan"/> that represents -1 milliseconds to wait indefinitely.</param>
-        /// <returns>
-        /// <see langword="true"/> if the current thread successfully entered the <see cref="SemaphoreLight"/>; otherwise, <see langword="false"/>.
-        /// </returns>
-        public bool Wait(TimeSpan timeout)
-        {
-            var timeoutInMilliseconds = timeout.TotalMilliseconds;
-            if (timeoutInMilliseconds is < -1d or > int.MaxValue)
-            {
-                throw new ArgumentOutOfRangeException(nameof(timeout), "The timeout must represent a value between -1 and Int32.MaxValue, inclusive.");
-            }
-
-            return WaitWithTimeout((int) timeoutInMilliseconds);
-        }
-
-        private bool WaitWithTimeout(int timeoutInMilliseconds)
-        {
-            lock (_lock)
-            {
-                if (timeoutInMilliseconds == Session.Infinite)
-                {
-                    while (_currentCount < 1)
-                    {
-                        _ = Monitor.Wait(_lock);
-                    }
-                }
-                else
-                {
-                    if (_currentCount < 1)
-                    {
-                        if (timeoutInMilliseconds > 0)
-                        {
-                            return false;
-                        }
-
-                        var remainingTimeInMilliseconds = timeoutInMilliseconds;
-                        var startTicks = Environment.TickCount;
-
-                        while (_currentCount < 1)
-                        {
-                            if (!Monitor.Wait(_lock, remainingTimeInMilliseconds))
-                            {
-                                return false;
-                            }
-
-                            var elapsed = Environment.TickCount - startTicks;
-                            remainingTimeInMilliseconds -= elapsed;
-                            if (remainingTimeInMilliseconds < 0)
-                            {
-                                return false;
-                            }
-                        }
-                    }
-                }
-
-                _currentCount--;
-
-                // unsignal waithandle when the semaphore count is zero
-                if (_waitHandle != null && _currentCount == 0)
-                {
-                    _ = _waitHandle.Reset();
-                }
-
-                Monitor.PulseAll(_lock);
-
-                return true;
-            }
-        }
-
-        /// <summary>
-        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
-        /// </summary>
-        public void Dispose()
-        {
-            Dispose(disposing: true);
-            GC.SuppressFinalize(this);
-        }
-
-        /// <summary>
-        /// Releases unmanaged and - optionally - managed resources.
-        /// </summary>
-        /// <param name="disposing"><see langword="true"/> to release both managed and unmanaged resources; <see langword="false"/> to release only unmanaged resources.</param>
-        private void Dispose(bool disposing)
-        {
-            if (disposing)
-            {
-                var waitHandle = _waitHandle;
-                if (waitHandle is not null)
-                {
-                    waitHandle.Dispose();
-                    _waitHandle = null;
-                }
-            }
-        }
-    }
-}

+ 1 - 1
src/Renci.SshNet/ISession.cs

@@ -36,7 +36,7 @@ namespace Renci.SshNet
         /// <value>
         /// The session semaphore.
         /// </value>
-        SemaphoreLight SessionSemaphore { get; }
+        SemaphoreSlim SessionSemaphore { get; }
 
         /// <summary>
         /// Gets a <see cref="WaitHandle"/> that can be used to wait for the message listener loop to complete.

+ 4 - 4
src/Renci.SshNet/Session.cs

@@ -87,7 +87,7 @@ namespace Renci.SshNet
         /// <remarks>
         /// Some server may restrict number to prevent authentication attacks.
         /// </remarks>
-        private static readonly SemaphoreLight AuthenticationConnection = new SemaphoreLight(3);
+        private static readonly SemaphoreSlim AuthenticationConnection = new SemaphoreSlim(3);
 
         /// <summary>
         /// Holds the factory to use for creating new services.
@@ -196,7 +196,7 @@ namespace Renci.SshNet
 
         private Compressor _clientCompression;
 
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
 
         private bool _isDisconnectMessageSent;
 
@@ -213,7 +213,7 @@ namespace Renci.SshNet
         /// <value>
         /// The session semaphore.
         /// </value>
-        public SemaphoreLight SessionSemaphore
+        public SemaphoreSlim SessionSemaphore
         {
             get
             {
@@ -221,7 +221,7 @@ namespace Renci.SshNet
                 {
                     lock (_connectAndLazySemaphoreInitLock)
                     {
-                        _sessionSemaphore ??= new SemaphoreLight(ConnectionInfo.MaxSessions);
+                        _sessionSemaphore ??= new SemaphoreSlim(ConnectionInfo.MaxSessions);
                     }
                 }
 

+ 2 - 2
src/Renci.SshNet/Sftp/SftpFileReader.cs

@@ -16,7 +16,7 @@ namespace Renci.SshNet.Sftp
         private readonly byte[] _handle;
         private readonly ISftpSession _sftpSession;
         private readonly uint _chunkSize;
-        private readonly SemaphoreLight _semaphore;
+        private readonly SemaphoreSlim _semaphore;
         private readonly object _readLock;
         private readonly ManualResetEvent _disposingWaitHandle;
         private readonly ManualResetEvent _readAheadCompleted;
@@ -62,7 +62,7 @@ namespace Renci.SshNet.Sftp
             _sftpSession = sftpSession;
             _chunkSize = chunkSize;
             _fileSize = fileSize;
-            _semaphore = new SemaphoreLight(maxPendingReads);
+            _semaphore = new SemaphoreSlim(maxPendingReads);
             _queue = new Dictionary<int, BufferedRead>(maxPendingReads);
             _readLock = new object();
             _readAheadCompleted = new ManualResetEvent(initialState: false);

+ 2 - 2
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_Disposed.cs

@@ -23,7 +23,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private uint _remotePacketSize;
         private uint _remoteChannelNumber;
         private TimeSpan _channelCloseTimeout;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private IList<ChannelEventArgs> _channelClosedRegister;
         private List<ExceptionEventArgs> _channelExceptionRegister;
 
@@ -38,7 +38,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _remoteWindowSize = (uint)random.Next(0, int.MaxValue);
             _remotePacketSize = (uint)random.Next(100, 200);
             _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20));
-            _sessionSemaphore = new SemaphoreLight(1);
+            _sessionSemaphore = new SemaphoreSlim(1);
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
         }

+ 2 - 2
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_DisposeInEventHandler.cs

@@ -24,7 +24,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private List<ExceptionEventArgs> _channelExceptionRegister;
         private ChannelSession _channel;
         private MockSequence _sequence;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private int _initialSessionSemaphoreCount;
 
         protected override void SetupData()
@@ -41,7 +41,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
             _initialSessionSemaphoreCount = random.Next(10, 20);
-            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
+            _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount);
         }
 
         protected override void SetupMocks()

+ 3 - 3
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure.cs

@@ -22,7 +22,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private List<ExceptionEventArgs> _channelExceptionRegister;
         private ChannelSession _channel;
         private MockSequence _sequence;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private int _initialSessionSemaphoreCount;
 
         protected override void SetupData()
@@ -38,7 +38,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
             _initialSessionSemaphoreCount = random.Next(10, 20);
-            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
+            _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount);
         }
 
         protected override void SetupMocks()
@@ -126,4 +126,4 @@ namespace Renci.SshNet.Tests.Classes.Channels
             Assert.IsFalse(_channel.IsOpen);
         }
     }
-}
+}

+ 3 - 3
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess.cs

@@ -23,7 +23,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private IList<ChannelEventArgs> _channelClosedRegister;
         private List<ExceptionEventArgs> _channelExceptionRegister;
         private ChannelSession _channel;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private int _initialSessionSemaphoreCount;
 
         protected override void SetupData()
@@ -40,7 +40,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
             _initialSessionSemaphoreCount = random.Next(10, 20);
-            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
+            _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount);
         }
 
         protected override void SetupMocks()
@@ -134,4 +134,4 @@ namespace Renci.SshNet.Tests.Classes.Channels
             Assert.IsFalse(_channel.IsOpen);
         }
     }
-}
+}

+ 2 - 2
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure.cs

@@ -22,7 +22,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private List<ExceptionEventArgs> _channelExceptionRegister;
         private ChannelSession _channel;
         private MockSequence _sequence;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private int _initialSessionSemaphoreCount;
 
         protected override void SetupData()
@@ -38,7 +38,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
             _initialSessionSemaphoreCount = random.Next(10, 20);
-            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
+            _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount);
         }
 
         protected override void SetupMocks()

+ 2 - 2
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess.cs

@@ -23,7 +23,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private IList<ChannelEventArgs> _channelClosedRegister;
         private List<ExceptionEventArgs> _channelExceptionRegister;
         private ChannelSession _channel;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private int _initialSessionSemaphoreCount;
 
         protected override void SetupData()
@@ -40,7 +40,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
             _initialSessionSemaphoreCount = random.Next(10, 20);
-            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
+            _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount);
         }
 
         protected override void SetupMocks()

+ 2 - 2
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure.cs

@@ -22,7 +22,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private List<ExceptionEventArgs> _channelExceptionRegister;
         private ChannelSession _channel;
         private MockSequence _sequence;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private int _initialSessionSemaphoreCount;
 
         protected override void SetupData()
@@ -38,7 +38,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
             _initialSessionSemaphoreCount = random.Next(10, 20);
-            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
+            _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount);
         }
 
         protected override void SetupMocks()

+ 2 - 2
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess.cs

@@ -22,7 +22,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private IList<ChannelEventArgs> _channelClosedRegister;
         private List<ExceptionEventArgs> _channelExceptionRegister;
         private ChannelSession _channel;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private int _initialSessionSemaphoreCount;
 
         protected override void SetupData()
@@ -39,7 +39,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
             _initialSessionSemaphoreCount = random.Next(10, 20);
-            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
+            _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount);
         }
 
         protected override void SetupMocks()

+ 3 - 3
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs

@@ -20,7 +20,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private uint _remotePacketSize;
         private uint _remoteChannelNumber;
         private TimeSpan _channelCloseTimeout;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private IList<ChannelEventArgs> _channelClosedRegister;
         private List<ExceptionEventArgs> _channelExceptionRegister;
 
@@ -35,7 +35,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _remoteWindowSize = (uint) random.Next(0, int.MaxValue);
             _remotePacketSize = (uint) random.Next(100, 200);
             _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20));
-            _sessionSemaphore = new SemaphoreLight(1);
+            _sessionSemaphore = new SemaphoreSlim(1);
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
         }
@@ -142,4 +142,4 @@ namespace Renci.SshNet.Tests.Classes.Channels
             Assert.IsFalse(_channel.IsOpen);
         }
     }
-}
+}

+ 2 - 2
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure.cs

@@ -20,7 +20,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private uint _remotePacketSize;
         private uint _remoteChannelNumber;
         private TimeSpan _channelCloseTimeout;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private IList<ChannelEventArgs> _channelClosedRegister;
         private List<ExceptionEventArgs> _channelExceptionRegister;
 
@@ -35,7 +35,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _remoteWindowSize = (uint) random.Next(0, int.MaxValue);
             _remotePacketSize = (uint) random.Next(100, 200);
             _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20));
-            _sessionSemaphore = new SemaphoreLight(1);
+            _sessionSemaphore = new SemaphoreSlim(1);
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
         }

+ 2 - 2
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived.cs

@@ -22,7 +22,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private List<ExceptionEventArgs> _channelExceptionRegister;
         private ChannelSession _channel;
         private MockSequence _sequence;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private int _initialSessionSemaphoreCount;
 
         protected override void SetupData()
@@ -38,7 +38,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
             _initialSessionSemaphoreCount = random.Next(10, 20);
-            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
+            _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount);
         }
 
         protected override void SetupMocks()

+ 2 - 2
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived.cs

@@ -22,7 +22,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private List<ExceptionEventArgs> _channelExceptionRegister;
         private ChannelSession _channel;
         private MockSequence _sequence;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private int _initialSessionSemaphoreCount;
 
         protected override void SetupData()
@@ -38,7 +38,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
             _initialSessionSemaphoreCount = random.Next(10, 20);
-            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
+            _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount);
         }
 
         protected override void SetupMocks()

+ 2 - 2
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs

@@ -22,7 +22,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private List<ExceptionEventArgs> _channelExceptionRegister;
         private ChannelSession _channel;
         private MockSequence _sequence;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private int _initialSessionSemaphoreCount;
 
         protected override void SetupData()
@@ -38,7 +38,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
             _initialSessionSemaphoreCount = random.Next(10, 20);
-            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
+            _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount);
         }
 
         protected override void SetupMocks()

+ 2 - 2
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen.cs

@@ -24,7 +24,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private List<ExceptionEventArgs> _channelExceptionRegister;
         private ChannelSession _channel;
         private MockSequence _sequence;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private int _initialSessionSemaphoreCount;
 
         protected override void SetupData()
@@ -41,7 +41,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
             _initialSessionSemaphoreCount = random.Next(10, 20);
-            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
+            _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount);
         }
 
         protected override void SetupMocks()

+ 2 - 2
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_ExceptionWaitingOnOpenConfirmation.cs

@@ -18,7 +18,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private uint _localPacketSize;
         private IList<ChannelEventArgs> _channelClosedRegister;
         private List<ExceptionEventArgs> _channelExceptionRegister;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private int _initialSessionSemaphoreCount;
         private Exception _waitOnConfirmationException;
         private SystemException _actualException;
@@ -31,7 +31,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _localWindowSize = (uint) random.Next(2000, 3000);
             _localPacketSize = (uint) random.Next(1000, 2000);
             _initialSessionSemaphoreCount = random.Next(10, 20);
-            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
+            _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount);
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
             _waitOnConfirmationException = new SystemException();

+ 2 - 2
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_NoRetriesAvailable.cs

@@ -19,7 +19,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private uint _localPacketSize;
         private IList<ChannelEventArgs> _channelClosedRegister;
         private List<ExceptionEventArgs> _channelExceptionRegister;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private int _initialSessionSemaphoreCount;
         private uint _failureReasonCode;
         private string _failureDescription;
@@ -34,7 +34,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _localWindowSize = (uint) random.Next(2000, 3000);
             _localPacketSize = (uint) random.Next(1000, 2000);
             _initialSessionSemaphoreCount = random.Next(10, 20);
-            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
+            _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount);
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
             _actualException = null;

+ 3 - 3
test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_RetriesAvalable.cs

@@ -22,7 +22,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private uint _remotePacketSize;
         private IList<ChannelEventArgs> _channelClosedRegister;
         private List<ExceptionEventArgs> _channelExceptionRegister;
-        private SemaphoreLight _sessionSemaphore;
+        private SemaphoreSlim _sessionSemaphore;
         private int _initialSessionSemaphoreCount;
         private uint _failureReasonCode;
         private string _failureDescription;
@@ -39,7 +39,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _remoteWindowSize = (uint) random.Next(0, int.MaxValue);
             _remotePacketSize = (uint) random.Next(0, int.MaxValue);
             _initialSessionSemaphoreCount = random.Next(10, 20);
-            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
+            _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount);
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
 
@@ -147,4 +147,4 @@ namespace Renci.SshNet.Tests.Classes.Channels
             Assert.IsTrue(_channel.IsOpen);
         }
     }
-}
+}

+ 0 - 94
test/Renci.SshNet.Tests/Classes/Common/SemaphoreLightTest.cs

@@ -1,94 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Threading;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Common;
-using Renci.SshNet.Tests.Common;
-
-namespace Renci.SshNet.Tests.Classes.Common
-{
-    [TestClass]
-    public class SemaphoreLightTest : TestBase
-    {
-        [TestMethod]
-        public void SemaphoreLightConstructorTest()
-        {
-            var initialCount = new Random().Next(1, 10);
-            var target = new SemaphoreLight(initialCount);
-            Assert.AreEqual(initialCount, target.CurrentCount);
-        }
-
-        [TestMethod]
-        public void Release()
-        {
-            var initialCount = new Random().Next(1, 10);
-            var target = new SemaphoreLight(initialCount);
-
-            Assert.AreEqual(initialCount, target.Release());
-            Assert.AreEqual(initialCount + 1, target.CurrentCount);
-
-            Assert.AreEqual(initialCount + 1, target.Release());
-            Assert.AreEqual(initialCount + 2, target.CurrentCount);
-        }
-
-        /// <summary>
-        ///A test for Release
-        ///</summary>
-        [TestMethod]
-        public void Release_ReleaseCount()
-        {
-            var initialCount = new Random().Next(1, 10);
-            var target = new SemaphoreLight(initialCount);
-
-            var releaseCount1 = new Random().Next(1, 10);
-            Assert.AreEqual(initialCount, target.Release(releaseCount1));
-            Assert.AreEqual(initialCount + releaseCount1, target.CurrentCount);
-
-            var releaseCount2 = new Random().Next(1, 10);
-            Assert.AreEqual(initialCount + releaseCount1, target.Release(releaseCount2));
-            Assert.AreEqual(initialCount + releaseCount1 + releaseCount2, target.CurrentCount);
-        }
-
-        /// <summary>
-        ///A test for Wait
-        ///</summary>
-        [TestMethod]
-        public void WaitTest()
-        {
-            const int sleepTime = 200; 
-            const int initialCount = 2;
-            var target = new SemaphoreLight(initialCount);
-
-            var watch = new Stopwatch();
-            watch.Start();
-
-            target.Wait();
-            target.Wait();
-            
-            Assert.IsTrue(watch.ElapsedMilliseconds < 50);
-
-            var releaseThread = new Thread(() =>
-                {
-                    Thread.Sleep(sleepTime);
-                    _ = target.Release();
-                });
-            releaseThread.Start();
-
-            target.Wait();
-
-            watch.Stop();
-
-            Assert.IsTrue(watch.ElapsedMilliseconds >= 200);
-            Assert.IsTrue(watch.ElapsedMilliseconds < 250);
-        }
-
-        [TestMethod]
-        public void CurrentCountTest()
-        {
-            var initialCount = new Random().Next(1, 20);
-            var target = new SemaphoreLight(initialCount);
-
-            Assert.AreEqual(initialCount, target.CurrentCount);
-        }
-    }
-}