| 228 | #endif |
| 229 | |
| 230 | void cleanup_coroutine_threads() FL_NOEXCEPT { |
| 231 | fl::detail::CoroutineRunner::instance().stop_all(); |
| 232 | |
| 233 | // Join coroutine threads (DLL mode only) |
| 234 | #ifdef TEST_DLL_MODE |
| 235 | { |
| 236 | auto& creg = CoroutineThreadRegistry::instance(); |
| 237 | fl::unique_lock<fl::mutex> lock(creg.mtx) FL_NOEXCEPT; |
| 238 | for (auto& t : creg.threads) { |
| 239 | if (t.joinable()) t.join(); |
| 240 | } |
| 241 | creg.threads.clear(); |
| 242 | } |
| 243 | #endif |
| 244 | |
| 245 | // Join background threads (always) |
| 246 | auto& bg = ICoroutineRuntime::instance(); |
| 247 | bg.requestShutdown(); |
| 248 | auto& reg = BackgroundThreadRegistry::instance(); |
| 249 | fl::unique_lock<fl::mutex> lock(reg.mtx) FL_NOEXCEPT; |
| 250 | for (auto& t : reg.threads) { |
| 251 | if (t.joinable()) t.join(); |
| 252 | } |
| 253 | reg.threads.clear(); |
| 254 | bg.resetShutdown(); |
| 255 | } |
| 256 | |
| 257 | void register_background_thread(fl::thread&& t) FL_NOEXCEPT { |
| 258 | auto& reg = BackgroundThreadRegistry::instance(); |