From 70aea89e131125b3d92fcc99c5b3ecd1e148d0c8 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Tue, 7 Jul 2015 20:23:43 +0300 Subject: [PATCH] Add an interface for invoking cancellable tasks on the RunLoop This is interface is going to be used the WorkQueue in the following patches. --- src/mbgl/util/run_loop.cpp | 2 +- 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 7f277c988..5c9595946 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&& fn) { - std::lock_guard lock(mutex); + std::lock_guard lock(mutex); fn(); } diff --git a/src/mbgl/util/run_loop.hpp b/src/mbgl/util/run_loop.hpp index 2175ea977..7f56c18dc 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 + std::unique_ptr + invokeCancellable(Fn&& fn, Args&&... args) { + auto flag = std::make_shared(); + *flag = false; + + auto tuple = std::make_tuple(std::move(args)...); + auto task = std::make_shared>( + std::move(fn), + std::move(tuple), + flag); + + withMutex([&] { queue.push(task); }); + async.send(); + + return std::make_unique(task); + } + // Invoke fn(args...) on this RunLoop, then invoke callback(results...) on the current RunLoop. template std::unique_ptr @@ -85,7 +108,7 @@ private: void operator()() override { // Lock the mutex while processing so that cancel() will block. - std::lock_guard lock(mutex); + std::lock_guard lock(mutex); if (!canceled || !*canceled) { invoke(std::make_index_sequence::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 lock(mutex); + std::lock_guard lock(mutex); *canceled = true; } @@ -110,7 +133,7 @@ private: func(std::get(std::forward

(params))...); } - std::mutex mutex; + std::recursive_mutex mutex; std::shared_ptr 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 current;