internal ServerSessionContext( ServerSocketAsyncEventArgs underlying )
 {
     this._underlying = underlying;
 }
 protected virtual void StartCore( Socket socket, ServerSocketAsyncEventArgs context )
 {
     this.AcceptAsync( socket, context );
 }
        protected virtual void OnReceived( ServerSocketAsyncEventArgs e )
        {
            var session = this.GetSession( e.RemoteEndPoint );
            if ( session == null )
            {
                session = this.CreateSession( e.RemoteEndPoint, new ServerSessionContext( e ) );
            }

            var workerThredInfo = new WorkerThreadInfo( DateTime.UtcNow, Thread.CurrentThread );
            if ( !this._exeuctingWorkerThreadTable.TryAdd( Thread.CurrentThread.ManagedThreadId, workerThredInfo ) )
            {
                Environment.FailFast( String.Format( CultureInfo.CurrentCulture, "Startig worker thread {0} is marked running.", Thread.CurrentThread.ManagedThreadId ) );
            }

            try { }
            finally
            {
                if ( Interlocked.Increment( ref this._exeuctingWorkerThreadCount ) == 1 )
                {
                    this._timeoutWatchDog.Change( ( long )this.TimeoutWatchPeriod.TotalMilliseconds, Timeout.Infinite );
                }
            }

            try
            {
                session.Transport.OnReceived( session );
            }
            catch ( ThreadAbortException ex )
            {
                if ( ex.ExceptionState == _executionTimeoutToken )
                {
                    Thread.ResetAbort();
                }
            }
            finally
            {
                if ( Interlocked.Decrement( ref this._exeuctingWorkerThreadCount ) == 0 )
                {
                    this._timeoutWatchDog.Change( Timeout.Infinite, Timeout.Infinite );
                }

                WorkerThreadInfo disposal;
                this._exeuctingWorkerThreadTable.TryRemove( Thread.CurrentThread.ManagedThreadId, out disposal );
                Contract.Assert( disposal.WorkerThread.ManagedThreadId == Thread.CurrentThread.ManagedThreadId );
            }
        }
        protected virtual void OnAcceptted( ServerSocketAsyncEventArgs e )
        {
            do
            {
                this.HandleError( e.LastOperation, e.SocketError );
                // Drain
                e.ResetReceivingBuffer();
                e.AppendRecivingBuffer( e.Buffer, e.Offset, e.BytesTransferred );
                while ( e.AcceptSocket.Available > 0 )
                {
                    // TODO: use buffer manager
                    SocketError error;
                    e.AcceptSocket.Receive( e.Buffer, e.Offset, e.Count, e.SocketFlags, out error );
                    this.HandleError( SocketAsyncOperation.Receive, error );

                    var feeding = new byte[ e.Buffer.Length - e.Offset ];
                    Buffer.BlockCopy( e.Buffer, e.Offset, feeding, 0, e.BytesTransferred );
                    e.AppendRecivingBuffer( feeding, 0, e.BytesTransferred );
                }

                ThreadPool.QueueUserWorkItem(
                    state => this.OnReceived( e as ServerSocketAsyncEventArgs ),
                    e
                );

                if ( !this._isRunning )
                {
                    return;
                }

            } while ( !e.AcceptSocket.AcceptAsync( e ) );
        }
 protected virtual void AcceptAsync( Socket socket, ServerSocketAsyncEventArgs context )
 {
     context.AcceptSocket = socket;
     // TODO: use streaming buffer
     var buffer = new byte[ this.ReceiveBufferSize ];
     context.SetBuffer( buffer, 0, buffer.Length );
     context.SendingContext = new SocketAsyncEventArgs();
     if ( !context.AcceptSocket.AcceptAsync( context ) )
     {
         this.OnAcceptted( context );
     }
 }
        public void Start( EndPoint localEndpoint )
        {
            int acceptConcurrency = this.AcceptConcurrency;

            this._isRunning = true;

            for ( int i = 0; i < acceptConcurrency; i++ )
            {
                var socket = new Socket( this._protocol.AddressFamily, this._protocol.SocketType, this._protocol.ProtocolType );
                socket.Bind( localEndpoint );
                var e = new ServerSocketAsyncEventArgs( this.OnAcceptted, this.OnReceived, this.HandleError );
                this.StartCore( socket, e );
            }
        }