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

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

To: Anoop <acv@xxxxxxxxxxxxxxxxxx>
Subject: Re: [Fwd: Re: whether ext() and atexit() are safe w.r.t each other
From: David Butenhof <david.butenhof@xxxxxx>
Date: Tue, 10 Jun 2008 06:07:08 -0400
Cc: Geoff Clare <gwc@xxxxxxxxxxxxx>, "austin-group-l@xxxxxxxxxxxxx" <austin-group-l@xxxxxxxxxxxxx>
Organization: IS/MSL/iCAP
References: <1212759114.12557.52.camel@localhost.localdomain> <20080606154514.GB39160@finch-staff-1.thus.net> <48496905.2050606@hp.com> <20080609075139.GC74480@finch-staff-1.thus.net> <20080609085814.GA23187@squonk.masqnet> <484CFFA2.6000701@hp.com> <484E2D05.9020008@linux.vnet.ibm.com>
Anoop wrote:
David Butenhof wrote:

The list could
be managed, for example, as a simple lock-free list. An atexit handler
registered asynchronously from another thread during exit() processing
MAY or MAY NOT be called by the thread executing exit() depending on the
implementation strategies.
But wont this implementation (without synchronization) cause inconsistencies in the list,
which might result in, handlers already registered (even before exit was called),
not to be invoked, which is a violation of the standard?
I guess the implementation needs to ensure (by locking or any other better means) that,
All successfully registered handlers are invoked before exiting, or in other words,
Fail all the registrations that cannot be handled. Is that correct?
Define "already" in a concurrent environment. Really, the only meaningful definition is based on visibility in an ordered list of shared memory transactions between the threads.

Lock-free operations are all about visibility rather than explicit synchronization.

All VISIBLE handlers are invoked before exit. exit() loops extracting the head of the list until empty; atexit() inserts an entry with a machine-appropriate visibility mechanism such that a subsequent extract operation will be able to see it.

There's still the chance that exit() will loop a final time seeing an empty list head, and at the next machine cycle some thread's atexit() call will make a new head visible -- that will be missed. The only possible, even theoretical, way to avoid this is to ensure that all threads aside from the one calling exit() are shut down before that final extract call. No matter what sort of synchronization or visibility mechanism is used.

(Actually, this may not be quite true; given an atomic signal that atexit processing is "done", perhaps by deliberately corrupting the list head on extraction of the final entry, like setting the list head to -1 instead of 0, the atexit() call might abort the insertion and instead invoke the handler directly. Of course the exit() would have proceeded in the other thread and the atexit handler might not complete. And if multiple threads were to do this, the atexit handlers they attempted to insert might run in parallel, which also might not be good. ;-) )

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