mike@ISIDAPS5.UUCP (Mike Maloney) (09/23/88)
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? Please confirm my fears or set my mind at ease. -- Mike Maloney "That's like saying 'if we had Integral Systems, Inc. eggs we could have bacon and eggs Lanham, Maryland 20706 if we had bacon'" - Sid (301) 731-4233 ext. 165
dave@micropen (David F. Carlson) (09/23/88)
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: > s = msgrcv(id, buf, size, 0, 0); > { if (errno == EINTR) > > Please confirm my fears or set my mind at ease. > Mike Maloney "That's like saying 'if we had RTFM: signal(2): "When a signal to be caught occurs during read(2), a write(2), an open(2), an ioctl(2) or system call to a slow device, ... during pause(2) or wait(2), ... the system call may return -1 to the calling process with errno set to EINTR." No mention of msgrcv(2) at all. I believe since it is not mentioned, it is guaranteed not to occur. -- David F. Carlson, Micropen, Inc. micropen!dave@ee.rochester.edu "The faster I go, the behinder I get." --Lewis Carroll
quan@hplabsb.UUCP (Suu Quan) (09/24/88)
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.
jfh@rpp386.Dallas.TX.US (The Beach Bum) (09/25/88)
In article <548@micropen> dave@micropen (David F. Carlson) writes: } 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? } } RTFM: signal(2): } "When a signal to be caught occurs during read(2), a write(2), an open(2), } an ioctl(2) or system call to a slow device, ... during pause(2) or wait(2), } ... the system call may return -1 to the calling process with errno set } to EINTR." } } No mention of msgrcv(2) at all. I believe since it is not mentioned, it } is guaranteed not to occur. incorrect. the page for msgrcv(2) states that if IPC_NOWAIT is false in the call to msgrcv() and a signal which is set to be received occurs, then msgrcv() returns -1 and errno == EINTR. this behavior is going to be true, in general, of all system calls which can be expected to block for more than a brief period of time. the only requirement that a system call be interuptable is that it does not sleep at less than PZERO. to answer david's question - not likely unless there is a race in the kernel i've never seen posted to the net. the two situations involve either the process sending itself a signal [ SIGALRM being the only one it can ] or some other process sending it a signal. some other process can only send it a signal if no message is ready to be read [ more or less ], so the message, which isn't being processed because it doesn't exist, can't be lost. the only signal a process can send itself while blocked in a system call is SIGALRM. if the process is blocked at the moment, no big deal, same situation as above. otherwise, the exact result depends on the scheduler and how it works. but generally i'd say the answer is no. -- John F. Haugh II (jfh@rpp386.Dallas.TX.US) HASA, "S" Division "Why waste negative entropy on comments, when you could use the same entropy to create bugs instead?" -- Steve Elias