internal static int FillFdSetFromSocketList(ref Interop.Sys.FdSet fdset, IList socketList) { if (socketList == null || socketList.Count == 0) { return(0); } int maxFd = -1; for (int i = 0; i < socketList.Count; i++) { var socket = socketList[i] as Socket; if (socket == null) { throw new ArgumentException(SR.Format(SR.net_sockets_select, socketList[i].GetType().FullName, typeof(System.Net.Sockets.Socket).FullName), "socketList"); } int fd = socket._handle.FileDescriptor; fdset.Set(fd); if (fd > maxFd) { maxFd = fd; } } return(maxFd + 1); }
// Transform the list socketList such that the only sockets left are those // with a file descriptor contained in the array "fileDescriptorArray". internal static void FilterSocketListUsingFdSet(ref Interop.Sys.FdSet fdset, IList socketList) { if (socketList == null || socketList.Count == 0) { return; } lock (socketList) { for (int i = socketList.Count - 1; i >= 0; i--) { var socket = (Socket)socketList[i]; if (!fdset.IsSet(socket._handle.FileDescriptor)) { socketList.RemoveAt(i); } } } }
public static unsafe SocketError Select(IList checkRead, IList checkWrite, IList checkError, int microseconds) { var readSet = new Interop.Sys.FdSet(); int maxReadFd = Socket.FillFdSetFromSocketList(ref readSet, checkRead); var writeSet = new Interop.Sys.FdSet(); int maxWriteFd = Socket.FillFdSetFromSocketList(ref writeSet, checkWrite); var errorSet = new Interop.Sys.FdSet(); int maxErrorFd = Socket.FillFdSetFromSocketList(ref errorSet, checkError); int fdCount = 0; Interop.Sys.FdSet* readFds = null; Interop.Sys.FdSet* writeFds = null; Interop.Sys.FdSet* errorFds = null; if (maxReadFd != 0) { readFds = &readSet; fdCount = maxReadFd; } if (maxWriteFd != 0) { writeFds = &writeSet; if (maxWriteFd > fdCount) { fdCount = maxWriteFd; } } if (maxErrorFd != 0) { errorFds = &errorSet; if (maxErrorFd > fdCount) { fdCount = maxErrorFd; } } int socketCount; Interop.Error err = Interop.Sys.Select(fdCount, readFds, writeFds, errorFds, microseconds, &socketCount); GlobalLog.Print("Socket::Select() Interop.libc.select returns socketCount:" + socketCount); if (err != Interop.Error.SUCCESS) { return GetSocketErrorForErrorCode(err); } Socket.FilterSocketListUsingFdSet(ref readSet, checkRead); Socket.FilterSocketListUsingFdSet(ref writeSet, checkWrite); Socket.FilterSocketListUsingFdSet(ref errorSet, checkError); return SocketError.Success; }
public static unsafe SocketError Poll(SafeCloseSocket handle, int microseconds, SelectMode mode, out bool status) { var fdSet = new Interop.Sys.FdSet(); fdSet.Set(handle.FileDescriptor); int fdCount = 0; Interop.Sys.FdSet* readFds = null; Interop.Sys.FdSet* writeFds = null; Interop.Sys.FdSet* errorFds = null; switch (mode) { case SelectMode.SelectRead: readFds = &fdSet; fdCount = handle.FileDescriptor + 1; break; case SelectMode.SelectWrite: writeFds = &fdSet; fdCount = handle.FileDescriptor + 1; break; case SelectMode.SelectError: errorFds = &fdSet; fdCount = handle.FileDescriptor + 1; break; } int socketCount = 0; Interop.Error err = Interop.Sys.Select(fdCount, readFds, writeFds, errorFds, microseconds, &socketCount); if (err != Interop.Error.SUCCESS) { status = false; return GetSocketErrorForErrorCode(err); } status = fdSet.IsSet(handle.FileDescriptor); return SocketError.Success; }