diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2015-01-16 14:04:41 +0100 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2015-02-04 10:46:37 +0100 |
commit | b9bf66e67ed1d0d1b1d3163255cab099a6ba4a95 (patch) | |
tree | 93ad6df882442e18d9a9771d4b4f06a0a764a0a9 /include/mbgl/util | |
parent | 3bfea8bf30c978173f1ec2fab6f89d6b33afea86 (diff) | |
download | qtlocation-mapboxgl-b9bf66e67ed1d0d1b1d3163255cab099a6ba4a95.tar.gz |
rewrite storage layer to be independent of the Map's event loop
Diffstat (limited to 'include/mbgl/util')
-rw-r--r-- | include/mbgl/util/async_queue.hpp | 95 | ||||
-rw-r--r-- | include/mbgl/util/util.hpp | 15 | ||||
-rw-r--r-- | include/mbgl/util/uv.hpp | 12 | ||||
-rw-r--r-- | include/mbgl/util/variant.hpp | 72 |
4 files changed, 173 insertions, 21 deletions
diff --git a/include/mbgl/util/async_queue.hpp b/include/mbgl/util/async_queue.hpp new file mode 100644 index 0000000000..b3eaabc319 --- /dev/null +++ b/include/mbgl/util/async_queue.hpp @@ -0,0 +1,95 @@ +#ifndef MBGL_UTIL_ASYNC_QUEUE +#define MBGL_UTIL_ASYNC_QUEUE + +#include "std.hpp" + +#include <uv.h> + +#include <thread> +#include <mutex> +#include <functional> +#include <queue> +#include <string> + + +#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10 +#define UV_ASYNC_PARAMS(handle) uv_async_t *handle, int +#else +#define UV_ASYNC_PARAMS(handle) uv_async_t *handle +#endif + +namespace mbgl { +namespace util { + +template <typename T> +class AsyncQueue { +public: + AsyncQueue(uv_loop_t *loop, std::function<void(T &)> fn) : + callback(fn) { + async.data = this; + uv_async_init(loop, &async, [](UV_ASYNC_PARAMS(handle)) { + auto q = reinterpret_cast<AsyncQueue *>(handle->data); + q->process(); + }); + } + + void send(T &&data) { + { + std::lock_guard<std::mutex> lock(mutex); + queue.push(util::make_unique<T>(std::move(data))); + } + uv_async_send(&async); + } + + void send(std::unique_ptr<T> data) { + { + std::lock_guard<std::mutex> lock(mutex); + queue.push(std::move(data)); + } + uv_async_send(&async); + } + + void stop() { + uv_close((uv_handle_t *)&async, [](uv_handle_t *handle) { + delete reinterpret_cast<AsyncQueue *>(handle->data); + }); + } + + void ref() { + uv_ref((uv_handle_t *)&async); + } + + void unref() { + uv_unref((uv_handle_t *)&async); + } + +private: + ~AsyncQueue() { + } + + void process() { + std::unique_ptr<T> item; + while (true) { + mutex.lock(); + if (queue.empty()) { + mutex.unlock(); + break; + } + item = std::move(queue.front()); + queue.pop(); + mutex.unlock(); + callback(*item); + } + } + +private: + std::mutex mutex; + uv_async_t async; + std::queue<std::unique_ptr<T>> queue; + std::function<void(T &)> callback; +}; + +} +} + +#endif diff --git a/include/mbgl/util/util.hpp b/include/mbgl/util/util.hpp new file mode 100644 index 0000000000..bf5dad3c01 --- /dev/null +++ b/include/mbgl/util/util.hpp @@ -0,0 +1,15 @@ +#ifndef MBGL_UTIL_UTIL +#define MBGL_UTIL_UTIL + +#include <thread> + +#ifndef NDEBUG +#include <thread> +#define MBGL_STORE_THREAD(tid) const std::thread::id tid = std::this_thread::get_id(); +#define MBGL_VERIFY_THREAD(tid) assert(tid == std::this_thread::get_id()); +#else +#define MBGL_STORE_THREAD(tid) +#define MBGL_VERIFY_THREAD(tid) +#endif + +#endif diff --git a/include/mbgl/util/uv.hpp b/include/mbgl/util/uv.hpp index f59037c1d8..85f93e78bd 100644 --- a/include/mbgl/util/uv.hpp +++ b/include/mbgl/util/uv.hpp @@ -3,10 +3,11 @@ #include <string> +typedef struct uv_handle_s uv_handle_t; typedef struct uv_async_s uv_async_t; typedef struct uv_timer_s uv_timer_t; -typedef struct uv_handle_s uv_handle_t; typedef struct uv_loop_s uv_loop_t; +typedef struct uv_fs_s uv_fs_t; namespace uv { @@ -19,6 +20,15 @@ class worker; class mutex; class cond; +const char *getFileRequestError(uv_fs_t *req); + +template <typename T> +void close(T *specific) { + uv_close(reinterpret_cast<uv_handle_t *>(specific), [](uv_handle_t *generic) { + delete reinterpret_cast<T *>(generic); + }); +} + } #endif diff --git a/include/mbgl/util/variant.hpp b/include/mbgl/util/variant.hpp index 2de195cd69..411f1918d5 100644 --- a/include/mbgl/util/variant.hpp +++ b/include/mbgl/util/variant.hpp @@ -10,7 +10,7 @@ #include <iosfwd> #include <string> -#include <mbgl/util/recursive_wrapper.hpp> +#include "recursive_wrapper.hpp" #ifdef _MSC_VER // http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx @@ -34,7 +34,19 @@ // translates to 100 #define VARIANT_VERSION (VARIANT_MAJOR_VERSION*100000) + (VARIANT_MINOR_VERSION*100) + (VARIANT_PATCH_VERSION) -namespace mapbox { namespace util { namespace detail { +namespace mapbox { namespace util { + +// static visitor +template <typename R = void> +struct static_visitor +{ + using result_type = R; +protected: + static_visitor() {} + ~static_visitor() {} +}; + +namespace detail { static constexpr std::size_t invalid_value = std::size_t(-1); @@ -109,18 +121,38 @@ struct select_type<0, T, Types...> using type = T; }; -} // namespace detail -// static visitor -template <typename R = void> -struct static_visitor +template <typename T, typename R = void> +struct enable_if_type { using type = R; }; + +template <typename F, typename V, typename Enable = void> +struct result_of_unary_visit { - using result_type = R; -protected: - static_visitor() {} - ~static_visitor() {} + using type = typename std::result_of<F(V&)>::type; }; +template <typename F, typename V> +struct result_of_unary_visit<F, V, typename enable_if_type<typename F::result_type>::type > +{ + using type = typename F::result_type; +}; + +template <typename F, typename V, class Enable = void> +struct result_of_binary_visit +{ + using type = typename std::result_of<F(V&,V&)>::type; +}; + + +template <typename F, typename V> +struct result_of_binary_visit<F, V, typename enable_if_type<typename F::result_type>::type > +{ + using type = typename F::result_type; +}; + + +} // namespace detail + template <std::size_t arg1, std::size_t ... others> struct static_max; @@ -225,7 +257,7 @@ struct dispatcher; template <typename F, typename V, typename T, typename...Types> struct dispatcher<F, V, T, Types...> { - using result_type = typename F::result_type; + using result_type = typename detail::result_of_unary_visit<F, V>::type; VARIANT_INLINE static result_type apply_const(V const& v, F f) { if (v.get_type_index() == sizeof...(Types)) @@ -254,7 +286,7 @@ struct dispatcher<F, V, T, Types...> template<typename F, typename V> struct dispatcher<F, V> { - using result_type = typename F::result_type; + using result_type = typename detail::result_of_unary_visit<F, V>::type; VARIANT_INLINE static result_type apply_const(V const&, F) { throw std::runtime_error(std::string("unary dispatch: FAIL ") + typeid(V).name()); @@ -273,7 +305,7 @@ struct binary_dispatcher_rhs; template <typename F, typename V, typename T0, typename T1, typename...Types> struct binary_dispatcher_rhs<F, V, T0, T1, Types...> { - using result_type = typename F::result_type; + using result_type = typename detail::result_of_binary_visit<F, V>::type; VARIANT_INLINE static result_type apply_const(V const& lhs, V const& rhs, F f) { if (rhs.get_type_index() == sizeof...(Types)) // call binary functor @@ -305,7 +337,7 @@ struct binary_dispatcher_rhs<F, V, T0, T1, Types...> template<typename F, typename V, typename T> struct binary_dispatcher_rhs<F, V, T> { - using result_type = typename F::result_type; + using result_type = typename detail::result_of_binary_visit<F, V>::type; VARIANT_INLINE static result_type apply_const(V const&, V const&, F) { throw std::runtime_error("binary dispatch: FAIL"); @@ -323,7 +355,7 @@ struct binary_dispatcher_lhs; template <typename F, typename V, typename T0, typename T1, typename...Types> struct binary_dispatcher_lhs<F, V, T0, T1, Types...> { - using result_type = typename F::result_type; + using result_type = typename detail::result_of_binary_visit<F, V>::type; VARIANT_INLINE static result_type apply_const(V const& lhs, V const& rhs, F f) { if (lhs.get_type_index() == sizeof...(Types)) // call binary functor @@ -353,7 +385,7 @@ struct binary_dispatcher_lhs<F, V, T0, T1, Types...> template<typename F, typename V, typename T> struct binary_dispatcher_lhs<F, V, T> { - using result_type = typename F::result_type; + using result_type = typename detail::result_of_binary_visit<F, V>::type; VARIANT_INLINE static result_type apply_const(V const&, V const&, F) { throw std::runtime_error("binary dispatch: FAIL"); @@ -371,7 +403,7 @@ struct binary_dispatcher; template <typename F, typename V, typename T, typename...Types> struct binary_dispatcher<F, V, T, Types...> { - using result_type = typename F::result_type; + using result_type = typename detail::result_of_binary_visit<F, V>::type; VARIANT_INLINE static result_type apply_const(V const& v0, V const& v1, F f) { if (v0.get_type_index() == sizeof...(Types)) @@ -416,7 +448,7 @@ struct binary_dispatcher<F, V, T, Types...> template<typename F, typename V> struct binary_dispatcher<F, V> { - using result_type = typename F::result_type; + using result_type = typename detail::result_of_binary_visit<F, V>::type; VARIANT_INLINE static result_type apply_const(V const&, V const&, F) { throw std::runtime_error("binary dispatch: FAIL"); @@ -448,7 +480,7 @@ struct less_comp }; template <typename Variant, typename Comp> -class comparer : public static_visitor<bool> +class comparer { public: explicit comparer(Variant const& lhs) noexcept @@ -467,7 +499,7 @@ private: // operator<< helper template <typename Out> -class printer : public static_visitor<> +class printer { public: explicit printer(Out & out) |