public static SocketError Select(IList checkRead, IList checkWrite, IList checkError, int microseconds)
        {
            IntPtr[] readfileDescriptorSet  = Socket.SocketListToFileDescriptorSet(checkRead);
            IntPtr[] writefileDescriptorSet = Socket.SocketListToFileDescriptorSet(checkWrite);
            IntPtr[] errfileDescriptorSet   = Socket.SocketListToFileDescriptorSet(checkError);

            // This code used to erroneously pass a non-null timeval structure containing zeroes
            // to select() when the caller specified (-1) for the microseconds parameter.  That
            // caused select to actually have a *zero* timeout instead of an infinite timeout
            // turning the operation into a non-blocking poll.
            //
            // Now we pass a null timeval struct when microseconds is (-1).
            //
            // Negative microsecond values that weren't exactly (-1) were originally successfully
            // converted to a timeval struct containing unsigned non-zero integers.  This code
            // retains that behavior so that any app working around the original bug with,
            // for example, (-2) specified for microseconds, will continue to get the same behavior.

            int socketCount;

            if (microseconds != -1)
            {
                Interop.Winsock.TimeValue IOwait = new Interop.Winsock.TimeValue();
                MicrosecondsToTimeValue((long)(uint)microseconds, ref IOwait);

                socketCount =
                    Interop.Winsock.select(
                        0, // ignored value
                        readfileDescriptorSet,
                        writefileDescriptorSet,
                        errfileDescriptorSet,
                        ref IOwait);
            }
            else
            {
                socketCount =
                    Interop.Winsock.select(
                        0, // ignored value
                        readfileDescriptorSet,
                        writefileDescriptorSet,
                        errfileDescriptorSet,
                        IntPtr.Zero);
            }

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(null, $"Interop.Winsock.select returns socketCount:{socketCount}");
            }

            if ((SocketError)socketCount == SocketError.SocketError)
            {
                return(GetLastSocketError());
            }

            Socket.SelectFileDescriptor(checkRead, readfileDescriptorSet);
            Socket.SelectFileDescriptor(checkWrite, writefileDescriptorSet);
            Socket.SelectFileDescriptor(checkError, errfileDescriptorSet);

            return(SocketError.Success);
        }
        private static void MicrosecondsToTimeValue(long microseconds, ref Interop.Winsock.TimeValue socketTime)
        {
            const int microcnv = 1000000;

            socketTime.Seconds      = (int)(microseconds / microcnv);
            socketTime.Microseconds = (int)(microseconds % microcnv);
        }
Beispiel #3
0
        public static unsafe SocketError Poll(SafeSocketHandle handle, int microseconds, SelectMode mode, out bool status)
        {
            bool refAdded = false;

            try
            {
                handle.DangerousAddRef(ref refAdded);

                IntPtr  rawHandle         = handle.DangerousGetHandle();
                IntPtr *fileDescriptorSet = stackalloc IntPtr[2] {
                    (IntPtr)1, rawHandle
                };
                Interop.Winsock.TimeValue IOwait = default;

                // A negative timeout value implies an indefinite wait.
                int socketCount;
                if (microseconds != -1)
                {
                    MicrosecondsToTimeValue((long)(uint)microseconds, ref IOwait);
                    socketCount =
                        Interop.Winsock.select(
                            0,
                            mode == SelectMode.SelectRead ? fileDescriptorSet : null,
                            mode == SelectMode.SelectWrite ? fileDescriptorSet : null,
                            mode == SelectMode.SelectError ? fileDescriptorSet : null,
                            ref IOwait);
                }
                else
                {
                    socketCount =
                        Interop.Winsock.select(
                            0,
                            mode == SelectMode.SelectRead ? fileDescriptorSet : null,
                            mode == SelectMode.SelectWrite ? fileDescriptorSet : null,
                            mode == SelectMode.SelectError ? fileDescriptorSet : null,
                            IntPtr.Zero);
                }

                if ((SocketError)socketCount == SocketError.SocketError)
                {
                    status = false;
                    return(GetLastSocketError());
                }

                status = (int)fileDescriptorSet[0] != 0 && fileDescriptorSet[1] == rawHandle;
                return(SocketError.Success);
            }
            finally
            {
                if (refAdded)
                {
                    handle.DangerousRelease();
                }
            }
        }
        public static SocketError Poll(SafeCloseSocket handle, int microseconds, SelectMode mode, out bool status)
        {
            IntPtr rawHandle = handle.DangerousGetHandle();

            IntPtr[] fileDescriptorSet = new IntPtr[2] {
                (IntPtr)1, rawHandle
            };
            Interop.Winsock.TimeValue IOwait = new Interop.Winsock.TimeValue();

            // A negative timeout value implies an indefinite wait.
            int socketCount;

            if (microseconds != -1)
            {
                MicrosecondsToTimeValue((long)(uint)microseconds, ref IOwait);
                socketCount =
                    Interop.Winsock.select(
                        0,
                        mode == SelectMode.SelectRead ? fileDescriptorSet : null,
                        mode == SelectMode.SelectWrite ? fileDescriptorSet : null,
                        mode == SelectMode.SelectError ? fileDescriptorSet : null,
                        ref IOwait);
            }
            else
            {
                socketCount =
                    Interop.Winsock.select(
                        0,
                        mode == SelectMode.SelectRead ? fileDescriptorSet : null,
                        mode == SelectMode.SelectWrite ? fileDescriptorSet : null,
                        mode == SelectMode.SelectError ? fileDescriptorSet : null,
                        IntPtr.Zero);
            }

            if ((SocketError)socketCount == SocketError.SocketError)
            {
                status = false;
                return(GetLastSocketError());
            }

            status = (int)fileDescriptorSet[0] != 0 && fileDescriptorSet[1] == rawHandle;
            return(SocketError.Success);
        }
