//
        // This is the internal callback that will be called when
        // the IO we issued for the user to winsock has completed.
        // when this function gets called it must:
        // 1) update the AsyncResult object with the results of the completed IO
        // 2) signal events that the user might be waiting on
        // 3) call the callback function that the user might have specified
        //
        // This method was copied from a ConnectAsyncResult class that became useless.
        private void ConnectCallback()
        {
            LazyAsyncResult asyncResult = (LazyAsyncResult) m_AcceptQueueOrConnectResult;


            GlobalLog.Enter("Socket#" + ValidationHelper.HashString(this) + "::ConnectCallback");
            //
            // If we came here due to a ---- between BeginConnect and Dispose
            //
            if (asyncResult.InternalPeekCompleted)
            {
                GlobalLog.Assert(CleanedUp, "Socket#{0}::ConnectCallback()|asyncResult is compelted but the socket does not have CleanedUp set.", ValidationHelper.HashString(this));
                GlobalLog.Leave("Socket#" + ValidationHelper.HashString(this) + "::ConnectCallback", "Already completed, socket must be closed");
                return;
            }


            //<STRIP>
            // we now need to get the status of the async completion, we had an easy implementation
            // that uses GetSocketOption(), but VadimE suggested not to use this 'cause it may be
            // buggy on some platforms, so we use WSAEnumNetworkEvents() instead:
            //
            // The best way to do this is to call WSAEnumNetworkEvents and use the error code iError
            // array corresponding to FD_CONNECT. getsockopt (SO_ERROR) may return NO_ERROR under
            // stress even in case of error at least on Winnt4.0 (I don't remember whether I fixed
            // it on Win2000 or WinXP).
            //</STRIP>

            //
            // get async completion
            //
            /*
            int errorCode = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Error);
            GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() GetSocketOption() returns errorCode:" + errorCode.ToString());
            */

            NetworkEvents networkEvents = new NetworkEvents();
            networkEvents.Events = AsyncEventBits.FdConnect;

            SocketError errorCode = SocketError.OperationAborted;
            object result = null;

            try
            {
                if (!CleanedUp)
                {
                    try
                    {
                        errorCode = UnsafeNclNativeMethods.OSSOCK.WSAEnumNetworkEvents(
                            m_Handle,
                            m_AsyncEvent.SafeWaitHandle,
                            ref networkEvents);

                        if (errorCode != SocketError.Success)
                        {
                            errorCode = (SocketError) Marshal.GetLastWin32Error();
                            GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::ConnectCallback() WSAEnumNetworkEvents() failed with errorCode:" + errorCode.ToString());
                        }
                        else
                        {
                            errorCode = (SocketError) networkEvents.ErrorCodes[(int) AsyncEventBitsPos.FdConnectBit];
                            GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::ConnectCallback() ErrorCodes(FdConnect) got errorCode:" + errorCode.ToString());
                        }
                        //
                        // Cancel async event and go back to blocking mode.
                        //
                        UnsetAsyncEventSelect();
                    }
                    catch (ObjectDisposedException)
                    {
                        errorCode = SocketError.OperationAborted;
                    }
                }

                //
                // if the native non-blocking call failed we'll throw a SocketException in EndConnect()
                //
                if (errorCode == SocketError.Success)
                {
                    //
                    // the Socket is connected, update our state and performance counter
                    //
                    SetToConnected();
                }
            }
            catch (Exception exception)
            {
                if (NclUtilities.IsFatal(exception)) throw;

                GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::ConnectCallback() caught exception:" + exception.Message + ", CleanedUp:" + CleanedUp);
                result = exception;
            }

            if (!asyncResult.InternalPeekCompleted)
            {
                // A "ErrorCode" concept is questionable, for ex. below lines are subject to a race condition
                asyncResult.ErrorCode = (int) errorCode;
                asyncResult.InvokeCallback(result);
            }

            GlobalLog.Leave("Socket#" + ValidationHelper.HashString(this) + "::ConnectCallback", errorCode.ToString());
        }
