Skip to content

Commit 3b23d11

Browse files
committed
Mark ChannelSession sealed, and added doc for SendChannelOpenMessage().
1 parent a353f95 commit 3b23d11

File tree

1 file changed

+43
-9
lines changed

1 file changed

+43
-9
lines changed

src/Renci.SshNet/Channels/ChannelSession.cs

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Renci.SshNet.Channels
1010
/// <summary>
1111
/// Implements Session SSH channel.
1212
/// </summary>
13-
internal class ChannelSession : ClientChannel, IChannelSession
13+
internal sealed class ChannelSession : ClientChannel, IChannelSession
1414
{
1515
/// <summary>
1616
/// Counts failed channel open attempts
@@ -62,7 +62,7 @@ public override ChannelTypes ChannelType
6262
/// <summary>
6363
/// Opens the channel.
6464
/// </summary>
65-
public virtual void Open()
65+
public void Open()
6666
{
6767
// Try to open channel several times
6868
while (!IsOpen && _failedOpenAttempts < ConnectionInfo.RetryAttempts)
@@ -356,19 +356,53 @@ protected override void OnFailure()
356356
/// <summary>
357357
/// Sends the channel open message.
358358
/// </summary>
359-
protected void SendChannelOpenMessage()
359+
/// <exception cref="SshConnectionException">The client is not connected.</exception>
360+
/// <exception cref="SshOperationTimeoutException">The operation timed out.</exception>
361+
/// <exception cref="InvalidOperationException">The size of the packet exceeds the maximum size defined by the protocol.</exception>
362+
/// <remarks>
363+
/// <para>
364+
/// When a session semaphore for this instance has not yet been obtained by this or any other thread,
365+
/// the thread will block until such a semaphore is available and send a <see cref="ChannelOpenMessage"/>
366+
/// to the remote host.
367+
/// </para>
368+
/// <para>
369+
/// Note that the session semaphore is released in any of the following cases:
370+
/// <list type="bullet">
371+
/// <item>
372+
/// <description>A <see cref="ChannelOpenFailureMessage"/> is received for the channel being opened.</description>
373+
/// </item>
374+
/// <item>
375+
/// <description>The remote host does not respond to the <see cref="ChannelOpenMessage"/> within the configured <see cref="ConnectionInfo.Timeout"/>.</description>
376+
/// </item>
377+
/// <item>
378+
/// <description>The remote host closes the channel.</description>
379+
/// </item>
380+
/// <item>
381+
/// <description>The <see cref="ChannelSession"/> is disposed.</description>
382+
/// </item>
383+
/// <item>
384+
/// <description>A socket error occurs sending a message to the remote host.</description>
385+
/// </item>
386+
/// </list>
387+
/// </para>
388+
/// <para>
389+
/// If the session semaphore was already obtained for this instance (and not released), then this method
390+
/// immediately returns control to the caller. This should only happen when another thread has obtain the
391+
/// session semaphore and already sent the <see cref="ChannelOpenMessage"/>, but the remote host did not
392+
/// confirmed or rejected attempt to open the channel.
393+
/// </para>
394+
/// </remarks>
395+
private void SendChannelOpenMessage()
360396
{
361397
// do not allow open to be ChannelOpenMessage to be sent again until we've
362398
// had a response on the previous attempt for the current channel
363399
if (Interlocked.CompareExchange(ref _sessionSemaphoreObtained, 1, 0) == 0)
364400
{
365401
SessionSemaphore.Wait();
366-
SendMessage(
367-
new ChannelOpenMessage(
368-
LocalChannelNumber,
369-
LocalWindowSize,
370-
LocalPacketSize,
371-
new SessionChannelOpenInfo()));
402+
SendMessage(new ChannelOpenMessage(LocalChannelNumber,
403+
LocalWindowSize,
404+
LocalPacketSize,
405+
new SessionChannelOpenInfo()));
372406
}
373407
}
374408

0 commit comments

Comments
 (0)