diff --git a/src/Renci.SshNet/Channels/ChannelSession.cs b/src/Renci.SshNet/Channels/ChannelSession.cs
index 3295c5a5d..38e13096b 100644
--- a/src/Renci.SshNet/Channels/ChannelSession.cs
+++ b/src/Renci.SshNet/Channels/ChannelSession.cs
@@ -10,7 +10,7 @@ namespace Renci.SshNet.Channels
///
/// Implements Session SSH channel.
///
- internal class ChannelSession : ClientChannel, IChannelSession
+ internal sealed class ChannelSession : ClientChannel, IChannelSession
{
///
/// Counts failed channel open attempts
@@ -62,7 +62,7 @@ public override ChannelTypes ChannelType
///
/// Opens the channel.
///
- public virtual void Open()
+ public void Open()
{
// Try to open channel several times
while (!IsOpen && _failedOpenAttempts < ConnectionInfo.RetryAttempts)
@@ -356,19 +356,53 @@ protected override void OnFailure()
///
/// Sends the channel open message.
///
- protected void SendChannelOpenMessage()
+ /// The client is not connected.
+ /// The operation timed out.
+ /// The size of the packet exceeds the maximum size defined by the protocol.
+ ///
+ ///
+ /// When a session semaphore for this instance has not yet been obtained by this or any other thread,
+ /// the thread will block until such a semaphore is available and send a
+ /// to the remote host.
+ ///
+ ///
+ /// Note that the session semaphore is released in any of the following cases:
+ ///
+ /// -
+ /// A is received for the channel being opened.
+ ///
+ /// -
+ /// The remote host does not respond to the within the configured .
+ ///
+ /// -
+ /// The remote host closes the channel.
+ ///
+ /// -
+ /// The is disposed.
+ ///
+ /// -
+ /// A socket error occurs sending a message to the remote host.
+ ///
+ ///
+ ///
+ ///
+ /// If the session semaphore was already obtained for this instance (and not released), then this method
+ /// immediately returns control to the caller. This should only happen when another thread has obtain the
+ /// session semaphore and already sent the , but the remote host did not
+ /// confirmed or rejected attempt to open the channel.
+ ///
+ ///
+ private void SendChannelOpenMessage()
{
// do not allow open to be ChannelOpenMessage to be sent again until we've
// had a response on the previous attempt for the current channel
if (Interlocked.CompareExchange(ref _sessionSemaphoreObtained, 1, 0) == 0)
{
SessionSemaphore.Wait();
- SendMessage(
- new ChannelOpenMessage(
- LocalChannelNumber,
- LocalWindowSize,
- LocalPacketSize,
- new SessionChannelOpenInfo()));
+ SendMessage(new ChannelOpenMessage(LocalChannelNumber,
+ LocalWindowSize,
+ LocalPacketSize,
+ new SessionChannelOpenInfo()));
}
}