diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/util/logging.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/util/thread.hpp | 173 | ||||
-rw-r--r-- | src/mbgl/util/thread_context.cpp | 13 | ||||
-rw-r--r-- | src/mbgl/util/thread_context.hpp | 22 |
4 files changed, 1 insertions, 209 deletions
diff --git a/src/mbgl/util/logging.cpp b/src/mbgl/util/logging.cpp index 939f1def64..0552eb36cb 100644 --- a/src/mbgl/util/logging.cpp +++ b/src/mbgl/util/logging.cpp @@ -1,6 +1,6 @@ #include <mbgl/util/logging.hpp> #include <mbgl/util/enum.hpp> -#include <mbgl/util/thread.hpp> +#include <mbgl/util/platform.hpp> #include <cstdio> #include <cstdarg> diff --git a/src/mbgl/util/thread.hpp b/src/mbgl/util/thread.hpp deleted file mode 100644 index 4afaab6b7a..0000000000 --- a/src/mbgl/util/thread.hpp +++ /dev/null @@ -1,173 +0,0 @@ -#pragma once - -#include <cassert> -#include <future> -#include <thread> -#include <atomic> -#include <utility> -#include <functional> - -#include <mbgl/util/run_loop.hpp> -#include <mbgl/util/thread_context.hpp> -#include <mbgl/util/platform.hpp> -#include <mbgl/util/util.hpp> - -namespace mbgl { -namespace util { - -// Manages a thread with Object. - -// Upon creation of this object, it launches a thread, creates an object of type Object in that -// thread, and then calls .start(); on that object. When the Thread<> object is destructed, the -// Object's .stop() function is called, and the destructor waits for thread termination. The -// Thread<> constructor blocks until the thread and the Object are fully created, so after the -// object creation, it's safe to obtain the Object stored in this thread. - -template <class Object> -class Thread { -public: - Thread(const Thread&) = delete; - Thread(Thread&&) = delete; - Thread& operator=(const Thread&) = delete; - Thread& operator=(Thread&&) = delete; - - template <class... Args> - Thread(const ThreadContext&, Args&&... args); - ~Thread(); - - // Invoke object->fn(args...) asynchronously. - template <typename Fn, class... Args> - void invoke(Fn fn, Args&&... args) { - loop->invoke(bind(fn), std::forward<Args>(args)...); - } - - // Invoke object->fn(args...) asynchronously. The final argument to fn must be a callback. - // The provided callback is wrapped such that it is invoked, in the current thread (which - // must have a RunLoop), once for each time the invocation of fn invokes the wrapper, each - // time forwarding the passed arguments, until such time as the AsyncRequest is cancelled. - template <typename Fn, class... Args> - std::unique_ptr<AsyncRequest> - invokeWithCallback(Fn fn, Args&&... args) { - return loop->invokeWithCallback(bind(fn), std::forward<Args>(args)...); - } - - // Invoke object->fn(args...) asynchronously, but wait for the result. - template <typename Fn, class... Args> - auto invokeSync(Fn fn, Args&&... args) { - assert(!paused); - - using R = std::result_of_t<Fn(Object, Args&&...)>; - std::packaged_task<R ()> task(std::bind(fn, object, args...)); - std::future<R> future = task.get_future(); - loop->invoke(std::move(task)); - return future.get(); - } - - void pause() { - MBGL_VERIFY_THREAD(tid); - - assert(!paused); - - paused = std::make_unique<std::promise<void>>(); - resumed = std::make_unique<std::promise<void>>(); - - auto pausing = paused->get_future(); - - loop->invoke([this] { - auto resuming = resumed->get_future(); - paused->set_value(); - resuming.get(); - }); - - pausing.get(); - } - - void resume() { - MBGL_VERIFY_THREAD(tid); - - assert(paused); - - resumed->set_value(); - - resumed.reset(); - paused.reset(); - } - -private: - MBGL_STORE_THREAD(tid); - - template <typename Fn> - auto bind(Fn fn) { - return [fn, this] (auto &&... args) { - return (object->*fn)(std::forward<decltype(args)>(args)...); - }; - } - - template <typename P, std::size_t... I> - void run(P&& params, std::index_sequence<I...>); - - std::promise<void> running; - std::promise<void> joinable; - - std::unique_ptr<std::promise<void>> paused; - std::unique_ptr<std::promise<void>> resumed; - - std::thread thread; - - Object* object = nullptr; - RunLoop* loop = nullptr; -}; - -template <class Object> -template <class... Args> -Thread<Object>::Thread(const ThreadContext& context, Args&&... args) { - // 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)...); - - thread = std::thread([&] { - platform::setCurrentThreadName(context.name); - - if (context.priority == ThreadPriority::Low) { - platform::makeThreadLowPriority(); - } - - run(std::move(params), std::index_sequence_for<Args...>{}); - }); - - running.get_future().get(); -} - -template <class Object> -template <typename P, std::size_t... I> -void Thread<Object>::run(P&& params, std::index_sequence<I...>) { - RunLoop loop_(RunLoop::Type::New); - loop = &loop_; - - Object object_(std::get<I>(std::forward<P>(params))...); - object = &object_; - - running.set_value(); - loop_.run(); - - loop = nullptr; - object = nullptr; - - joinable.get_future().get(); -} - -template <class Object> -Thread<Object>::~Thread() { - MBGL_VERIFY_THREAD(tid); - - if (paused) { - resume(); - } - - loop->stop(); - joinable.set_value(); - thread.join(); -} - -} // namespace util -} // namespace mbgl diff --git a/src/mbgl/util/thread_context.cpp b/src/mbgl/util/thread_context.cpp deleted file mode 100644 index fe64c2a686..0000000000 --- a/src/mbgl/util/thread_context.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include <mbgl/util/thread_context.hpp> -#include <utility> - -namespace mbgl { -namespace util { - -ThreadContext::ThreadContext(std::string name_, ThreadPriority priority_) - : name(std::move(name_)), - priority(priority_) { -} - -} // namespace util -} // namespace mbgl diff --git a/src/mbgl/util/thread_context.hpp b/src/mbgl/util/thread_context.hpp deleted file mode 100644 index a51dede404..0000000000 --- a/src/mbgl/util/thread_context.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include <string> - -namespace mbgl { -namespace util { - -enum class ThreadPriority : bool { - Regular, - Low, -}; - -struct ThreadContext { -public: - ThreadContext(std::string name, ThreadPriority priority = ThreadPriority::Regular); - - std::string name; - ThreadPriority priority; -}; - -} // namespace util -} // namespace mbgl |