|
11 | 11 |
|
12 | 12 | #include "util/HighsDynamicLibrary.h" |
13 | 13 |
|
| 14 | +#include "HConfig.h" |
| 15 | + |
14 | 16 | #if defined(_WIN32) || defined(_WIN64) |
15 | 17 | #ifndef WIN32_LEAN_AND_MEAN |
16 | 18 | #define WIN32_LEAN_AND_MEAN |
@@ -65,23 +67,35 @@ bool HighsDynamicLibrary::load(const std::string& filename, |
65 | 67 | void HighsDynamicLibrary::unload() { |
66 | 68 | if (!handle_) return; |
67 | 69 |
|
68 | | -#if defined(_WIN32) || defined(_WIN64) |
69 | | - FreeLibrary(static_cast<HMODULE>(handle_)); |
70 | | -#else |
71 | | - // check if blas_shutdown exists and potentially use it before dlclose-ing |
| 70 | +#ifdef HIPO_USES_OPENBLAS |
| 71 | + // Openblas creates a thread pool that may still exist after dlclose-ing the |
| 72 | + // library, leading to seg fault. blas_shutdown should prevent this, but its |
| 73 | + // symbol is not always exposed. If the symbol exists, use it and then call |
| 74 | + // dlclose. If the symbol does not exist, avoid calling dlclose. |
72 | 75 |
|
73 | 76 | using shutdown_t = void (*)(); |
74 | | - |
75 | 77 | shutdown_t shutdown_fn = nullptr; |
76 | | - |
77 | 78 | if (auto p = dlsym(handle_, "blas_shutdown")) |
78 | 79 | shutdown_fn = reinterpret_cast<shutdown_t>(p); |
79 | 80 | else if (auto p = dlsym(handle_, "openblas_shutdown")) |
80 | 81 | shutdown_fn = reinterpret_cast<shutdown_t>(p); |
81 | 82 |
|
82 | | - if (shutdown_fn) shutdown_fn(); |
| 83 | + if (shutdown_fn) { |
| 84 | + shutdown_fn(); |
| 85 | +#if defined(_WIN32) || defined(_WIN64) |
| 86 | + FreeLibrary(static_cast<HMODULE>(handle_)); |
| 87 | +#else |
| 88 | + dlclose(handle_); |
| 89 | +#endif |
| 90 | + } |
| 91 | + |
| 92 | +#else |
83 | 93 |
|
| 94 | +#if defined(_WIN32) || defined(_WIN64) |
| 95 | + FreeLibrary(static_cast<HMODULE>(handle_)); |
| 96 | +#else |
84 | 97 | dlclose(handle_); |
| 98 | +#endif |
85 | 99 | #endif |
86 | 100 |
|
87 | 101 | handle_ = nullptr; |
|
0 commit comments