Esempio n. 1
0
        private bool SetAsyncEventSelect(AsyncEventBits blockEventBits)
        {
            GlobalLog.Enter("Socket#" + ValidationHelper.HashString(this) + "::SetAsyncEventSelect", "blockEventBits:" + blockEventBits.ToString() + " m_BlockEventBits:" + m_BlockEventBits.ToString() + " willBlockInternal:" + willBlockInternal.ToString());
            GlobalLog.Assert(blockEventBits != AsyncEventBits.FdNone, "Socket#{0}::SetAsyncEventSelect|Use UnsetAsyncEventSelect for FdNone.", ValidationHelper.HashString(this));
            GlobalLog.Assert(m_BlockEventBits == AsyncEventBits.FdNone || m_BlockEventBits == blockEventBits, "Socket#{0}::SetAsyncEventSelect|Can't change from one active wait to another.", ValidationHelper.HashString(this));
            GlobalLog.Assert(m_RegisteredWait == null, "Socket#{0}::SetAsyncEventSelect|Already actively waiting on an op.", ValidationHelper.HashString(this));

            // This check is bogus, too late diggin into a historical reason for it.
            // Make sure the upper level will fail with ObjectDisposedException
            if (m_RegisteredWait != null)
                return false;

            //
            // This will put us into non-blocking mode.  Create the event if it isn't, and register a wait.
            //
            if (m_AsyncEvent == null)
            {
                Interlocked.CompareExchange<ManualResetEvent>(ref m_AsyncEvent, new ManualResetEvent(false), null);
                if (s_RegisteredWaitCallback == null)
                    s_RegisteredWaitCallback = new WaitOrTimerCallback(RegisteredWaitCallback);
            }

            //
            // Try to win over Dispose is there is a ----
            //
            if (Interlocked.CompareExchange(ref m_IntCleanedUp, 2, 0) != 0)
            {
                GlobalLog.Leave("Socket#" + ValidationHelper.HashString(this) + "::SetAsyncEventSelect() Already Cleaned up, returning ... ", string.Empty);
                return false;
            }

            try
            {
                m_BlockEventBits = blockEventBits;
                m_RegisteredWait = ThreadPool.UnsafeRegisterWaitForSingleObject(m_AsyncEvent, s_RegisteredWaitCallback, this, Timeout.Infinite, true);
            }
            finally
            {
                //
                // Release dispose if any is waiting
                //
                Interlocked.Exchange(ref m_IntCleanedUp, 0);
            }

            SocketError errorCode = SocketError.NotSocket;
            //
            // issue the native call
            //
            try {
                errorCode = UnsafeNclNativeMethods.OSSOCK.WSAEventSelect(m_Handle, m_AsyncEvent.SafeWaitHandle, blockEventBits);
            }
            catch (Exception e)
            {
                if (NclUtilities.IsFatal(e))
                    throw;
                GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::SetAsyncEventSelect() !!! (converting to ObjectDisposed) Exception :" + e.ToString());
                GlobalLog.Assert(CleanedUp, "Socket#{0}::SetAsyncEventSelect|WSAEventSelect got exception and CleanedUp not set.", ValidationHelper.HashString(this));
            }

            if (errorCode==SocketError.SocketError) {
                //
                // update our internal state after this socket error
                // we won't throw since this is an internal method
                //
                UpdateStatusAfterSocketError(errorCode);
            }

            //
            // the call to WSAEventSelect will put us in non-blocking mode, 
            // hence we need update internal status
            //
            willBlockInternal = false;

            GlobalLog.Leave("Socket#" + ValidationHelper.HashString(this) + "::SetAsyncEventSelect", "m_BlockEventBits:" + m_BlockEventBits.ToString() + " willBlockInternal:" + willBlockInternal.ToString());
            return errorCode == SocketError.Success;
        }
Esempio n. 2
0
        //
        // Does internal initalization before async winsock
        // call to BeginConnect() or BeginAccept().
        //
        internal void SetAsyncEventSelect(AsyncEventBits blockEventBits) {
            GlobalLog.Enter("Socket#" + ValidationHelper.HashString(this) + "::SetAsyncEventSelect", "blockEventBits:" + blockEventBits.ToString() + " m_BlockEventBits:" + m_BlockEventBits.ToString() + " willBlockInternal:" + willBlockInternal.ToString());

            if (blockEventBits==m_BlockEventBits) {
                //
                // nothing for us to do, nothing is going to change
                //
                GlobalLog.Leave("Socket#" + ValidationHelper.HashString(this) + "::SetAsyncEventSelect", "nothing to do");
                return;
            }

            //
            // We need to select socket first, enabling us to listen to events
            // then submit the event to the thread pool, and then finally
            // call the function we wish to call.
            // the following event is not used in Send/Receive async APIs
            //
            IntPtr eventHandle;
            if (blockEventBits==AsyncEventBits.FdNone) {
                //
                // this will cancel any previous WSAEventSelect() and will put us back
                // into blocking mode. custom build the native parameters
                //
                if (m_AsyncEvent!=null) {
                    m_AsyncEvent = null;
                }
                eventHandle = IntPtr.Zero;
            }
            else {
                //
                // this will put us into non-blocking mode.
                // we'll need the real pointer here
                //
                if (m_AsyncEvent==null) {
                    m_AsyncEvent = new AutoResetEvent(false);
                }
                eventHandle = m_AsyncEvent.Handle;
            }

            //
            // save blockEventBits
            //
            m_BlockEventBits = blockEventBits;

            //
            // issue the native call
            //
            int errorCode =
                UnsafeNclNativeMethods.OSSOCK.WSAEventSelect(
                    m_Handle,
                    eventHandle,
                    m_BlockEventBits );

            if (errorCode==SocketErrors.SocketError) {
                //
                // update our internal state after this socket error
                // we won't throw since this is an internal method
                //
                UpdateStatusAfterSocketError();
            }

            //
            // the call to WSAEventSelect might have caused us to change
            // blocking mode, hence we need update internal status
            //
            willBlockInternal = willBlockInternal && m_BlockEventBits==AsyncEventBits.FdNone;

            GlobalLog.Leave("Socket#" + ValidationHelper.HashString(this) + "::SetAsyncEventSelect", "m_BlockEventBits:" + m_BlockEventBits.ToString() + " willBlockInternal:" + willBlockInternal.ToString());
        }