|
Boost : |
From: Jeremy Pack (rostovpack_at_[hidden])
Date: 2008-07-07 22:42:42
Robert,
> I'm developing a plugin system and I will be loading several DLLs.
> Basically, as far as I know, this means having one factory_map per DLL
> (on Windows).
This depends on how you want to use the factory_maps. Do you want to close
the shared libraries that you aren't using? If not, just use the same
factory_map for every shared library. Unless you have a LOT of separate
shared libraries, this is usually a good solution (if you have a lot, you
may not want the unused libraries taking up RAM).
If you do want to close unused shared libraries, it's a bit trickier. I had
some code that did this, but have let it languish because it didn't cover a
number of special cases. Here is more or less how it worked:
- Create a counted_factory_map instead of a factory_map. Internally, a
counted_factory_map contains a separate map and shared_library object for
each shared library.
- Whenever you ask it to add a constructor for a class T, it instead adds
a constructor for a class counted<T> (which is a derived class of T), which
increments and decrements a counter whenever it is created or destroyed.
- There is a function in the shared library that can be called to see how
many objects are currently live from the given shared library.
- You can call a function on the counted_factory_map to do garbage
collection - ie, close shared libraries with no live objects.
The reasons this code is not currently used in Extension:
- It requires a duplicate of almost every class in Extension - a counted
version and a non-counted version.
- The counted versions have very high coupling - whereas the uncounted
versions of shared_library and factory_map are very loosely coupled. It also
makes it impossible to use parameter_map in its current form.
- It requires, in the common case, the use of mutexes to protect the
counters. This requires linking in the Thread library.
- It only works if all you are doing in a shared library is constructing
objects using counted_factory. If you take a reference to anything else in a
shared library, you risk having a dangling reference when all of the
counted<T> objects are destroyed. Note that this can be alleviated by using
a separate shared_library instance if you want to do anything besides
populate a counted_factory_map, since a shared library is only closed when
all shared_library instances referencing it are destroyed (it is also
possible to force a shared library to remain open until program termination
- by passing false as the second parameter to the shared_library
constructor).
There were a few other special cases that broke it as well - but I can't
remember what they were right now.
I can update that code if people are interested. I certainly wouldn't mind
suggestions about how to avoid some of the problems that I listed, or a
different way of handling this sort of "garbage collection" of unused shared
libraries.
Thanks!
Jeremy Pack
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk