$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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