Exemple #2
0
        //
        // This is the internal callback that will be called when
        // the IO we issued for the user to winsock has completed.
        // when this function gets called it must:
        // 1) update the AsyncResult object with the results of the completed IO
        // 2) signal events that the user might be waiting on
        // 3) call the callback function that the user might have specified
        //
        // This method was copied from a ConnectAsyncResult class that became useless.
        private void ConnectCallback()
        {
            LazyAsyncResult asyncResult = (LazyAsyncResult) m_AcceptQueueOrConnectResult;


            GlobalLog.Enter("Socket#" + ValidationHelper.HashString(this) + "::ConnectCallback");
            //
            // If we came here due to a ---- between BeginConnect and Dispose
            //
            if (asyncResult.InternalPeekCompleted)
            {
                GlobalLog.Assert(CleanedUp, "Socket#{0}::ConnectCallback()|asyncResult is compelted but the socket does not have CleanedUp set.", ValidationHelper.HashString(this));
                GlobalLog.Leave("Socket#" + ValidationHelper.HashString(this) + "::ConnectCallback", "Already completed, socket must be closed");
                return;
            }


            //<










            //
            // get async completion
            //
            /*
            int errorCode = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Error);
            GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() GetSocketOption() returns errorCode:" + errorCode.ToString());
            */

            NetworkEvents networkEvents = new NetworkEvents();
            networkEvents.Events = AsyncEventBits.FdConnect;

            SocketError errorCode = SocketError.OperationAborted;
            object result = null;

            try
            {
                if (!CleanedUp)
                {
                    try
                    {
                        errorCode = UnsafeNclNativeMethods.OSSOCK.WSAEnumNetworkEvents(
                            m_Handle,
                            m_AsyncEvent.SafeWaitHandle,
                            ref networkEvents);

                        if (errorCode != SocketError.Success)
                        {
                            errorCode = (SocketError) Marshal.GetLastWin32Error();
                            GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::ConnectCallback() WSAEnumNetworkEvents() failed with errorCode:" + errorCode.ToString());
                        }
                        else
                        {
                            errorCode = (SocketError) networkEvents.ErrorCodes[(int) AsyncEventBitsPos.FdConnectBit];
                            GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::ConnectCallback() ErrorCodes(FdConnect) got errorCode:" + errorCode.ToString());
                        }
                        //
                        // Cancel async event and go back to blocking mode.
                        //
                        UnsetAsyncEventSelect();
                    }
                    catch (ObjectDisposedException)
                    {
                        errorCode = SocketError.OperationAborted;
                    }
                }

                //
                // if the native non-blocking call failed we'll throw a SocketException in EndConnect()
                //
                if (errorCode == SocketError.Success)
                {
                    //
                    // the Socket is connected, update our state and performance counter
                    //
                    SetToConnected();
                }
            }
            catch (Exception exception)
            {
                if (NclUtilities.IsFatal(exception)) throw;

                GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::ConnectCallback() caught exception:" + exception.Message + ", CleanedUp:" + CleanedUp);
                result = exception;
            }

            if (!asyncResult.InternalPeekCompleted)
            {
                // A "ErrorCode" concept is questionable, for ex. below lines are subject to a race condition
                asyncResult.ErrorCode = (int) errorCode;
                asyncResult.InvokeCallback(result);
            }

            GlobalLog.Leave("Socket#" + ValidationHelper.HashString(this) + "::ConnectCallback", errorCode.ToString());
        }
        //
        // This is the static internal callback that will be called when
        // the IO we issued for the user to winsock has completed, either
        // synchronously (Signaled=false) or asynchronously (Signaled=true)
        // when this function gets called it must:
        // 1) update the AsyncResult object with the results of the completed IO
        // 2) signal events that the user might be waiting on
        // 3) cal the callback function that the user might have specified
        //
        internal static void ConnectCallback(object stateObject, bool Signaled) {
            ConnectAsyncResult asyncResult = stateObject as ConnectAsyncResult;
            Socket socket = asyncResult.AsyncObject as Socket;

            GlobalLog.Enter("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback", "Signaled:" + Signaled.ToString());

            GlobalLog.Assert(!asyncResult.IsCompleted, "Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() asyncResult.IsCompleted", "");

            //

            //
            // get async completion
            //
            /*
            int errorCode = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Error);
            GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() GetSocketOption() returns errorCode:" + errorCode.ToString());
            */

            NetworkEvents networkEvents = new NetworkEvents();
            networkEvents.Events = AsyncEventBits.FdConnect;

            AutoResetEvent chkAsyncEvent = socket.m_AsyncEvent;

            int errorCode = SocketErrors.WSAENOTSOCK;

            if (chkAsyncEvent!=null) {
                errorCode =
                    UnsafeNclNativeMethods.OSSOCK.WSAEnumNetworkEvents(
                        socket.m_Handle,
                        chkAsyncEvent.Handle,
                        ref networkEvents );

                if (errorCode!=SocketErrors.Success) {
                    errorCode = Marshal.GetLastWin32Error();
                    GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() WSAEnumNetworkEvents() failed with errorCode:" + errorCode.ToString());
                }
                else {
                    errorCode = networkEvents.ErrorCodes[(int)AsyncEventBitsPos.FdConnectBit];
                    GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() ErrorCodes(FdConnect) got errorCode:" + errorCode.ToString());
                }
            }

            try {
                //
                // cancel async event
                //
                socket.SetAsyncEventSelect(AsyncEventBits.FdNone);
                //
                // go back to blocking mode
                //
                socket.InternalSetBlocking(true);
            }
            catch (Exception exception) {
                GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() caught exception::" + exception.Message);
                asyncResult.Result = exception;
            }

            //
            // if the native non-blocking call failed we'll throw a SocketException in EndConnect()
            //
            if (errorCode!=SocketErrors.Success) {
                //
                // just save the error code, the SocketException will be thrown in EndConnect()
                //
                asyncResult.ErrorCode = errorCode;
            }
            else {
                //
                // the Socket is connected, update our state and performance counter
                //
                socket.SetToConnected();
            }

            //
            // call the user's callback now, if there is one.
            //
            asyncResult.InvokeCallback(false);

            GlobalLog.Leave("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback", errorCode.ToString());
        }
 private void ConnectCallback()
 {
     LazyAsyncResult lazyAsyncResult = (LazyAsyncResult) this.m_AcceptQueueOrConnectResult;
       if (lazyAsyncResult.InternalPeekCompleted)
     return;
       NetworkEvents networkEvents = new NetworkEvents();
       networkEvents.Events = AsyncEventBits.FdConnect;
       SocketError socketError = SocketError.OperationAborted;
       object result = (object) null;
       try
       {
     if (!this.CleanedUp)
     {
       try
       {
     socketError = UnsafeNclNativeMethods.OSSOCK.WSAEnumNetworkEvents(this.m_Handle, this.m_AsyncEvent.SafeWaitHandle, out networkEvents);
     socketError = socketError == SocketError.Success ? (SocketError) networkEvents.ErrorCodes[4] : (SocketError) Marshal.GetLastWin32Error();
     this.UnsetAsyncEventSelect();
       }
       catch (ObjectDisposedException ex)
       {
     socketError = SocketError.OperationAborted;
       }
     }
     if (socketError == SocketError.Success)
       this.SetToConnected();
       }
       catch (Exception ex)
       {
     if (NclUtilities.IsFatal(ex))
       throw;
     else
       result = (object) ex;
       }
       if (lazyAsyncResult.InternalPeekCompleted)
     return;
       lazyAsyncResult.ErrorCode = (int) socketError;
       lazyAsyncResult.InvokeCallback(result);
 }
