Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!uwmcsd1!ig!agate!ucbvax!hplabs!hplabsb!quan From: quan@hplabsb.UUCP (Suu Quan) Newsgroups: comp.unix.questions Subject: Re: signals interrupting IPC functions Summary: RESTART the system read Keywords: ...worried about data loss... Message-ID: <4915@hplabsb.UUCP> Date: 24 Sep 88 00:37:14 GMT References: <216@ISIDAPS5.UUCP> Organization: HP Labs, Manufacturing & Measurement Systems Lab, Palo Alto, CA Lines: 40 In article <216@ISIDAPS5.UUCP>, mike@ISIDAPS5.UUCP (Mike Maloney) writes: > When a call to msgrcv terminates because of the arrival of a signal, > is it possible that a message on the queue could be lost? I want > to be able to read a message queue and process messages as soon as > they arrive, or timeout and do other stuff after 3 seconds: > > signal(SIG_ALARM, timeout); > alarm(3); > > s = msgrcv(id, buf, size, 0, 0); > if (s == -1) > { if (errno == EINTR) > Timeout happened....do stuff. > else > Some other dasterdly error occurred. > } > else /* Timeout did not occur. */ > { alarm(0); /* Cancel alarm. */ > ...process message that arrived. > } > > The code for the 'timeout' function does absolutely nothing. Just > the fact that the signal was caught should cause msgrcv to return. > > I'm worried about the alarm clobbering msgrcv() and causing it to > drop a message. Does msgrcv guard against this? > msgrcv() -I don't think - is not an atomic operation. It may be signaled in the middle of a reception, and you may loose messages. I suggest the following pseudo code for your timeout routine. timeout(signo, code, scp) int signo, code; register struct sigcontext *scp; { if (incoming queue has no-zero message length) if (scp != NULL) scp->syscall_action = SIG_RESTART; } This should restart your msgrecv() if there is something in it and disrupt msgrecv() if there is none.