diff options
Diffstat (limited to 'include/mbgl/util')
-rw-r--r-- | include/mbgl/util/run_loop.hpp | 52 | ||||
-rw-r--r-- | include/mbgl/util/thread.hpp | 52 |
2 files changed, 104 insertions, 0 deletions
diff --git a/include/mbgl/util/run_loop.hpp b/include/mbgl/util/run_loop.hpp new file mode 100644 index 0000000000..f0318d2026 --- /dev/null +++ b/include/mbgl/util/run_loop.hpp @@ -0,0 +1,52 @@ +#ifndef MBGL_UTIL_RUN_LOOP +#define MBGL_UTIL_RUN_LOOP + +#include <mutex> +#include <functional> +#include <queue> + +namespace uv { +class async; +class loop; +} + +namespace mbgl { +namespace util { + +template <typename T> class Thread; + +class RunLoop { + friend Thread<RunLoop>; + +protected: + // These are called by the Thread<> wrapper. + RunLoop(); + ~RunLoop(); + + // Called by the Thread<> wrapper to start the loop. When you implement this + // method in a child class, you *must* call this function as the last action. + void start(); + +protected: + // Called by the Thread<> wrapper to terminate this loop. + void stop(); + +private: + // Invokes function in the run loop. + void process(); + +public: + // Schedules a function to be executed as part of this run loop. + void invoke(std::function<void()> fn); + +private: + const std::unique_ptr<uv::loop> runloop; + const std::unique_ptr<uv::async> runloopAsync; + std::mutex runloopMutex; + std::queue<std::function<void()>> runloopQueue; +}; + +} +} + +#endif
\ No newline at end of file diff --git a/include/mbgl/util/thread.hpp b/include/mbgl/util/thread.hpp new file mode 100644 index 0000000000..943039c5d6 --- /dev/null +++ b/include/mbgl/util/thread.hpp @@ -0,0 +1,52 @@ +#ifndef MBGL_UTIL_THREAD +#define MBGL_UTIL_THREAD + +#include <future> +#include <thread> + +namespace mbgl { +namespace util { + +template <class Object> +class Thread { +public: + template <class... Args> + Thread(Args&&... args); + Thread(const Thread&) = delete; + Thread(Thread&&) = delete; + Thread& operator=(const Thread&) = delete; + Thread& operator=(Thread&&) = delete; + ~Thread(); + + inline Object* operator->() const { return &object; } + inline operator Object*() const { return &object; } + +private: + std::thread thread; + Object& object; +}; + +template <class Object> +template <class... Args> +Thread<Object>::Thread(Args&&... args) + : object([&]() -> Object& { + std::promise<Object&> promise; + thread = std::thread([&] { + Object context(::std::forward<Args>(args)...); + promise.set_value(context); + context.start(); + }); + return promise.get_future().get(); + }()) { +} + +template <class Object> +Thread<Object>::~Thread() { + object.stop(); + thread.join(); +} + +} +} + +#endif |