From d5e63cea21932dbc03e513e205f0f3c66cc8c350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Fri, 30 May 2014 17:32:09 +0200 Subject: [PATCH] retain the uv loop until all things deconstructed fixes #261 --- common/curl_request.cpp | 4 ++-- common/foundation_request.mm | 6 +++--- include/llmr/map/map.hpp | 4 ++-- include/llmr/platform/platform.hpp | 6 +++++- include/llmr/platform/request.hpp | 8 ++++++-- include/llmr/util/uv.hpp | 18 +++++++++++++++--- src/map/map.cpp | 18 ++++++++---------- src/platform/request.cpp | 6 +++--- 8 files changed, 44 insertions(+), 26 deletions(-) diff --git a/common/curl_request.cpp b/common/curl_request.cpp index 0702e1e72..7eae7fd95 100644 --- a/common/curl_request.cpp +++ b/common/curl_request.cpp @@ -89,7 +89,7 @@ class CURLRequest : public llmr::platform::Request { public: CURLRequest(const std::string &url, std::function callback, - uv_loop_t *loop) + std::shared_ptr loop) : Request(url, callback, loop) {} CURL *curl = nullptr; @@ -358,7 +358,7 @@ void thread_init_cb() { std::shared_ptr platform::request_http(const std::string &url, std::function callback, - uv_loop_t *loop) { + std::shared_ptr loop) { using namespace request; init_thread_once(thread_init_cb); std::shared_ptr req = std::make_shared(url, callback, loop); diff --git a/common/foundation_request.mm b/common/foundation_request.mm index ca32706ba..4d6ca9c5f 100644 --- a/common/foundation_request.mm +++ b/common/foundation_request.mm @@ -41,7 +41,7 @@ class FoundationRequest : public llmr::platform::Request { public: FoundationRequest(const std::string &url, std::function callback, - uv_loop_t *loop) + std::shared_ptr loop) : Request(url, callback, loop) { #if TARGET_OS_IPHONE active_tasks++; @@ -68,7 +68,7 @@ public: std::shared_ptr llmr::platform::request_http(const std::string &url, std::function callback, - uv_loop_t *loop) { + std::shared_ptr loop) { uv_once(&request_initialize, request_initialize_cb); std::shared_ptr req = @@ -99,7 +99,7 @@ llmr::platform::request_http(const std::string &url, } (*req_ptr)->complete(); - + delete req_ptr; }]; diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp index 5f46c0e7e..8874172c3 100644 --- a/include/llmr/map/map.hpp +++ b/include/llmr/map/map.hpp @@ -102,7 +102,7 @@ public: inline std::shared_ptr getGlyphStore() { return glyphStore; } inline std::shared_ptr getSpriteAtlas() { return spriteAtlas; } inline std::shared_ptr getTexturepool() { return texturepool; } - inline uv_loop_t *getLoop() { return loop; } + inline std::shared_ptr getLoop() { return loop; } inline time getAnimationTime() const { return animationTime; } inline const Sources &getSources() { return sources; } @@ -168,7 +168,7 @@ private: private: bool async = false; - uv_loop_t *loop = nullptr; + std::shared_ptr loop; uv_thread_t thread; uv_async_t *async_terminate = nullptr; uv_async_t *async_render = nullptr; diff --git a/include/llmr/platform/platform.hpp b/include/llmr/platform/platform.hpp index d516378c2..31118a22f 100644 --- a/include/llmr/platform/platform.hpp +++ b/include/llmr/platform/platform.hpp @@ -7,6 +7,10 @@ typedef struct uv_loop_s uv_loop_t; +namespace uv { +class loop; +} + namespace llmr { extern const char *kSpriteURL; @@ -29,7 +33,7 @@ struct Response { // Returns a cancellable request. std::shared_ptr request_http(const std::string &url, std::function callback, - uv_loop_t *loop = nullptr); + std::shared_ptr loop = nullptr); // Cancels an HTTP request. void cancel_request_http(const std::shared_ptr &req); diff --git a/include/llmr/platform/request.hpp b/include/llmr/platform/request.hpp index 974f854bf..5ba00830b 100644 --- a/include/llmr/platform/request.hpp +++ b/include/llmr/platform/request.hpp @@ -12,6 +12,10 @@ typedef struct uv_loop_s uv_loop_t; typedef struct uv_async_s uv_async_t; +namespace uv { +class loop; +} + namespace llmr { namespace platform { @@ -21,7 +25,7 @@ class Request : public std::enable_shared_from_this, private util::nonc public: Request(const std::string &url, std::function callback, - uv_loop_t *loop); + std::shared_ptr loop); ~Request(); void complete(); @@ -36,7 +40,7 @@ public: public: uv_async_t *async = nullptr; - uv_loop_t *loop = nullptr; + std::shared_ptr loop; }; } } diff --git a/include/llmr/util/uv.hpp b/include/llmr/util/uv.hpp index aae5a1b05..0600b8550 100644 --- a/include/llmr/util/uv.hpp +++ b/include/llmr/util/uv.hpp @@ -12,6 +12,16 @@ namespace uv { +class loop { +public: + inline loop() : l(uv_loop_new()) {} + inline ~loop() { uv_loop_delete(l); } + + inline uv_loop_t *operator*() { return l; } + +private: + uv_loop_t *l; +}; class mutex { public: @@ -90,12 +100,13 @@ public: typedef void (*after_work_callback)(T &object); template - work(uv_loop_t *loop, work_callback work_cb, after_work_callback after_work_cb, Args&&... args) - : data(std::forward(args)...), + work(const std::shared_ptr &loop, work_callback work_cb, after_work_callback after_work_cb, Args&&... args) + : loop(loop), + data(std::forward(args)...), work_cb(work_cb), after_work_cb(after_work_cb) { req.data = this; - uv_queue_work(loop, &req, do_work, after_work); + uv_queue_work(**loop, &req, do_work, after_work); } private: @@ -111,6 +122,7 @@ private: } private: + std::shared_ptr loop; uv_work_t req; T data; work_callback work_cb; diff --git a/src/map/map.cpp b/src/map/map.cpp index 295704511..c4c736d1a 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -25,7 +26,7 @@ Map::Map(View& view) spriteAtlas(std::make_shared(512, 512)), texturepool(std::make_shared()), painter(*this), - loop(uv_loop_new()) { + loop(std::make_shared()) { view.initialize(this); @@ -39,9 +40,6 @@ Map::~Map() { if (async) { stop(); } - - uv_loop_delete(loop); - loop = nullptr; } void Map::start() { @@ -51,15 +49,15 @@ void Map::start() { // Setup async notifications async_terminate = new uv_async_t(); - uv_async_init(loop, async_terminate, terminate); - async_terminate->data = loop; + uv_async_init(**loop, async_terminate, terminate); + async_terminate->data = **loop; async_render = new uv_async_t(); - uv_async_init(loop, async_render, render); + uv_async_init(**loop, async_render, render); async_render->data = this; async_cleanup = new uv_async_t(); - uv_async_init(loop, async_cleanup, cleanup); + uv_async_init(**loop, async_cleanup, cleanup); async_cleanup->data = this; uv_thread_create(&thread, [](void *arg) { @@ -80,7 +78,7 @@ void Map::stop() { async_cleanup = nullptr; // Run the event loop once to make sure our async delete handlers are called. - uv_run(loop, UV_RUN_ONCE); + uv_run(**loop, UV_RUN_ONCE); async = false; } @@ -92,7 +90,7 @@ void Map::delete_async(uv_handle_t *handle) { void Map::run() { setup(); prepare(); - uv_run(loop, UV_RUN_DEFAULT); + uv_run(**loop, UV_RUN_DEFAULT); // If the map rendering wasn't started asynchronously, we perform one render // *after* all events have been processed. diff --git a/src/platform/request.cpp b/src/platform/request.cpp index f689517ab..5ec08197b 100644 --- a/src/platform/request.cpp +++ b/src/platform/request.cpp @@ -1,13 +1,13 @@ #include #include #include -#include +#include using namespace llmr::platform; Request::Request(const std::string &url, std::function callback, - uv_loop_t *loop) + std::shared_ptr loop) : url(url), res(std::make_unique(callback)), cancelled(false), @@ -20,7 +20,7 @@ Request::Request(const std::string &url, // create an actual work request that is attached to the default loop. async = new uv_async_t(); async->data = new std::unique_ptr(); - uv_async_init(loop, async, complete); + uv_async_init(**loop, async, complete); } }