diff --git a/src/App.h b/src/App.h index c608e71..0352f58 100644 --- a/src/App.h +++ b/src/App.h @@ -79,7 +79,7 @@ public: } TemplatedApp(us_new_socket_context_options_t options = {}) { - httpContext = uWS::HttpContext::create(uWS::Loop::defaultLoop(), options); + httpContext = uWS::HttpContext::create(uWS::Loop::get(), options); } bool constructorFailed() { @@ -105,7 +105,7 @@ public: "µWebSockets cannot satisfy UserData alignment requirements. You need to recompile µSockets with LIBUS_EXT_ALIGNMENT adjusted accordingly."); /* Every route has its own websocket context with its own behavior and user data type */ - auto *webSocketContext = WebSocketContext::create(Loop::defaultLoop(), (us_new_socket_context_t *) httpContext); + auto *webSocketContext = WebSocketContext::create(Loop::get(), (us_new_socket_context_t *) httpContext); /* We need to clear this later on */ webSocketContexts.push_back(webSocketContext); diff --git a/src/Loop.h b/src/Loop.h index 810a8a9..7c965bd 100644 --- a/src/Loop.h +++ b/src/Loop.h @@ -23,9 +23,6 @@ #include "LoopData.h" #include -#include -#include - namespace uWS { struct Loop { private: @@ -84,33 +81,17 @@ private: } public: - /* Returns the default loop if called from one thread, or a dedicated per-thread loop if called from multiple threads */ - static Loop *defaultLoop() { - /* Lock this whole function */ - static std::mutex m; - std::lock_guard lock(m); - - /* Deliver and attach the default loop to the first thread who calls us */ - static thread_local bool ownsDefaultLoop; - static Loop *defaultLoop; - if (!defaultLoop) { - ownsDefaultLoop = true; - defaultLoop = create(true); + /* Lazily initializes a per-thread loop and returns it. Will automatically free all initialized loops at exit. */ + static Loop *get() { + static thread_local Loop *lazyLoop; + if (!lazyLoop) { + lazyLoop = create(false); std::atexit([]() { - Loop::defaultLoop()->free(); + Loop::get()->free(); }); - return defaultLoop; - } else if (ownsDefaultLoop) { - return defaultLoop; } - /* Other threads get their non-default loops lazily created */ - static thread_local Loop *threadLocalLoop; - if (!threadLocalLoop) { - threadLocalLoop = create(false); - return threadLocalLoop; - } - return threadLocalLoop; + return lazyLoop; } /* Freeing the default loop should be done once */ @@ -166,7 +147,7 @@ public: /* Can be called from any thread to run the thread local loop */ inline void run() { - Loop::defaultLoop()->run(); + Loop::get()->run(); } } diff --git a/src/TopicTree.h b/src/TopicTree.h index 3b9a271..fe1e710 100644 --- a/src/TopicTree.h +++ b/src/TopicTree.h @@ -82,7 +82,7 @@ public: return; /* Dynamically hook us up with the Loop post handler */ - Loop::defaultLoop()->addPostHandler([this](Loop *loop) { + Loop::get()->addPostHandler([this](Loop *loop) { if (!pubNodes.size()) { return;