Exemple #5
0
        //
        // This is the static internal callback that will be called when
        // the IO we issued for the user to winsock has completed, either
        // synchronously (Signaled=false) or asynchronously (Signaled=true)
        // when this function gets called it must:
        // 1) update the AsyncResult object with the results of the completed IO
        // 2) signal events that the user might be waiting on
        // 3) cal the callback function that the user might have specified
        //
        internal static void ConnectCallback(object stateObject, bool Signaled)
        {
            ConnectAsyncResult asyncResult = stateObject as ConnectAsyncResult;
            Socket             socket      = asyncResult.AsyncObject as Socket;

            GlobalLog.Enter("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback", "Signaled:" + Signaled.ToString());

            GlobalLog.Assert(!asyncResult.IsCompleted, "Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() asyncResult.IsCompleted", "");

            //
            // we now need to get the status of the async completion, we had an easy implementation
            // that uses GetSocketOption(), but VadimE suggested not to use this 'cause it may be
            // buggy on some platforms, so we use WSAEnumNetworkEvents() instead:
            //
            // The best way to do this is to call WSAEnumNetworkEvents and use the error code iError
            // array corresponding to FD_CONNECT. getsockopt (SO_ERROR) may return NO_ERROR under
            // stress even in case of error at least on Winnt4.0 (I don't remember whether I fixed
            // it on Win2000 or WinXP).
            //

            //
            // get async completion
            //

            /*
             * int errorCode = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Error);
             * GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() GetSocketOption() returns errorCode:" + errorCode.ToString());
             */

            NetworkEvents networkEvents = new NetworkEvents();

            networkEvents.Events = AsyncEventBits.FdConnect;

            AutoResetEvent chkAsyncEvent = socket.m_AsyncEvent;

            int errorCode = SocketErrors.WSAENOTSOCK;

            if (chkAsyncEvent != null)
            {
                errorCode =
                    UnsafeNclNativeMethods.OSSOCK.WSAEnumNetworkEvents(
                        socket.m_Handle,
                        chkAsyncEvent.Handle,
                        ref networkEvents);

                if (errorCode != SocketErrors.Success)
                {
                    errorCode = Marshal.GetLastWin32Error();
                    GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() WSAEnumNetworkEvents() failed with errorCode:" + errorCode.ToString());
                }
                else
                {
                    errorCode = networkEvents.ErrorCodes[(int)AsyncEventBitsPos.FdConnectBit];
                    GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() ErrorCodes(FdConnect) got errorCode:" + errorCode.ToString());
                }
            }

            try {
                //
                // cancel async event
                //
                socket.SetAsyncEventSelect(AsyncEventBits.FdNone);
                //
                // go back to blocking mode
                //
                socket.InternalSetBlocking(true);
            }
            catch (Exception exception) {
                GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() caught exception::" + exception.Message);
                asyncResult.Result = exception;
            }

            //
            // if the native non-blocking call failed we'll throw a SocketException in EndConnect()
            //
            if (errorCode != SocketErrors.Success)
            {
                //
                // just save the error code, the SocketException will be thrown in EndConnect()
                //
                asyncResult.ErrorCode = errorCode;
            }
            else
            {
                //
                // the Socket is connected, update our state and performance counter
                //
                socket.SetToConnected();
            }

            //
            // call the user's callback now, if there is one.
            //
            asyncResult.InvokeCallback(false);

            GlobalLog.Leave("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback", errorCode.ToString());
        }
