|
|
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.