summaryrefslogtreecommitdiff
path: root/include/mbgl/util
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2015-01-16 14:04:41 +0100
committerKonstantin Käfer <mail@kkaefer.com>2015-02-04 10:46:37 +0100
commitb9bf66e67ed1d0d1b1d3163255cab099a6ba4a95 (patch)
tree93ad6df882442e18d9a9771d4b4f06a0a764a0a9 /include/mbgl/util
parent3bfea8bf30c978173f1ec2fab6f89d6b33afea86 (diff)
downloadqtlocation-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.hpp95
-rw-r--r--include/mbgl/util/util.hpp15
-rw-r--r--include/mbgl/util/uv.hpp12
-rw-r--r--include/mbgl/util/variant.hpp72
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)