I have a static library which contains singletons. I need to load a separate instance of those singletons in the same process for testing purposes.
So I have created a DLL which links the same static library, and then the main process loads that DLL.
As soon as the DLL tries to load, I get access violations when trying to access the static instance pointers in the singletons.
Some posts that I have read say that it's impossible and that I need a second process, while others say that each DLL gets it's own copies of all the static variables in the static library it links, which suggests that this should work..
Is what I am trying to do possible?
Most of the time a singleton is really meant to be only one - your request is unusual.
I know that linking a static library into a DLL can result in multiple instances of static variables, because I've seen it myself. Each DLL or EXE gets its own copy of the static library via the linker, and thus its own copy of the static variables.
The access violations may come from problems with initialization order. The best way to control that is to make sure the static variables are within a function that initializes them just-in-time, rather than global variables.
Related
I'm linking against a 3rd party library that uses static variables. These end up getting initialised before main and grab resources prematurely, causing some havoc in my application. Is there any idiom / technique/ wrapping method, to regain control and define the point in execution where the library is allowed initialise all of its static variables without hacking at the library itself?
Specifically, I have a thirdpartylib::system object, that once defined in main, grabs all sorts of resources before main is entered. The compiler sees that the code can be hit, and then goes about initialising all of its static vars out of control of the library consumer. Ideally, I'd like some kind of guard to stop this until I say so, like . .
// my code that may exit before I want the lib stuff to be invoked
{
LET_SYSTEM_RUN_RIOT();
thirdpartylib::system sys;
// do some stuff with it
KILL_IT_ALL_WITH_FIRE();
}
The only thing you can do is build it dynamically and load it at runtime via dload/LoadLibrary. Then you are in complete control of when the library initializes itself. By linking statically, you are conceptually making the library part of your application, which means it will initialize as part of you application, i.e. before your main function.
I have a library (L) that is dynamically loaded by a program (P) using dlopen. L implements a plugin interface and so calls back on it's parent to obtain some functionality.
Inside P is a singleton object that dynamically creates a thread pool object A.
I need access to A from L.
However, because the singleton works by using a static variable, when L is loaded it ends up creatng it's own instance which is some cases would be fine but I want the instance that was created in P. Is there a way around this?
You should not have a static A in L. Let P pass the address of A to L, i.e., L.init(&A).
File scope names declared static have internal linkage. Internal linkage means that they are invisible to other translation units, even in a "classic" linking model without any dynamic libraries. Given that statics are not visible even to other translation units in the same executable, it is not reasonable to expect them to be visible from attached dynamic libraries.
You have to think of a way to achieve the necessary linkage using external, dynamic symbols. Perhaps the singleton simply cannot have an internal name, but must have an external name.
L is creating its own instance of the object not just because the object is static, but because you have linked into L the thread pool module which defines that singleton and the thread pool functions. This can happen even with objects that have external names, depending on how the library is linked.
You must pick a single object in which the thread pool service will reside, and then make sure it only resides there. Doesn't your project have a utility library where you can stick in this sort of thing?
You can adhere to the model that it is the program executable P which provides the thread pool API. This is really the same thing. The program P is another dynamic object and effectively serves as the library for the thread pool module, which it provides to itself and to other shared objects.
Regardless of where that thread pool module lives, make sure that you are not statically linking copies of that module into other objects: it lives just in one place.
If the thread pool singleton's external name is part of that API (everyone knows its documented name and uses it directly, passing that global pool to the API functions) then that name should be made external, and declared in the header file.
If the singleton is to be private, then you have to think of some way of hiding it, like making it implicit in the function calls (there is only one thread pool, and that is that) or else abstracting the access to it somewhat (provide an ensure_thread_pool) function which creates a thread pool if one does not exist, or else returns the previously created one, in a thread safe way.
Think: why do not, for instance, stdin and stdout have this problem? Why doesn't every library instantiate its own stdout stream and call its own fprintf function on that stream? Why, obviously, because these things live in one place: the C library. Copies of them do not live in other places; other places just use them by reference via the dynamic symbols.
I'm currently using QT (4) to parallelize a non-threadsafe library that's written in C by non-programmers, and thus has a lot of global variables. The threads don't need to interact or share data, they each just call a bunch of methods of the library and then at the end the library gives an output that is used further.
The problem is, though, that global variables are per default shared between threads, causing the library to crash in different places. There are two ways to fix this:
Refactor the entire library to not use global variables (ouch), or find a way to make global variables non-shared, or find a third magic way.
Is the latter an option with QT or standard (C++01) C++?
Using thread local storage is a way to make global variables non-shared. Starting point for that, with links to details for different implementations:
http://en.wikipedia.org/wiki/Thread-local_storage
You can't "unshare" global variables. The only available option for parallelization (bar refactoring) is to have multiple processes instead of multiple threads. Preferably pooled.
Create a singleton that is responsible for synchronizing the access to the global variables. The global variables become members of the new singleton class and can be accessed by methods that have the same names as your current global variables so you don't need to change code all over the place.
I have a singleton class, and I will compile it as a library static(lib) or dynamic(dll).
Is it guaranteed that calls to same file in a machine always refer to same and unique instance in both cases?
Edit:
What if a process loads two different library and different functions from these libraries want to use instance of singleton class. Now, they are accessing same instance, am I right?
Thanks,
No, different processes will not share a singleton from a common library. Different processes use different memory spaces, so each will instantiate its own singleton.
You'll need to use some sort of shared memory or interprocess-communication to share data between processes.
If a single process loads libraries A and B, and both those libraries use a singleton from library C, then they will be using the same instance.
You don't call files. You load code into your process from the file, the code contains initialisation instructions that construct your singleton. The singleton is thus unique within your process, regardless of what other code within the process uses it. The singleton is not unique from one process to another, even if they use the same shared library.
I am pretty sure these classes are not thread safe.
But, is it safe to use different objects from these classes in different threads?
Do they have any global dependencies with each other like static data or anything to watch out for?
As long as the calls you are making are to static functions that do not access shared memory (shared between threads).
Basically the only time you will hit a problem is if the function you call accesses shared data. If your function simply does some work on data you provide it is thread safe.