Просмотр исходного кода

Mark ChannelSession sealed, and added doc for SendChannelOpenMessage().

Gert Driesen 8 лет назад
Родитель
Сommit
3b23d11c8a
1 измененных файлов с 43 добавлено и 9 удалено
  1. 43 9
      src/Renci.SshNet/Channels/ChannelSession.cs

+ 43 - 9
src/Renci.SshNet/Channels/ChannelSession.cs

@@ -10,7 +10,7 @@ namespace Renci.SshNet.Channels
     /// <summary>
     /// Implements Session SSH channel.
     /// </summary>
-    internal class ChannelSession : ClientChannel, IChannelSession
+    internal sealed class ChannelSession : ClientChannel, IChannelSession
     {
         /// <summary>
         /// Counts failed channel open attempts
@@ -62,7 +62,7 @@ namespace Renci.SshNet.Channels
         /// <summary>
         /// Opens the channel.
         /// </summary>
-        public virtual void Open()
+        public void Open()
         {
             //  Try to open channel several times
             while (!IsOpen && _failedOpenAttempts < ConnectionInfo.RetryAttempts)
@@ -356,19 +356,53 @@ namespace Renci.SshNet.Channels
         /// <summary>
         /// Sends the channel open message.
         /// </summary>
-        protected void SendChannelOpenMessage()
+        /// <exception cref="SshConnectionException">The client is not connected.</exception>
+        /// <exception cref="SshOperationTimeoutException">The operation timed out.</exception>
+        /// <exception cref="InvalidOperationException">The size of the packet exceeds the maximum size defined by the protocol.</exception>
+        /// <remarks>
+        /// <para>
+        /// 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 <see cref="ChannelOpenMessage"/>
+        /// to the remote host.
+        /// </para>
+        /// <para>
+        /// Note that the session semaphore is released in any of the following cases:
+        /// <list type="bullet">
+        ///   <item>
+        ///     <description>A <see cref="ChannelOpenFailureMessage"/> is received for the channel being opened.</description>
+        ///   </item>
+        ///   <item>
+        ///     <description>The remote host does not respond to the <see cref="ChannelOpenMessage"/> within the configured <see cref="ConnectionInfo.Timeout"/>.</description>
+        ///   </item>
+        ///   <item>
+        ///     <description>The remote host closes the channel.</description>
+        ///   </item>
+        ///   <item>
+        ///     <description>The <see cref="ChannelSession"/> is disposed.</description>
+        ///   </item>
+        ///   <item>
+        ///     <description>A socket error occurs sending a message to the remote host.</description>
+        ///   </item>
+        /// </list>
+        /// </para>
+        /// <para>
+        /// 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 <see cref="ChannelOpenMessage"/>, but the remote host did not
+        /// confirmed or rejected attempt to open the channel.
+        /// </para>
+        /// </remarks>
+        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()));
             }
         }