[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: signals and atomicity



> if you implement "interruptible" system calls this way: 1. UNBLOCK
> SIGNAL 2. SYSTEM CALL 3. BLOCK SIGNAL it may happen that the signal
> handler is called just after unblocking the signal but before the
> call. this way no EINTR happens, the signal is lost and (2) is stuck
> in the system call.
> 
> because of this, i have to do a siglongjmp() in the signal handler.
> now it isn't anymore possible that signals get lost. BUT ! i do not
> know the return value of the system call, if it was interrupted.
> remember, after the call , the signal is blocked again. now, if the
> call succeeded, but still before the BLOCK SIGNAL command, if now
> again a signal is received, siglongjmp jumps away, and the fact,
> that the system call succeeded is just lost.

You can solve it this way (at least I hope... :-) :

static int timeout;

static void alarm_handler(int sig) {
	timeout = 1; 
}

int wait_or_timeout (int *status) {
	struct sigaction act;
	int wait_retval;

	timeout = 0;

	sigaction(SIGALRM, 0, &act);
	act.sa_handler = alarm_handler;
	act.sa_flags &= ~SA_RESTART;
	sigaction(SIGALRM, &act, 0);
	alarm(1);
	wait_retval = wait(status);
	alarm(0); 
	/* ... */
}

If 'timeout' is set at the end, SIGALRM was delivered before the
alarm(0). On the other hand, wait_retval is -EINTR if and only if the
system call itself has been interrupted. So you can distinguish
between the cases "system call interrupted" and "signal arrived, but
somewhere around the syscall".

Roman


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org


Reply to: