Email List: Xaustin-group-lX
[All Lists]

Re: [Fwd: Re: whether ext() and atexit() are safe w.r.t each other

To: David Butenhof <david.butenhof@xxxxxx>
Subject: Re: [Fwd: Re: whether ext() and atexit() are safe w.r.t each other
From: Nick Stoughton <nick@xxxxxxxxxx>
Date: Tue, 03 Jun 2008 14:34:49 +0200
Cc: Andrew Josey <ajosey@xxxxxxxxxxxxx>, austin-group-l <austin-group-l@xxxxxxxxxxxxx>
Organization: USENIX
References: <1212759114.12557.52.camel@localhost.localdomain> <1212493665.3701.0.camel@amstaff2.msbit.com> <484D1F78.8060402@hp.com>
On Mon, 2008-06-09 at 08:18 -0400, David Butenhof wrote:
> Nick Stoughton wrote:
> > Interestingly, C++ have also been looking at this same issue, and are
> > intending to add the following requirement:
> >
> > "The program shall ensure that all threads, except the main thread, have
> > terminated before calling exit or returning from main."
> >   
> Interesting.
> 
> POSIX deliberately decided NOT to try to require this because of the 
> practical difficulties. For example, what if a thread is hung? You can't 
> call exit()? What HAPPENS if you call exit() while other threads are 
> running? Does it hang? Does exit() return a failure status and do 
> nothing? How do you manage dependencies between multiple modular 
> facilities that might use threads? Who's responsible for shutting them 
> down in the right order?
> 
> Or are we merely talking about a weasel-word disclaimer that "we're not 
> going to do anything to solve shutdown problems, so you either do it 
> yourself -- we won't tell you how nor give you any help -- or don't 
> complain to us when it doesn't work."

You got it! Actually, the wording is changing as we speak (making a few
more promises about what might happen), but by and large the advice is
"its your problem, application writer".

> > On Fri, 2008-06-06 at 14:31 +0100, Andrew Josey wrote:
> >   
> >> [ This was blocked due to the attachment -- Andrew ]
> >>
> >>
> >> Date: Fri, 06 Jun 2008 08:27:06 -0400
> >> From: David Butenhof <david.butenhof@hp.com>
> >> Organization: IS/MSL/iCAP
> >> User-Agent: Thunderbird 2.0.0.14 (Windows/20080421)
> >> MIME-Version: 1.0
> >> To: Anoop <acv@linux.vnet.ibm.com>
> >> CC: "austin-group-l@opengroup.org" <austin-group-l@opengroup.org>
> >> Subject: Re: whether ext() and atexit() are safe w.r.t each other
> >> References: <48491601.7030306@linux.vnet.ibm.com>
> >> In-Reply-To: <48491601.7030306@linux.vnet.ibm.com>
> >>
> >>
> >> Anoop wrote:
> >>     
> >>> A race is observed between atexit() and exit() in Linux.
> >>>
> >>> Does these functions need to be safe with respect to each other?
> >>>
> >>> Being more specific, if a thread is registering a handler using atexit() 
>while
> >>> exit() is processing the already registered handlers in the main thread,
> >>> what is the expected behavior as per the standard?
> >>>
> >>>       
> >>     2.9.1 Thread-Safety
> >>
> >>     All functions defined by this volume of POSIX.1-200x shall be
> >>     thread-safe, except that the
> >>     following functions need not be thread-safe.
> >>
> >> Neither atexit() nor exit() are on the list, therefore they must be
> >> thread safe. Being thread safe means not subject to "unexpected
> >> behavior" when called concurrently. This implicitly (but strongly and
> >> unambiguously) requires synchronization between dependent functions.
> >> (E.g., malloc and free, or exit and atexit.)
> >>
> >> (I suppose one could make an argument that the standard should specify
> >> and describe all such dependencies among the defined interfaces. That
> >> might make it easier for "naive implementors", but it's hard to imagine
> >> that any reasonable effort would identify all possible interactions; and
> >> ultimately an implementor is still responsible for making the
> >> implementation usable. I'll also agree that doesn't sound like a very
> >> good excuse -- but someone would have to volunteer to get such an effort
> >> started. While you're at it, you can work on a complete, consistent, and
> >> comprehensible memory model. ;-) )
> >>
> >> In any case, it clearly would not be acceptable for the application to
> >> crash because exit() found the list of atexit() handlers in an
> >> inconsistent state, for example. Nor for atexit() to crash because
> >> exit() might modify the list.
> >>
> >> There is, however, always a "race" between callers of dependent
> >> functions. That is, it's not possible to define exit() so that it's
> >> guaranteed to see all atexit() handlers that the application might ever
> >> register (concurrently or in the future). But either exit() shall see
> >> the new atexit handler and invoke it properly OR exit() shall not see
> >> the new atexit handler and will proceed as if this call to atexit() had
> >> not happened. Logically, exit() occurs either before or after atexit()
> >> insertion; never "during".
> >>
> >> The exit() function in particular has a lot of dependencies since it
> >> cleans up and finalizes a lot of implicit user-mode process state "on
> >> the way out". For example exit() can't crash because some thread is
> >> opening a stdio stream, even though exit() must flush all streams.
> >> Again, the new stream is either flushed because it's known to exit() as
> >> open, or not flushed because it's not; but exit() must complete
> >> successfully.
> >>
> >>     
> >
> >
> >
> >   

<Prev in Thread] Current Thread [Next in Thread>