diff options
author | Thiago Marcos P. Santos <thiago@mapbox.com> | 2015-07-07 20:23:43 +0300 |
---|---|---|
committer | Thiago Marcos P. Santos <thiago@mapbox.com> | 2015-07-15 16:16:51 +0300 |
commit | 70aea89e131125b3d92fcc99c5b3ecd1e148d0c8 (patch) | |
tree | 2869b73c4f2deaa31acd93c7b7f3990aa71f3f54 /src | |
parent | 3c1d46113effef75c44a28a1847cbac4d1003948 (diff) | |
download | qtlocation-mapboxgl-70aea89e131125b3d92fcc99c5b3ecd1e148d0c8.tar.gz |
Add an interface for invoking cancellable tasks on the RunLoop
This is interface is going to be used the WorkQueue in the following
patches.
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/util/run_loop.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/util/run_loop.hpp | 31 |
2 files changed, 28 insertions, 5 deletions
diff --git a/src/mbgl/util/run_loop.cpp b/src/mbgl/util/run_loop.cpp index 7f277c9885..5c95959460 100644 --- a/src/mbgl/util/run_loop.cpp +++ b/src/mbgl/util/run_loop.cpp @@ -15,7 +15,7 @@ RunLoop::~RunLoop() { } void RunLoop::withMutex(std::function<void()>&& fn) { - std::lock_guard<std::mutex> lock(mutex); + std::lock_guard<std::recursive_mutex> lock(mutex); fn(); } diff --git a/src/mbgl/util/run_loop.hpp b/src/mbgl/util/run_loop.hpp index 2175ea977a..7f56c18dcd 100644 --- a/src/mbgl/util/run_loop.hpp +++ b/src/mbgl/util/run_loop.hpp @@ -19,6 +19,10 @@ public: RunLoop(uv_loop_t*); ~RunLoop(); + static RunLoop* Get() { + return current.get(); + } + static uv_loop_t* getLoop() { return current.get()->get(); } @@ -37,6 +41,25 @@ public: async.send(); } + // Post the cancellable work fn(args...) to this RunLoop. + template <class Fn, class... Args> + std::unique_ptr<WorkRequest> + invokeCancellable(Fn&& fn, Args&&... args) { + auto flag = std::make_shared<bool>(); + *flag = false; + + auto tuple = std::make_tuple(std::move(args)...); + auto task = std::make_shared<Invoker<Fn, decltype(tuple)>>( + std::move(fn), + std::move(tuple), + flag); + + withMutex([&] { queue.push(task); }); + async.send(); + + return std::make_unique<WorkRequest>(task); + } + // Invoke fn(args...) on this RunLoop, then invoke callback(results...) on the current RunLoop. template <class Fn, class Cb, class... Args> std::unique_ptr<WorkRequest> @@ -85,7 +108,7 @@ private: void operator()() override { // Lock the mutex while processing so that cancel() will block. - std::lock_guard<std::mutex> lock(mutex); + std::lock_guard<std::recursive_mutex> lock(mutex); if (!canceled || !*canceled) { invoke(std::make_index_sequence<std::tuple_size<P>::value>{}); } @@ -100,7 +123,7 @@ private: // If the task has completed and the after callback has executed, this will // do nothing. void cancel() override { - std::lock_guard<std::mutex> lock(mutex); + std::lock_guard<std::recursive_mutex> lock(mutex); *canceled = true; } @@ -110,7 +133,7 @@ private: func(std::get<I>(std::forward<P>(params))...); } - std::mutex mutex; + std::recursive_mutex mutex; std::shared_ptr<bool> canceled; F func; @@ -123,7 +146,7 @@ private: void process(); Queue queue; - std::mutex mutex; + std::recursive_mutex mutex; uv::async async; static uv::tls<RunLoop> current; |