@@ -7,7 +7,39 @@ std::string error_number_as_string;
7
7
8
8
HANDLE open_library (const char *path) {
9
9
#ifdef IS_UNIX
10
- return dlopen (path, RTLD_LAZY); // TODO: Is RTLD_LAZY the best?
10
+ //
11
+ // Note: Experience has shown that multiple platforms/libraries
12
+ // have issues with handling dynamically loaded shared
13
+ // libraries and Thread Local Variables/Thread Local Storage
14
+ // and/or at exit terminators properly.
15
+ //
16
+ // This can result in multiple thread crashes when the
17
+ // program exits because the library is no longer loaded
18
+ // but pointers to the library clean-up functions still exist.
19
+ //
20
+ // The best workaround found so far is to...just not unload
21
+ // a library when it is closed. :/
22
+ //
23
+ // The workaround is implemented via the addition of an
24
+ // additional `dlopen()` call which is (by design) never
25
+ // matched with a `dlclose()` call. This results in all
26
+ // at exit/thread local storage cleanup happening when the
27
+ // main thread is exiting.
28
+ //
29
+ // The disadvantage of this workaround is that it means
30
+ // it's not possible to "reload" a shared library but
31
+ // we can cross that bridge when someone gets to it. :)
32
+ //
33
+ // Additional note: In theory `RTLD_NODELETE` should have
34
+ // also worked as a workaround but it led to crashes.
35
+ // (Also tried `RTLD_LOCAL` or `RTLD_FIRST` approaches.)
36
+ //
37
+ //
38
+ // TODO: Document TLV on Mac issue with Library X.
39
+ // TODO: Document at exit terminator issue on Linux with Library Y.
40
+ //
41
+ dlopen (path, RTLD_LAZY|RTLD_GLOBAL); // Workaround to bump ref-count so library never unloaded.
42
+ return dlopen (path, RTLD_LAZY|RTLD_GLOBAL|RTLD_NOLOAD); // TODO: Is RTLD_LAZY the best?
11
43
#else
12
44
return LoadLibrary (path);
13
45
#endif
@@ -25,6 +57,8 @@ const char *open_library_error() {
25
57
26
58
int close_library (HANDLE handle) {
27
59
#ifdef IS_UNIX
60
+ // Note: See workaround note in `open_library()` above as to why
61
+ // the following line will no longer unload library.
28
62
return dlclose (handle);
29
63
#else
30
64
return FreeLibrary ((HMODULE) handle);
0 commit comments