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

sleep() and device drivers ...



A question:

Is there a safe way for a device driver function to decide whether a call to
sleep() was interrupted by delivery of a signal, or (even better) a way to
make sure the functions arguments are still valid after a sleep()?

To understand why this is important, look at a piece of code from pipe_write():
(Read first (1), then (2))

	if (nbytes > 0 && nbytes <= PIPE_BUF) {
check_atomicity:
		r = p->tail - p->head;
/* (2)
 * Here we dereference p, which is a pointer to one of the fifos pipes.
 * Because we might get here after sleep() (see (2)), *p's memory could
 * have been freed and we are in trouble!
 */
		if (r < 0) r += PIPESIZ;
		r = (PIPESIZ-1) - r;
		if (r < nbytes) {
			if (p->readers == 0 || p->readers == VIRGIN_PIPE) {
				check_sigs();
				DEBUG(("pipe_write: broken pipe"));
				raise(SIGPIPE);
				return EPIPE;
			}
			if (p->rsel) {
				wakeselect(p->rsel);
				p->rsel = 0;
			}
			wake(IO_Q, (long)p);
			sleep(IO_Q, (long)p);
/* (1)
 * Woken up from sleep(). Because sleep() has an embedded call of check_sigs()
 * in it, a signal handler function could just have Fclose()'d all references
 * to the fifo. Because then there are no more readers/writers, pipe_close()
 * kfree()'s all the fifo's memory.
 */
			goto check_atomicity;
		}
	}


Unixes check for delivery of signals in such situations and return EINTR
if appropriate or restart the whole system call if possible.

I'd be grateful for any suggestions.

-- kay roemer.