Наследование: System.Net.LazyAsyncResult
        //
        // AcceptCallback - called by WaitCallback to do special Accept handling
        //   this involves searching through a queue of queued Accept requests
        //   and handling them if there are available accept sockets to handle them,
        //   or rewaiting if they are not
        //
        //  The overlapped function called by the thread pool
        //   when IO completes.
        //

        internal static void AcceptCallback(object stateObject, bool Signaled)
        {
            AcceptAsyncResult thisAsyncResult    = (AcceptAsyncResult)stateObject;
            Socket            socket             = (Socket)thisAsyncResult.AsyncObject;
            Exception         unhandledException = null;

            Monitor.Enter(socket);
            //
            // Accept Callback - called on the callback path, when we expect to release
            //  an accept socket that winsock says has completed.
            //
            //  While we still have items in our Queued list of Accept Requests,
            //   we recall the Winsock accept, to attempt to gather new
            //   results, and then match them again the queued items,
            //   when accept call returns would_block, we reinvoke ourselves
            //   and rewait for the next asyc callback.
            //
            //  If we have emptied the queue, then disable the queue and go back
            //   to sync.
            //
            socket.incallback = true;

            //
            //  Attempt to process queued Accept async
            //
            while (socket.AcceptQueue.Count != 0)    // if ! empty
            //
            // pick an element from the head of the list
            //
            {
                AcceptAsyncResult AResult = (AcceptAsyncResult)socket.AcceptQueue[0];
                socket.AcceptQueue.RemoveAt(0);

                Monitor.Exit(socket);

                int           Status        = SocketErrors.WSAENOTSOCK;
                SocketAddress socketAddress = null;
                IntPtr        AcceptResult  = (IntPtr)0;

                if (!socket.CleanedUp)
                {
                    socketAddress = socket.m_RightEndPoint.Serialize();

                    AcceptResult =
                        UnsafeNclNativeMethods.OSSOCK.accept(
                            socket.m_Handle,
                            socketAddress.m_Buffer,
                            ref socketAddress.m_Size);

                    Status = AcceptResult == SocketErrors.InvalidSocketIntPtr ? Marshal.GetLastWin32Error() : 0;
                }

                GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::AcceptCallback() UnsafeNclNativeMethods.OSSOCK.accept returns:" + Status.ToString());

                //
                // now check for synchronous completion
                //
                if (Status == 0)
                {
                    //
                    // on synchronous completion give our async callback
                    // the accepted Socket right away
                    //

                    try {
                        AResult.InvokeCallback(false, socket.CreateAcceptSocket(AcceptResult, socket.m_RightEndPoint.Create(socketAddress)));
                    } catch (Exception exception) {
                        unhandledException = new InvalidOperationException("AcceptCallback", exception);
                    }
                }
                else if (Status == SocketErrors.WSAEWOULDBLOCK)
                {
                    Monitor.Enter(socket);

                    socket.AcceptQueue.Add(AResult);

                    ThreadPool.RegisterWaitForSingleObject(
                        socket.m_AsyncEvent,
                        new WaitOrTimerCallback(AcceptCallback),
                        thisAsyncResult,
                        -1,
                        true);

                    socket.incallback = false;
                    Monitor.Exit(socket);
                    return;
                }
                else
                {
                    try {
                        AResult.ErrorCode = Status;
                        AResult.InvokeCallback(false, null);
                    } catch (Exception exception) {
                        unhandledException = new InvalidOperationException("AcceptCallback", exception);
                    }
                }
                //
                // Attempt to accept another socket
                //
                Monitor.Enter(socket);
            }

            socket.incallback = false;
            //
            // the accept queue is empty.
            // cancel async event
            //
            socket.SetAsyncEventSelect(AsyncEventBits.FdNone);
            //
            // go back to blocking mode
            //
            socket.InternalSetBlocking(true);

            Monitor.Exit(socket);

            if (unhandledException != null)
            {
                throw unhandledException;
            }
        }
Пример #2
0
        public IAsyncResult BeginAccept(AsyncCallback callback, object state) {

#if !FEATURE_PAL
            if (CanUseAcceptEx)
            {
                return BeginAccept(0,callback,state);
            }
#endif
            if(s_LoggingEnabled)Logging.Enter(Logging.Sockets, this, "BeginAccept", "");
            if (CleanedUp) {
                throw new ObjectDisposedException(this.GetType().FullName);
            }

            // Set up the context flow.
            AcceptAsyncResult asyncResult = new AcceptAsyncResult(this, state, callback);
            asyncResult.StartPostingAsyncOp(false);

            // Do the accept.
            DoBeginAccept(asyncResult);

            // Set up for return.
            asyncResult.FinishPostingAsyncOp(ref Caches.AcceptClosureCache);

            if(s_LoggingEnabled)Logging.Exit(Logging.Sockets, this, "BeginAccept", asyncResult);
            return asyncResult;
        }
Пример #3
0
        /*++

        Routine Description:

           BeginAccept - Does a async winsock accept, creating a new socket on success

            Works by creating a pending accept request the first time,
            and subsequent calls are queued so that when the first accept completes,
            the next accept can be resubmitted in the callback.
            this routine may go pending at which time,
            but any case the callback Delegate will be called upon completion

        Arguments:

           Callback - Async Callback Delegate that is called upon Async Completion
           State - State used to track callback, set by caller, not required

        Return Value:

           IAsyncResult - Async result used to retreive resultant new socket

        --*/

        /// <include file='doc\Socket.uex' path='docs/doc[@for="Socket.BeginAccept"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        public IAsyncResult BeginAccept(AsyncCallback callback, object state) {
            if (CleanedUp) {
                throw new ObjectDisposedException(this.GetType().FullName);
            }

            if (m_RightEndPoint==null) {
                throw new InvalidOperationException(SR.GetString(SR.net_sockets_mustbind));
            }

            //
            // We keep a queue, which lists the set of requests that want to
            //  be called when an accept queue completes.  We call accept
            //  once, and then as it completes asyncrounsly we pull the
            //  requests out of the queue and call their callback.
            //
            // We start by grabbing Critical Section, then attempt to
            //  determine if we haven an empty Queue of Accept Sockets
            //  or if its in a Callback on the Callback thread.
            //
            // If its in the callback thread proocessing of the callback, then we
            //  just need to notify the callback by adding an additional request
            //   to the queue.
            //
            // If its an empty queue, and its not in the callback, then
            //   we just need to get the Accept going, make it go async
            //   and leave.
            //
            GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::BeginAccept()");

            AcceptAsyncResult asyncResult = new AcceptAsyncResult(this, state, callback);

            Monitor.Enter(this);

            if (AcceptQueue.Count==0 && !incallback) {
                //
                // if the accept queue is empty
                //
                AcceptQueue.Add(asyncResult);

                SocketAddress socketAddress = m_RightEndPoint.Serialize();

                // get async going
                SetAsyncEventSelect(AsyncEventBits.FdAccept);

                GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::BeginAccept() queue is empty calling UnsafeNclNativeMethods.OSSOCK.accept");

                IntPtr acceptedSocketHandle =
                    UnsafeNclNativeMethods.OSSOCK.accept(
                        m_Handle,
                        socketAddress.m_Buffer,
                        ref socketAddress.m_Size );

                int errorCode = acceptedSocketHandle!=SocketErrors.InvalidSocketIntPtr ? 0 : Marshal.GetLastWin32Error();

                GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::BeginAccept() UnsafeNclNativeMethods.OSSOCK.accept returns:" + errorCode.ToString());

                if (errorCode==SocketErrors.Success) {
                    asyncResult.Result = CreateAcceptSocket(acceptedSocketHandle, m_RightEndPoint.Create(socketAddress));
                }
                //
                // the following code will call Monitor.Exit(this) as soon as possible
                //
                asyncResult.CheckAsyncCallResult(errorCode);

                //
                // if the asynchronous native call fails synchronously
                // we'll throw a SocketException
                //
                if (asyncResult.ErrorCode!=SocketErrors.Success) {
                    //
                    // update our internal state after this socket error and throw
                    //
                    UpdateStatusAfterSocketError();
                    throw new SocketException(asyncResult.ErrorCode);
                }
            }
            else {
                AcceptQueue.Add(asyncResult);

                GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::BeginAccept() queue is not empty Count:" + AcceptQueue.Count.ToString());

                Monitor.Exit(this);
            }

            GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::BeginAccept() returning AsyncResult:" + ValidationHelper.HashString(asyncResult));

            return asyncResult;
        }
Пример #4
0
 public IAsyncResult BeginAccept(AsyncCallback callback, object state)
 {
     if (this.CanUseAcceptEx)
     return this.BeginAccept(0, callback, state);
       if (Socket.s_LoggingEnabled)
     Logging.Enter(Logging.Sockets, (object) this, "BeginAccept", "");
       if (this.CleanedUp)
     throw new ObjectDisposedException(this.GetType().FullName);
       AcceptAsyncResult acceptAsyncResult = new AcceptAsyncResult((object) this, state, callback);
       acceptAsyncResult.StartPostingAsyncOp(false);
       this.DoBeginAccept((LazyAsyncResult) acceptAsyncResult);
       acceptAsyncResult.FinishPostingAsyncOp(ref this.Caches.AcceptClosureCache);
       if (Socket.s_LoggingEnabled)
     Logging.Exit(Logging.Sockets, (object) this, "BeginAccept", (object) acceptAsyncResult);
       return (IAsyncResult) acceptAsyncResult;
 }
Пример #5
0
 public IAsyncResult BeginAcceptChannel(AsyncCallback callback, object state)
 {
     AcceptAsyncResult completionHandle = new AcceptAsyncResult(callback, state, this);
     this.actorManager.SendMessage(this.transportReceivingActor, new AcceptRequestMessage(completionHandle));
     return completionHandle;
 }
Пример #6
0
 public AcceptRequestMessage(AcceptAsyncResult completionHandle)
 {
     this.completionHandle = completionHandle;
 }
 public IAsyncResult BeginAccept(AsyncCallback callback, object state)
 {
     if (this.CanUseAcceptEx)
     {
         return this.BeginAccept(0, callback, state);
     }
     if (s_LoggingEnabled)
     {
         Logging.Enter(Logging.Sockets, this, "BeginAccept", "");
     }
     if (this.CleanedUp)
     {
         throw new ObjectDisposedException(base.GetType().FullName);
     }
     AcceptAsyncResult asyncResult = new AcceptAsyncResult(this, state, callback);
     asyncResult.StartPostingAsyncOp(false);
     this.DoBeginAccept(asyncResult);
     asyncResult.FinishPostingAsyncOp(ref this.Caches.AcceptClosureCache);
     if (s_LoggingEnabled)
     {
         Logging.Exit(Logging.Sockets, this, "BeginAccept", asyncResult);
     }
     return asyncResult;
 }