Fix multithreaded loop clean-up, fixes #888 (#902)

* Fix multithreaded loop clean-up, fixes #888

* Style fixes
This commit is contained in:
BotoX
2019-06-18 22:21:30 +02:00
committed by Alex Hultman
parent dfe0df6586
commit 8cd13833d9
+17 -8
View File
@@ -80,26 +80,35 @@ private:
return ((Loop *) us_create_loop(hint, wakeupCb, preCb, postCb, sizeof(LoopData)))->init(); return ((Loop *) us_create_loop(hint, wakeupCb, preCb, postCb, sizeof(LoopData)))->init();
} }
/* What to do with loops created with existingNativeLoop? */
struct LoopCleaner {
~LoopCleaner() {
if(loop && cleanMe) {
loop->free();
}
}
Loop *loop = nullptr;
bool cleanMe = false;
};
public: public:
/* Lazily initializes a per-thread loop and returns it. /* Lazily initializes a per-thread loop and returns it.
* Will automatically free all initialized loops at exit. */ * Will automatically free all initialized loops at exit. */
static Loop *get(void *existingNativeLoop = nullptr) { static Loop *get(void *existingNativeLoop = nullptr) {
static thread_local Loop *lazyLoop; static thread_local LoopCleaner lazyLoop;
if (!lazyLoop) { if (!lazyLoop.loop) {
/* If we are given a native loop pointer we pass that to uSockets and let it deal with it */ /* If we are given a native loop pointer we pass that to uSockets and let it deal with it */
if (existingNativeLoop) { if (existingNativeLoop) {
/* Todo: here we want to pass the pointer, not a boolean */ /* Todo: here we want to pass the pointer, not a boolean */
lazyLoop = create(existingNativeLoop); lazyLoop.loop = create(existingNativeLoop);
/* We cannot register automatic free here, must be manually done */ /* We cannot register automatic free here, must be manually done */
} else { } else {
lazyLoop = create(nullptr); lazyLoop.loop = create(nullptr);
std::atexit([]() { lazyLoop.cleanMe = true;
Loop::get()->free();
});
} }
} }
return lazyLoop; return lazyLoop.loop;
} }
/* Freeing the default loop should be done once */ /* Freeing the default loop should be done once */