Exemple #6
0
        //
        // This is the static internal callback that will be called when
        // the IO we issued for the user to winsock has completed, either
        // synchronously (Signaled=false) or asynchronously (Signaled=true)
        // when this function gets called it must:
        // 1) update the AsyncResult object with the results of the completed IO
        // 2) signal events that the user might be waiting on
        // 3) cal the callback function that the user might have specified
        //
        internal static void ConnectCallback(object stateObject, bool Signaled)
        {
            ConnectAsyncResult asyncResult = stateObject as ConnectAsyncResult;
            Socket             socket      = asyncResult.AsyncObject as Socket;

            GlobalLog.Enter("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback", "Signaled:" + Signaled.ToString());

            GlobalLog.Assert(!asyncResult.IsCompleted, "Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() asyncResult.IsCompleted", "");

            //

            //
            // get async completion
            //

            /*
             * int errorCode = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Error);
             * GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() GetSocketOption() returns errorCode:" + errorCode.ToString());
             */

            NetworkEvents networkEvents = new NetworkEvents();

            networkEvents.Events = AsyncEventBits.FdConnect;

            AutoResetEvent chkAsyncEvent = socket.m_AsyncEvent;

            int errorCode = SocketErrors.WSAENOTSOCK;

            if (chkAsyncEvent != null)
            {
                errorCode =
                    UnsafeNclNativeMethods.OSSOCK.WSAEnumNetworkEvents(
                        socket.m_Handle,
                        chkAsyncEvent.Handle,
                        ref networkEvents);

                if (errorCode != SocketErrors.Success)
                {
                    errorCode = Marshal.GetLastWin32Error();
                    GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() WSAEnumNetworkEvents() failed with errorCode:" + errorCode.ToString());
                }
                else
                {
                    errorCode = networkEvents.ErrorCodes[(int)AsyncEventBitsPos.FdConnectBit];
                    GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() ErrorCodes(FdConnect) got errorCode:" + errorCode.ToString());
                }
            }

            try {
                //
                // cancel async event
                //
                socket.SetAsyncEventSelect(AsyncEventBits.FdNone);
                //
                // go back to blocking mode
                //
                socket.InternalSetBlocking(true);
            }
            catch (Exception exception) {
                GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() caught exception::" + exception.Message);
                asyncResult.Result = exception;
            }

            //
            // if the native non-blocking call failed we'll throw a SocketException in EndConnect()
            //
            if (errorCode != SocketErrors.Success)
            {
                //
                // just save the error code, the SocketException will be thrown in EndConnect()
                //
                asyncResult.ErrorCode = errorCode;
            }
            else
            {
                //
                // the Socket is connected, update our state and performance counter
                //
                socket.SetToConnected();
            }

            //
            // call the user's callback now, if there is one.
            //
            asyncResult.InvokeCallback(false);

            GlobalLog.Leave("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback", errorCode.ToString());
        }
 private void ConnectCallback()
 {
     LazyAsyncResult acceptQueueOrConnectResult = (LazyAsyncResult) this.m_AcceptQueueOrConnectResult;
     if (!acceptQueueOrConnectResult.InternalPeekCompleted)
     {
         NetworkEvents networkEvents = new NetworkEvents {
             Events = AsyncEventBits.FdConnect
         };
         SocketError operationAborted = SocketError.OperationAborted;
         object result = null;
         try
         {
             if (!this.CleanedUp)
             {
                 try
                 {
                     operationAborted = UnsafeNclNativeMethods.OSSOCK.WSAEnumNetworkEvents(this.m_Handle, this.m_AsyncEvent.SafeWaitHandle, ref networkEvents);
                     if (operationAborted != SocketError.Success)
                     {
                         operationAborted = (SocketError) Marshal.GetLastWin32Error();
                     }
                     else
                     {
                         operationAborted = (SocketError) networkEvents.ErrorCodes[4];
                     }
                     this.UnsetAsyncEventSelect();
                 }
                 catch (ObjectDisposedException)
                 {
                     operationAborted = SocketError.OperationAborted;
                 }
             }
             if (operationAborted == SocketError.Success)
             {
                 this.SetToConnected();
             }
         }
         catch (Exception exception)
         {
             if (NclUtilities.IsFatal(exception))
             {
                 throw;
             }
             result = exception;
         }
         if (!acceptQueueOrConnectResult.InternalPeekCompleted)
         {
             acceptQueueOrConnectResult.ErrorCode = (int) operationAborted;
             acceptQueueOrConnectResult.InvokeCallback(result);
         }
     }
 }