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.