Re: resolver un-conditionally restarts interrupted kevent

From: Bruce Evans (bde_at_zeta.org.au)
Date: 01/27/05

  • Next message: Paul Richards: "c99/c++ localised variable definition"
    Date: Fri, 28 Jan 2005 03:07:31 +1100 (EST)
    To: "Christian S.J. Peron" <csjp@freebsd.org>
    
    

    On Wed, 26 Jan 2005, Christian S.J. Peron wrote:

    > On Thu, Jan 27, 2005 at 10:04:21AM +0800, David Xu wrote:
    [On why the kernel changes ERESTART to EINTR for kevent() and a few
    other interfaces like poll()]
    > > 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.

    Perhaps a more fundamental reason is that not restarting is part of
    how these interfaces work. POSIX specifies it for poll() and select().

    Changing signal handler[s] to restart automatically would be very bad
    even if it worked for kevent(). It would break applications that want
    other syscalls to not be restarted, and increase problems with
    applications longjmping out of signal handlers.

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

    I think it is mostly historical -- applications or perhaps the library
    would not be prepared for __res_send() failing for any signal.

    > The problem is this breaks many programs which use loops and conditions
    > for program termination. Some examples are ping(8) and tcpdump(1).
    >
    > I.E. you go to ping some host or process some packets without -n and
    > try to ctrl+c to interrupt the process, the program will not terminate
    > because the resolver keeps restarting the kevent system call.

    This problem for ping was noticed soon after ping.c:status() was changed
    in rev.1.12 to just set a flag. It can't be easy to fix since it has
    lived for 8 years since then.

    Just setting flags in signal handlers is very hard to implement correctly.
    SA_RESTART must not be used for any signal handler, and EINTR must be
    handled for all syscalls and perhaps some library functions that would
    otherwise be restarted. ping attempts this but doesn't succeed because
    the resolver library doesn't cooperate. top's signal handling was
    broken by changing its signal handler[s] to just set a flag without
    even attempting this. So SIGINT doesn't kill top when top is blocked
    in read().

    > Does anyone think it would make sense to not un-conditionally restart
    > the system call and have EINTR (or something to this effect) propogate
    > back to the process through h_errno?

    That is what should happen. I don't know if it is practical.

    Bruce
    _______________________________________________
    freebsd-arch@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-arch
    To unsubscribe, send any mail to "freebsd-arch-unsubscribe@freebsd.org"


  • Next message: Paul Richards: "c99/c++ localised variable definition"

    Relevant Pages

    • Re: What does this error message mean and what do I do?
      ... >My computer keeps restarting. ... The event log gives me, ... This can be a potential security hazard to the ... >machine since some of the network interfaces may not get the protection as ...
      (microsoft.public.windowsxp.perform_maintain)
    • Re: System Calls and I/O Parameter Reinitialization
      ... reinitialized before restarting the call? ... I'm having trouble understanding what you're asking about. ... Another possibility is the arguments that are passed _by reference_ to ... If EINTR is returned, no application visible side ...
      (comp.unix.programmer)