diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2015-04-20 18:28:10 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2015-04-28 14:32:22 -0400 |
commit | 75ae956b0e598685117f7f72231677d8841cbea3 (patch) | |
tree | 0aadbd3927d2ff5f57a7da8710ef644acaa4ba5b /src/mbgl/util | |
parent | 32c818feea8af1a355c661978694382245854413 (diff) | |
download | qtlocation-mapboxgl-75ae956b0e598685117f7f72231677d8841cbea3.tar.gz |
WIP: Use Thread<MapContext>
Diffstat (limited to 'src/mbgl/util')
-rw-r--r-- | src/mbgl/util/run_loop.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/util/signal.cpp | 21 | ||||
-rw-r--r-- | src/mbgl/util/signal.hpp | 24 | ||||
-rw-r--r-- | src/mbgl/util/thread.hpp | 51 |
4 files changed, 49 insertions, 51 deletions
diff --git a/src/mbgl/util/run_loop.hpp b/src/mbgl/util/run_loop.hpp index d785854e79..a192fe1799 100644 --- a/src/mbgl/util/run_loop.hpp +++ b/src/mbgl/util/run_loop.hpp @@ -53,6 +53,8 @@ public: uv_loop_t* get() { return *loop; } + static uv::tls<RunLoop> current; + private: // A movable type-erasing invokable entity wrapper. This allows to store arbitrary invokable // things (like std::function<>, or the result of a movable-only std::bind()) in the queue. @@ -71,8 +73,6 @@ private: using Queue = std::queue<std::unique_ptr<Message>>; - static uv::tls<RunLoop> current; - void withMutex(std::function<void()>&&); void process(); diff --git a/src/mbgl/util/signal.cpp b/src/mbgl/util/signal.cpp deleted file mode 100644 index 58795f7458..0000000000 --- a/src/mbgl/util/signal.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "signal.hpp" - -namespace mbgl { -namespace util { - -void Signal::wait() { - std::unique_lock<std::mutex> lock(mutex); - condition.wait(lock, [this] { return status; }); - status = false; -} - -void Signal::notify() { - { - std::lock_guard<std::mutex> lock(mutex); - status = true; - } - condition.notify_all(); -} - -} -} diff --git a/src/mbgl/util/signal.hpp b/src/mbgl/util/signal.hpp deleted file mode 100644 index fa406601b6..0000000000 --- a/src/mbgl/util/signal.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef MBGL_UTIL_SIGNAL -#define MBGL_UTIL_SIGNAL - -#include <mutex> -#include <condition_variable> - -namespace mbgl { -namespace util { - -class Signal { -public: - void wait(); - void notify(); - -private: - bool status = false; - std::condition_variable condition; - std::mutex mutex; -}; - -} -} - -#endif diff --git a/src/mbgl/util/thread.hpp b/src/mbgl/util/thread.hpp index 956e7718dc..036ac33c97 100644 --- a/src/mbgl/util/thread.hpp +++ b/src/mbgl/util/thread.hpp @@ -3,6 +3,7 @@ #include <future> #include <thread> +#include <atomic> #include <functional> #include <mbgl/util/run_loop.hpp> @@ -52,6 +53,29 @@ public: loop->invokeWithResult(std::bind(fn, object, args...), callback); } + // Invoke object->fn(args...) in the runloop thread, and wait for the result. + template <class R, typename Fn, class... Args> + R invokeSync(Fn fn, Args&&... args) { + std::promise<R> promise; + auto bound = std::bind(fn, object, args...); + loop->invoke([&] { promise.set_value(bound()); } ); + return promise.get_future().get(); + } + + // Invoke object->fn(args...) in the runloop thread, and wait for it to complete. + template <typename Fn, class... Args> + void invokeSync(Fn fn, Args&&... args) { + std::promise<void> promise; + auto bound = std::bind(fn, object, args...); + loop->invoke([&] { bound(); promise.set_value(); } ); + promise.get_future().get(); + } + + // Join the thread, but call the given function repeatedly in the current thread + // while waiting for the join to finish. This should be immediately followed by + // destroying the Thread. + void pumpingStop(std::function<void ()>); + uv_loop_t* get() { return loop->get(); } private: @@ -67,6 +91,7 @@ private: std::promise<void> joinable; std::thread thread; + std::atomic_bool joined; Object* object; RunLoop* loop; @@ -74,7 +99,8 @@ private: template <class Object> template <class... Args> -Thread<Object>::Thread(const std::string& name, Args&&... args) { +Thread<Object>::Thread(const std::string& name, Args&&... args) + : joined(false) { // Note: We're using std::tuple<> to store the arguments because GCC 4.9 has a bug // when expanding parameters packs captured in lambdas. std::tuple<Args...> params = std::forward_as_tuple(::std::forward<Args>(args)...); @@ -99,13 +125,21 @@ void Thread<Object>::run(P&& params, index_sequence<I...>) { RunLoop loop_; loop = &loop_; - Object object_(loop_.get(), std::get<I>(std::forward<P>(params))...); - object = &object_; + { + Object object_(loop_.get(), std::get<I>(std::forward<P>(params))...); + object = &object_; - running.set_value(); + running.set_value(); + loop_.run(); + + object = nullptr; + } + + // Run the loop again to ensure that async close callbacks have been called. loop_.run(); joinable.get_future().get(); + joined = true; } template <class Object> @@ -115,6 +149,15 @@ Thread<Object>::~Thread() { thread.join(); } +template <class Object> +void Thread<Object>::pumpingStop(std::function<void ()> cb) { + loop->stop(); + joinable.set_value(); + while (!joined) { + cb(); + } +} + } } |