Clive D.W. Feather <clive@demon.net> wrote, on 09 Jun 2008:
>
> Dave Butenhof said:
> > Except that here we're talking about synchronization between two
> > concurrently executing threads. It IS possible for atexit() to be
> > invoked after exit() starts, but not from another atexit handler -- it's
> > called from another thread.
>
> Ah. Threads.
>
> Okay, just ignore me.
Actually, I thought you had a valid point, which Dave doesn't
seem to have taken into account.
Dave said:
| Except that here we're talking about synchronization between two
| concurrently executing threads. It IS possible for atexit() to be
| invoked after exit() starts, but not from another atexit handler -- it's
| called from another thread.
Perhaps he meant to say "but not only from another atexit handler", but
without the "only" this suggests that he thinks atexit handlers are not
allowed to call atexit(), when in fact they are.
So exit() cannot lock the handler list and keep it locked until it calls
_exit(); it must unlock the list during the call to each handler[*].
Consequently it is possible for other threads to register new handlers
while exit() is processing the handler list (as long as the list is not
empty). The rule from the C Standard about handler ordering applies to
new handlers regardless of whether they are added by one of the handlers
or by another thread.
* Actually, I suppose it could use a recursive mutex, which would allow
atexit() to lock it again if called from the same thread that called
exit() (i.e. from a handler), but not if called from a different thread.
It shouldn't matter to applications either way, since the process is
about to exit anyway.
--
Geoff Clare <g.clare@opengroup.org>
The Open Group, Thames Tower, Station Road, Reading, RG1 1LX, England
|