resolver un-conditionally restarts interrupted kevent
David Xu
davidxu at freebsd.org
Wed Jan 26 17:57:06 PST 2005
Christian S.J. Peron wrote:
> Hey
>
> I've noticed kind of an anoying feature with our resolver. It
> seems that if a process recieves a signal while waiting for a
> DNS response, kevent(2) will fail returning EINTR which sounds
> right. However I also noticed this:
>
> n = _kevent(kq, &kv, 1, &kv, 1, &ts);
> if (n < 0) {
> if (errno == EINTR) {
> (void) gettimeofday(&ctv, NULL);
> if (timercmp(&ctv, &timeout, <)) {
> timersub(&timeout, &ctv, &ctv);
> TIMEVAL_TO_TIMESPEC(&ctv, &ts);
> goto wait;
>
> Which un-conditionally restarts kevent(2) in the event of a signal.
> Logic tells me that the right way to do this would be to have the
> process set SA_RESTART when it registers a signal handler, and have
> kevent return ERESTART and IF kevent returns ERESTART, restart the
> signal.
>
> After further investigation into our multiplexing mechanisms like
> poll, select and kevent explicitly change ERESTART to EINTR.
>
> /* don't restart after signals... */
> if (error == ERESTART)
> error = EINTR;
> else if (error == EWOULDBLOCK)
> error = 0;
> goto done;
>
> So I guess I have two questions
>
> 1) why do we explicitly change ERESTART to EINTR?
Because they can not be simply restarted. those interfaces
have in/out parameters which may already be changed by kernel
before returning, also a timeout wait can not be restarted, you
told kernel to sleep 10 minutes, and at minute 9, it gets a signal
and is restarted, it will return to user code after totally 19
minutes.
> 2) why do we unconditionally restart kevent in our
> resolver code?
>
I think that's right because the code checks 'n < 0' first,
it got nothing and does timeout calculation by itself, that's OK.
> Any insight would be great, thanks!
>
More information about the freebsd-arch
mailing list