Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site umcp-cs.UUCP Path: utzoo!decvax!decwrl!amdcad!lll-crg!gymble!umcp-cs!chris From: chris@umcp-cs.UUCP (Chris Torek) Newsgroups: net.unix-wizards Subject: Re: inter-process communication Message-ID: <3015@umcp-cs.UUCP> Date: Sun, 2-Feb-86 10:45:09 EST Article-I.D.: umcp-cs.3015 Posted: Sun Feb 2 10:45:09 1986 Date-Received: Sun, 2-Feb-86 23:52:47 EST References: <2532@gatech.CSNET> Distribution: na Organization: U of Maryland, Computer Science Dept., College Park, MD Lines: 95 Keywords: fcntl, select, pipe, kill, signal I am not sure about 4.2, but SIGIO works in 4.3, at least judging by the kernel code. But whether or not it works in 4.2 you will still have to use a select loop in a signal handler, because (as you noted) signals are not queued. #include #include #include #ifndef FD_ZERO /* 4.2, alas */ #define FD_ZERO(p) ((p)->fds_bits = 0) #define FD_SET(n, p) ((p)->fds_bits |= 1 << (n)) #define FD_CLR(n, p) ((p)->fds_bits &= ~(1 << (n))) #define FD_ISSET(n, p) ((p)->fds_bits & (1 << (n))) #endif int sockets[N]; /* for some N */ int nsockets; ... signal(SIGIO, asyncinput); ... /* * Poll all the sockets to see who has input ready. */ asyncinput() { register int i, cc; int nfds = 0; fd_set inset, intemp; struct timeval tv; extern int errno; /* * Initialise `inset', then set bits for the descriptors * in which we are interested. Also note the highest * descriptor, and add one; this is the number of * `interesting' descriptors in inset. (Passing an * exact value helps the kernel run us faster.) */ FD_ZERO(&inset); /* init */ for (i = 0; i < nsockets; i++) { FD_SET(sockets[i], &inset); if (sockets[i] >= nfds) nfds = sockets[i] + 1; } tv.tv_sec = 0; /* poll */ tv.tv_usec = 0; /* * Select until there is no more input available. Since * select() clobbers its masks, we use a copy of inset. * The select is done with a `poll' (time out immediately * if nothing ready). */ for (;;) { intemp = inset; cc = select(max, &intemp, (fd_set *) 0, (fd_set *) 0, &tv); if (cc < 0) { if (errno == EINTR) continue; /* handle select error */ } if (cc == 0) return; /* none left (timed out) */ for (i = 0; i < nsockets; i++) if (FD_ISSET(sockets[i], &intemp)) readsocket(sockets[i]); /* all done with input, try again for more */ } } Something like the above should work with explicit `kill's to wake up readers as well as with SIGIOs from the kernel. Oh, important: you must use F_SETOWN before you will get any SIGIOs: me = getpid(); /* or -getpid() for process group instead of single owner */ for (i = 0; i < nsockets; i++) if (fcntl(sockets[i], F_SETOWN, mypid)) oops(); /* handle error */ This is no doubt true in 4.2 as well. (You can substitute an ioctl(SIOCSPGRP) for F_SETOWN, though I think the former is clearer.) You may get a performance increase by setting the select timeout to a few milliseconds, depending on how much message passing goes on versus how much computation. Experiment a bit. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1415) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@mimsy.umd.edu