Beispiel #5
0
        public static SocketError Select(IList checkRead, IList checkWrite, IList checkError, int microseconds)
        {
            IntPtr[] readfileDescriptorSet = Socket.SocketListToFileDescriptorSet(checkRead);
            IntPtr[] writefileDescriptorSet = Socket.SocketListToFileDescriptorSet(checkWrite);
            IntPtr[] errfileDescriptorSet = Socket.SocketListToFileDescriptorSet(checkError);

            // This code used to erroneously pass a non-null timeval structure containing zeroes 
            // to select() when the caller specified (-1) for the microseconds parameter.  That 
            // caused select to actually have a *zero* timeout instead of an infinite timeout
            // turning the operation into a non-blocking poll.
            //
            // Now we pass a null timeval struct when microseconds is (-1).
            // 
            // Negative microsecond values that weren't exactly (-1) were originally successfully 
            // converted to a timeval struct containing unsigned non-zero integers.  This code 
            // retains that behavior so that any app working around the original bug with, 
            // for example, (-2) specified for microseconds, will continue to get the same behavior.

            int socketCount;
            if (microseconds != -1)
            {
                Interop.Winsock.TimeValue IOwait = new Interop.Winsock.TimeValue();
                MicrosecondsToTimeValue((long)(uint)microseconds, ref IOwait);

                socketCount =
                    Interop.Winsock.select(
                        0, // ignored value
                        readfileDescriptorSet,
                        writefileDescriptorSet,
                        errfileDescriptorSet,
                        ref IOwait);
            }
            else
            {
                socketCount =
                    Interop.Winsock.select(
                        0, // ignored value
                        readfileDescriptorSet,
                        writefileDescriptorSet,
                        errfileDescriptorSet,
                        IntPtr.Zero);
            }

            GlobalLog.Print("Socket::Select() Interop.Winsock.select returns socketCount:" + socketCount);

            if ((SocketError)socketCount == SocketError.SocketError)
            {
                return GetLastSocketError();
            }

            Socket.SelectFileDescriptor(checkRead, readfileDescriptorSet);
            Socket.SelectFileDescriptor(checkWrite, writefileDescriptorSet);
            Socket.SelectFileDescriptor(checkError, errfileDescriptorSet);

            return SocketError.Success;
        }
Beispiel #6
0
        public static SocketError Poll(SafeCloseSocket handle, int microseconds, SelectMode mode, out bool status)
        {
            IntPtr rawHandle = handle.DangerousGetHandle();
            IntPtr[] fileDescriptorSet = new IntPtr[2] { (IntPtr)1, rawHandle };
            Interop.Winsock.TimeValue IOwait = new Interop.Winsock.TimeValue();

            // A negative timeout value implies an indefinite wait.
            int socketCount;
            if (microseconds != -1)
            {
                MicrosecondsToTimeValue((long)(uint)microseconds, ref IOwait);
                socketCount =
                    Interop.Winsock.select(
                        0,
                        mode == SelectMode.SelectRead ? fileDescriptorSet : null,
                        mode == SelectMode.SelectWrite ? fileDescriptorSet : null,
                        mode == SelectMode.SelectError ? fileDescriptorSet : null,
                        ref IOwait);
            }
            else
            {
                socketCount =
                    Interop.Winsock.select(
                        0,
                        mode == SelectMode.SelectRead ? fileDescriptorSet : null,
                        mode == SelectMode.SelectWrite ? fileDescriptorSet : null,
                        mode == SelectMode.SelectError ? fileDescriptorSet : null,
                        IntPtr.Zero);
            }

            if ((SocketError)socketCount == SocketError.SocketError)
            {
                status = false;
                return GetLastSocketError();
            }

            status = (int)fileDescriptorSet[0] != 0 && fileDescriptorSet[1] == rawHandle;
            return SocketError.Success;
        }