Subject: Re: [boost] News about proposed Boost.Application library
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2014-07-30 06:20:20
On Wed, Jul 30, 2014 at 2:02 PM, Klaim - JoÃ«l Lamotte <mjklaim_at_[hidden]> wrote:
> On Wed, Jul 30, 2014 at 11:27 AM, Rob Stewart <robertstewart_at_[hidden]>
>> >I was suggesting weak_ptr (wrapped inside something that looks like a
>> >so that the user decides if or not he wants to check if the library is
>> >still loaded before using the function.
>> >But personally I wouldn't.
>> I'm still at a loss to understand what you'd actually want get_symbol() to
>> return to solve your use cases.
>> If the returned object holds a shared_ptr to the library, the library
>> can't be unloaded until all such objects have been destroyed or until they
>> are told to release their ref count. That is safer, however. Holding a
>> weak_ptr instead implies a runtime check on each invocation, but doesn't
>> prevent unloading the library. However, you've said you wouldn't use the
>> weak_ptr, so I'm missing something.
> Very sorry, I was not clear at all and I also mixed up details about the
> get_symbol() return type (it's not a callable but the call result, I mixed
> up this part).
> Let me try again:
> In most use cases I had, the lifetime of a plugin was necessarily separate
> from it's usage:
> I would have a way to say that the plugin must be unloaded and that would
> invalidate all code trying to use it. This is because
> unloading-the-plugin-event is then propagated through the users
> systems and they have to do the cleaning work (that is, destroy all
> accesses to the plugin).
> Once the plugin is unloaded, in my use cases, we want it to not be usable
> at all anymore, explicitly. And we want the whole application to fail early
> if access to the unloaded plugin is tried.
> Therefore, I agree that get_symbol() should return a smart pointer, but
> containing a weak_ptr instead
> of a shared_ptr, so that the symbol lifetimes don't force the plugin to
> still be loaded when
> we wanted it not to.
> Once the plugin is unloaded (the shared_ptr to it is destroyed), when the
> returned smart pointer
> is accessed, the weak_ptr would test locking and would, by default, throw
> an exception.
> Personally I would prefer the default behaviour in this case to be
> overwriteable, so that I can for example
> just log and call terminate(), then change this behaviour in the shiped
> In some specific cases I would want to test if the symbol is valid before
> using it (but in most
> cases I had, I don't want to because it should fail at this point - it's
> what I meant by "but personally I wouldn't").
> Centralization or not of the plugins lifetime is let to the user, this part
> was more noise than argument.
> The user can or not share the plugin lifetime between different systems,
> but I disagree that returns of the symbols should force the lifetime of the
> plugin to be longer than necessary.
> Am I more clear?
> Maybe two different get_symbol() functions could return either a "safe"
> (managing a shared_ptr to the plugin)
> or "unsafe" (managing a weak_ptr to the plugin and throwing an exception by
> default when it's not available
> and we try to use the data) smart pointer?
> Maybe that way our different use cases would be all solved.
I think you can achieve any behavior you described with the interface
Peter suggested, can't you?
// p1 locks lib from being unloaded
shared_ptr< foo > p1 = get_symbol< foo >(lib, "foo");
// p2 does not lock lib from being unloaded and is testable
weak_ptr< foo > p2 = get_symbol< foo >(lib, "foo");
// p3 does not lock lib from being unloaded and crashes if used
after lib is unloaded
foo* p3 = get_symbol< foo >(lib, "foo").get();
Personally, I'd prefer get_symbol to return something immediately
usable, i.e. shared_ptr. I'd also like to emphasize that it should
return a pointer and not a function since the symbol may be data. Just
my 2 cents.