int Ns_SockPipe ( SOCKET socks[2] );
Ns_SockPipe returns a pair of connected sockets. On Unix, Ns_SockPipe uses socketpair(). A socket pipe can be used for IPC between threads or as a way to wakeup a thread waiting in a select call as in the example below.
SOCKET sockPipe[2]; /* Init - called at startup to create the pipe. */ void Init(void) { Ns_SockPipe(sockPipe); } /* Wakeup - called by another thread to stop InteruptableIO in another thread. */ void Wakeup(void) { send(sockPipe[1], "w", 1, 0); } /* InterruptableIO - called by a thread dedicated to reading from a remote host. Reading will continue until another thread calls Wakeup, causing sockPipe to be readable. */ void InteruptableIO(void) { SOCKET sock, max; fd_set set; char sig; sock = Ns_SockConnect("slowmachine", 6767); FD_ZERO(&set); FD_SET(sock, &set); FD_SET(sockPipe[0], &set); max = sockPipe; if (sock > max) { max = sock; } while (1) { select(max+1, &set, NULL, NULL, NULL); if (FD_ISSET(sockPipe[0], &set)) { /* Another thread called Wakeup(). * Read the signal and return. */ recv(sockPipe[0], &sig, 1, 0); closesocket(sock); return; } else if (FD_ISSET(sock, &set)) { recv(sock, buf, sizeof(buf), 0); ... process buf ... } } }
Note: Interruptable I/O typically makes use of the alarm() system call on Unix. The method above, used throughout AOLserver, works on all platforms and avoids the alarm system call which is inappropriate for a multithreaded application.