Ulrich Drepper wrote:
> Drazen Kacar <yyyy@xxxxxxxxxxxxx> writes:
>
> > I'd be happier with "Object unloading occurs by a successful invocation
> > of dlclose()." If dlclose() can't or won't unload object (for any reason),
> > it doesn't make sense to run atexit handlers anyway.
>
> This doesn't work. The registered functions obviously have to be
> called before you try to unload the object.
Obviously, but dlclose() implementation calls registered functions, right?
Therefore dlclose() can first check if it is OK to unload the object.
If there are no obstacles, it can then call registered functions and
perform unloading.
> So, it is the late if the
> unloading failed (you cannot simply run the constructors again).
I don't expect that an entity external to dlclose() implementation would
interpose here and make unloading fail. Currently I see two interesting
conditions which would prevent removing from process address space (on
implementation that actually does that):
1. Implementation has a way to mark objects as unloadable and dlclose()
will not remove them from the process space. In this case I think the
handlers shouldn't be called.
2. Multiple dlopen() calls for the same object. The current dlopen() spec
says:
Only a single copy of an object file is brought into the address
space, even if dlopen() is invoked multiple times in reference to
the file, and even if different pathnames are used to reference
the file.
Suppose there is an application which uses two shared objects (either
dependencies or through dlopen() calls) and that both objects dlopen()
yet another object which registers some handlers with atexit().
What happens when one of the shared objects calls dlclose() for
this third object? With the current wording, atexit handlers are
run and one could expect that they would make the object unusable.
But then the other shared object still has a valid handle and can still
call functions from the third object. Except that they might not work
as expected.
To work as expected, destructor functions in the third object would
have to check internal reference counter to see if they should
perform the tear down or do nothing. This is not desirable because
there is no portable way to specify initialization function for
objects used through dlopen(), so object's API would have to
mandate that the caller explicitly calls such function after dlopen().
And the whole thing is error prone, because things like this tend
to be overlooked.
Both of the above conditions are detected by the dlclose() implementation
and it can decide whether to call object's destructor functions or not.
I would like it to perform reference counting and permission checking,
so loadable objects wouldn't have to do it.
My wording is no good, because it doesn't cover the second case, since
dlclose() will return success to both invocations.
BTW, it would be nice if there was a portable way to specify
initialization function(s) for shared objects. I don't know if that's
in scope, though.
--
.-. .-. Sarcasm is just one more service we offer.
(_ \ / _)
| yyyy@xxxxxxxxxxxxx
|
|