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); }
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); }
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; }
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; }