Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 27 Jan 2005 10:04:21 +0800
From:      David Xu <davidxu@freebsd.org>
To:        "Christian S.J. Peron" <csjp@freebsd.org>
Cc:        arch@freebsd.org
Subject:   Re: resolver un-conditionally restarts interrupted kevent
Message-ID:  <41F84C25.60903@freebsd.org>
In-Reply-To: <20050127012401.GB48521@freefall.freebsd.org>
References:  <20050127012401.GB48521@freefall.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help


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!
> 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?41F84C25.60903>