From 0884390ee04c4419b7139a18ab0874f099b6c7b8 Mon Sep 17 00:00:00 2001 From: Robert Hague Date: Sat, 10 Jun 2023 12:26:25 +0200 Subject: [PATCH] Replace SemaphoreLight with SemaphoreSlim This paves the way for asynchronous synchronisation via WaitAsync (and eliminates a timing test which sometimes fails in CI) --- src/Renci.SshNet/Channels/Channel.cs | 2 +- src/Renci.SshNet/Common/SemaphoreLight.cs | 244 ------------------ src/Renci.SshNet/ISession.cs | 2 +- src/Renci.SshNet/Session.cs | 8 +- src/Renci.SshNet/Sftp/SftpFileReader.cs | 4 +- .../ChannelSessionTest_Dispose_Disposed.cs | 4 +- ...hannelEofReceived_DisposeInEventHandler.cs | 4 +- ...Received_SendChannelCloseMessageFailure.cs | 6 +- ...Received_SendChannelCloseMessageSuccess.cs | 6 +- ...Received_SendChannelCloseMessageFailure.cs | 4 +- ...Received_SendChannelCloseMessageSuccess.cs | 4 +- ...Received_SendChannelCloseMessageFailure.cs | 4 +- ...Received_SendChannelCloseMessageSuccess.cs | 4 +- ...Open_NoChannelCloseOrChannelEofReceived.cs | 6 +- ...ofReceived_SendChannelEofMessageFailure.cs | 4 +- ...sOpen_ChannelCloseAndChannelEofReceived.cs | 4 +- ...edAndChannelIsOpen_ChannelCloseReceived.cs | 4 +- ...Open_NoChannelCloseOrChannelEofReceived.cs | 4 +- ...ived_SessionIsConnectedAndChannelIsOpen.cs | 4 +- ...Open_ExceptionWaitingOnOpenConfirmation.cs | 4 +- ...nOpenFailureReceived_NoRetriesAvailable.cs | 4 +- ...n_OnOpenFailureReceived_RetriesAvalable.cs | 6 +- .../Classes/Common/SemaphoreLightTest.cs | 94 ------- 23 files changed, 46 insertions(+), 384 deletions(-) delete mode 100644 src/Renci.SshNet/Common/SemaphoreLight.cs delete mode 100644 test/Renci.SshNet.Tests/Classes/Common/SemaphoreLightTest.cs diff --git a/src/Renci.SshNet/Channels/Channel.cs b/src/Renci.SshNet/Channels/Channel.cs index 580c63e0f..25975872d 100644 --- a/src/Renci.SshNet/Channels/Channel.cs +++ b/src/Renci.SshNet/Channels/Channel.cs @@ -285,7 +285,7 @@ protected IConnectionInfo ConnectionInfo /// Gets the session semaphore to control number of session channels. /// /// The session semaphore. - protected SemaphoreLight SessionSemaphore + protected SemaphoreSlim SessionSemaphore { get { return _session.SessionSemaphore; } } diff --git a/src/Renci.SshNet/Common/SemaphoreLight.cs b/src/Renci.SshNet/Common/SemaphoreLight.cs deleted file mode 100644 index 106b10180..000000000 --- a/src/Renci.SshNet/Common/SemaphoreLight.cs +++ /dev/null @@ -1,244 +0,0 @@ -using System; -using System.Threading; - -namespace Renci.SshNet.Common -{ - /// - /// Light implementation of SemaphoreSlim. - /// - public sealed class SemaphoreLight : IDisposable - { - private readonly object _lock = new object(); - private ManualResetEvent _waitHandle; - - private int _currentCount; - - /// - /// Initializes a new instance of the class, specifying the initial number of requests that can - /// be granted concurrently. - /// - /// The initial number of requests for the semaphore that can be granted concurrently. - /// is a negative number. - public SemaphoreLight(int initialCount) - { - if (initialCount < 0) - { - throw new ArgumentOutOfRangeException(nameof(initialCount), "The value cannot be negative."); - } - - _currentCount = initialCount; - } - - /// - /// Gets the current count of the . - /// - public int CurrentCount - { - get { return _currentCount; } - } - - /// - /// Gets a that can be used to wait on the semaphore. - /// - /// - /// A that can be used to wait on the semaphore. - /// - /// - /// A successful wait on the does not imply a successful - /// wait on the itself. It should be followed by a true wait - /// on the semaphore. - /// - public WaitHandle AvailableWaitHandle - { - get - { - if (_waitHandle is null) - { - lock (_lock) - { - _waitHandle ??= new ManualResetEvent(_currentCount > 0); - } - } - - return _waitHandle; - } - } - - /// - /// Exits the once. - /// - /// The previous count of the . - public int Release() - { - return Release(1); - } - - /// - /// Exits the a specified number of times. - /// - /// The number of times to exit the semaphore. - /// - /// The previous count of the . - /// - 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; - } - } - - /// - /// Blocks the current thread until it can enter the . - /// - 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); - } - } - - /// - /// Blocks the current thread until it can enter the , using a 32-bit signed - /// integer that specifies the timeout. - /// - /// The number of milliseconds to wait, or Infinite(-1) to wait indefinitely. - /// - /// if the current thread successfully entered the ; otherwise, . - /// - 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); - } - - /// - /// Blocks the current thread until it can enter the , using a - /// to specify the timeout. - /// - /// A that represents the number of milliseconds to wait, or a that represents -1 milliseconds to wait indefinitely. - /// - /// if the current thread successfully entered the ; otherwise, . - /// - 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; - } - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(disposing: true); - GC.SuppressFinalize(this); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// to release both managed and unmanaged resources; to release only unmanaged resources. - private void Dispose(bool disposing) - { - if (disposing) - { - var waitHandle = _waitHandle; - if (waitHandle is not null) - { - waitHandle.Dispose(); - _waitHandle = null; - } - } - } - } -} diff --git a/src/Renci.SshNet/ISession.cs b/src/Renci.SshNet/ISession.cs index e78ff75f8..707d36805 100644 --- a/src/Renci.SshNet/ISession.cs +++ b/src/Renci.SshNet/ISession.cs @@ -36,7 +36,7 @@ internal interface ISession : IDisposable /// /// The session semaphore. /// - SemaphoreLight SessionSemaphore { get; } + SemaphoreSlim SessionSemaphore { get; } /// /// Gets a that can be used to wait for the message listener loop to complete. diff --git a/src/Renci.SshNet/Session.cs b/src/Renci.SshNet/Session.cs index c984d3109..5bf6d8eef 100644 --- a/src/Renci.SshNet/Session.cs +++ b/src/Renci.SshNet/Session.cs @@ -87,7 +87,7 @@ public class Session : ISession /// /// Some server may restrict number to prevent authentication attacks. /// - private static readonly SemaphoreLight AuthenticationConnection = new SemaphoreLight(3); + private static readonly SemaphoreSlim AuthenticationConnection = new SemaphoreSlim(3); /// /// Holds the factory to use for creating new services. @@ -196,7 +196,7 @@ public class Session : ISession private Compressor _clientCompression; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private bool _isDisconnectMessageSent; @@ -213,7 +213,7 @@ public class Session : ISession /// /// The session semaphore. /// - public SemaphoreLight SessionSemaphore + public SemaphoreSlim SessionSemaphore { get { @@ -221,7 +221,7 @@ public SemaphoreLight SessionSemaphore { lock (_connectAndLazySemaphoreInitLock) { - _sessionSemaphore ??= new SemaphoreLight(ConnectionInfo.MaxSessions); + _sessionSemaphore ??= new SemaphoreSlim(ConnectionInfo.MaxSessions); } } diff --git a/src/Renci.SshNet/Sftp/SftpFileReader.cs b/src/Renci.SshNet/Sftp/SftpFileReader.cs index af32f87a7..8d3ef211f 100644 --- a/src/Renci.SshNet/Sftp/SftpFileReader.cs +++ b/src/Renci.SshNet/Sftp/SftpFileReader.cs @@ -16,7 +16,7 @@ internal sealed class SftpFileReader : ISftpFileReader 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 @@ public SftpFileReader(byte[] handle, ISftpSession sftpSession, uint chunkSize, i _sftpSession = sftpSession; _chunkSize = chunkSize; _fileSize = fileSize; - _semaphore = new SemaphoreLight(maxPendingReads); + _semaphore = new SemaphoreSlim(maxPendingReads); _queue = new Dictionary(maxPendingReads); _readLock = new object(); _readAheadCompleted = new ManualResetEvent(initialState: false); diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_Disposed.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_Disposed.cs index 07ba0d53e..da5ce0d12 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_Disposed.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_Disposed.cs @@ -23,7 +23,7 @@ public class ChannelSessionTest_Dispose_Disposed : ChannelSessionTestBase private uint _remotePacketSize; private uint _remoteChannelNumber; private TimeSpan _channelCloseTimeout; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private IList _channelClosedRegister; private List _channelExceptionRegister; @@ -38,7 +38,7 @@ protected override void SetupData() _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(); _channelExceptionRegister = new List(); } diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_DisposeInEventHandler.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_DisposeInEventHandler.cs index be4fdc300..626a6519a 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_DisposeInEventHandler.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_DisposeInEventHandler.cs @@ -24,7 +24,7 @@ public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_Chann private List _channelExceptionRegister; private ChannelSession _channel; private MockSequence _sequence; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private int _initialSessionSemaphoreCount; protected override void SetupData() @@ -41,7 +41,7 @@ protected override void SetupData() _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); - _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount); } protected override void SetupMocks() diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure.cs index aac5c837c..dca9c0ecf 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure.cs @@ -22,7 +22,7 @@ public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_Chann private List _channelExceptionRegister; private ChannelSession _channel; private MockSequence _sequence; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private int _initialSessionSemaphoreCount; protected override void SetupData() @@ -38,7 +38,7 @@ protected override void SetupData() _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); - _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount); } protected override void SetupMocks() @@ -126,4 +126,4 @@ public void IsOpenShouldReturnFalse() Assert.IsFalse(_channel.IsOpen); } } -} \ No newline at end of file +} diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess.cs index dd17c5ab5..7a68ff177 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess.cs @@ -23,7 +23,7 @@ public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_Chann private IList _channelClosedRegister; private List _channelExceptionRegister; private ChannelSession _channel; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private int _initialSessionSemaphoreCount; protected override void SetupData() @@ -40,7 +40,7 @@ protected override void SetupData() _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); - _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount); } protected override void SetupMocks() @@ -134,4 +134,4 @@ public void IsOpenShouldReturnFalse() Assert.IsFalse(_channel.IsOpen); } } -} \ No newline at end of file +} diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure.cs index 251adf5d0..6948fded2 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure.cs @@ -22,7 +22,7 @@ public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_Chann private List _channelExceptionRegister; private ChannelSession _channel; private MockSequence _sequence; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private int _initialSessionSemaphoreCount; protected override void SetupData() @@ -38,7 +38,7 @@ protected override void SetupData() _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); - _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount); } protected override void SetupMocks() diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess.cs index 37dff92fa..b07bf3d20 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess.cs @@ -23,7 +23,7 @@ public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_Chann private IList _channelClosedRegister; private List _channelExceptionRegister; private ChannelSession _channel; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private int _initialSessionSemaphoreCount; protected override void SetupData() @@ -40,7 +40,7 @@ protected override void SetupData() _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); - _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount); } protected override void SetupMocks() diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure.cs index 83b40b327..d8294bf1f 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure.cs @@ -22,7 +22,7 @@ public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_Chann private List _channelExceptionRegister; private ChannelSession _channel; private MockSequence _sequence; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private int _initialSessionSemaphoreCount; protected override void SetupData() @@ -38,7 +38,7 @@ protected override void SetupData() _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); - _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount); } protected override void SetupMocks() diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess.cs index 5ab596264..3b340bd42 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess.cs @@ -22,7 +22,7 @@ public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_Chann private IList _channelClosedRegister; private List _channelExceptionRegister; private ChannelSession _channel; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private int _initialSessionSemaphoreCount; protected override void SetupData() @@ -39,7 +39,7 @@ protected override void SetupData() _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); - _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount); } protected override void SetupMocks() diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs index 47c84903a..ce2bc0969 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs @@ -20,7 +20,7 @@ public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoCha private uint _remotePacketSize; private uint _remoteChannelNumber; private TimeSpan _channelCloseTimeout; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private IList _channelClosedRegister; private List _channelExceptionRegister; @@ -35,7 +35,7 @@ protected override void SetupData() _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(); _channelExceptionRegister = new List(); } @@ -142,4 +142,4 @@ public void IsOpenShouldReturnFalse() Assert.IsFalse(_channel.IsOpen); } } -} \ No newline at end of file +} diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure.cs index ce733bbcd..b547af778 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure.cs @@ -20,7 +20,7 @@ public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoCha private uint _remotePacketSize; private uint _remoteChannelNumber; private TimeSpan _channelCloseTimeout; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private IList _channelClosedRegister; private List _channelExceptionRegister; @@ -35,7 +35,7 @@ protected override void SetupData() _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(); _channelExceptionRegister = new List(); } diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived.cs index d44f4e0ab..e2ded5942 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived.cs @@ -22,7 +22,7 @@ public class ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_Ch private List _channelExceptionRegister; private ChannelSession _channel; private MockSequence _sequence; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private int _initialSessionSemaphoreCount; protected override void SetupData() @@ -38,7 +38,7 @@ protected override void SetupData() _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); - _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount); } protected override void SetupMocks() diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived.cs index fedd4cd64..62f5ab4ac 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived.cs @@ -22,7 +22,7 @@ public class ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_Ch private List _channelExceptionRegister; private ChannelSession _channel; private MockSequence _sequence; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private int _initialSessionSemaphoreCount; protected override void SetupData() @@ -38,7 +38,7 @@ protected override void SetupData() _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); - _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount); } protected override void SetupMocks() diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs index ce8fa16cd..08f00b905 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs @@ -22,7 +22,7 @@ public class ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_No private List _channelExceptionRegister; private ChannelSession _channel; private MockSequence _sequence; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private int _initialSessionSemaphoreCount; protected override void SetupData() @@ -38,7 +38,7 @@ protected override void SetupData() _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); - _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount); } protected override void SetupMocks() diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen.cs index 584c4e943..5771f4e10 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen.cs @@ -24,7 +24,7 @@ public class ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnected private List _channelExceptionRegister; private ChannelSession _channel; private MockSequence _sequence; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private int _initialSessionSemaphoreCount; protected override void SetupData() @@ -41,7 +41,7 @@ protected override void SetupData() _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); - _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + _sessionSemaphore = new SemaphoreSlim(_initialSessionSemaphoreCount); } protected override void SetupMocks() diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_ExceptionWaitingOnOpenConfirmation.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_ExceptionWaitingOnOpenConfirmation.cs index fbb27e38f..44b9800a2 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_ExceptionWaitingOnOpenConfirmation.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_ExceptionWaitingOnOpenConfirmation.cs @@ -18,7 +18,7 @@ public class ChannelSessionTest_Open_ExceptionWaitingOnOpenConfirmation : Channe private uint _localPacketSize; private IList _channelClosedRegister; private List _channelExceptionRegister; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private int _initialSessionSemaphoreCount; private Exception _waitOnConfirmationException; private SystemException _actualException; @@ -31,7 +31,7 @@ protected override void SetupData() _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(); _channelExceptionRegister = new List(); _waitOnConfirmationException = new SystemException(); diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_NoRetriesAvailable.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_NoRetriesAvailable.cs index ab4ba4f60..37cf3ac06 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_NoRetriesAvailable.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_NoRetriesAvailable.cs @@ -19,7 +19,7 @@ public class ChannelSessionTest_Open_OnOpenFailureReceived_NoRetriesAvailable : private uint _localPacketSize; private IList _channelClosedRegister; private List _channelExceptionRegister; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private int _initialSessionSemaphoreCount; private uint _failureReasonCode; private string _failureDescription; @@ -34,7 +34,7 @@ protected override void SetupData() _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(); _channelExceptionRegister = new List(); _actualException = null; diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_RetriesAvalable.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_RetriesAvalable.cs index e6caeb222..9934c0715 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_RetriesAvalable.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_RetriesAvalable.cs @@ -22,7 +22,7 @@ public class ChannelSessionTest_Open_OnOpenFailureReceived_RetriesAvalable : Cha private uint _remotePacketSize; private IList _channelClosedRegister; private List _channelExceptionRegister; - private SemaphoreLight _sessionSemaphore; + private SemaphoreSlim _sessionSemaphore; private int _initialSessionSemaphoreCount; private uint _failureReasonCode; private string _failureDescription; @@ -39,7 +39,7 @@ protected override void SetupData() _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(); _channelExceptionRegister = new List(); @@ -147,4 +147,4 @@ public void IsOpenShouldReturnTrue() Assert.IsTrue(_channel.IsOpen); } } -} \ No newline at end of file +} diff --git a/test/Renci.SshNet.Tests/Classes/Common/SemaphoreLightTest.cs b/test/Renci.SshNet.Tests/Classes/Common/SemaphoreLightTest.cs deleted file mode 100644 index 5b4aa43b9..000000000 --- a/test/Renci.SshNet.Tests/Classes/Common/SemaphoreLightTest.cs +++ /dev/null @@ -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); - } - - /// - ///A test for Release - /// - [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); - } - - /// - ///A test for Wait - /// - [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); - } - } -}