diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2015-11-18 17:43:18 -0800 |
---|---|---|
committer | Thiago Marcos P. Santos <thiago@mapbox.com> | 2015-12-01 11:49:02 +0200 |
commit | c5a437771470382718500ba5cea598ede364b240 (patch) | |
tree | 7317fc5b61d42eed0110856ba3cdd0ced154dffc /src | |
parent | 1c63f98f6df6a8b1a5db2cfb9e0d0bedba931b07 (diff) | |
download | qtlocation-mapboxgl-c5a437771470382718500ba5cea598ede364b240.tar.gz |
[core] Privatize internal headers
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/util/async_task.hpp | 28 | ||||
-rw-r--r-- | src/mbgl/util/timer.hpp | 30 | ||||
-rw-r--r-- | src/mbgl/util/uv.hpp | 301 |
3 files changed, 359 insertions, 0 deletions
diff --git a/src/mbgl/util/async_task.hpp b/src/mbgl/util/async_task.hpp new file mode 100644 index 0000000000..09bdab94d7 --- /dev/null +++ b/src/mbgl/util/async_task.hpp @@ -0,0 +1,28 @@ +#ifndef MBGL_UTIL_ASYNC_TASK +#define MBGL_UTIL_ASYNC_TASK + +#include <mbgl/util/noncopyable.hpp> + +#include <memory> +#include <functional> + +namespace mbgl { +namespace util { + +class AsyncTask : private util::noncopyable { +public: + AsyncTask(std::function<void()>&&); + ~AsyncTask(); + + void send(); + void unref(); + +private: + class Impl; + std::unique_ptr<Impl> impl; +}; + +} +} + +#endif diff --git a/src/mbgl/util/timer.hpp b/src/mbgl/util/timer.hpp new file mode 100644 index 0000000000..932bb47950 --- /dev/null +++ b/src/mbgl/util/timer.hpp @@ -0,0 +1,30 @@ +#ifndef MBGL_UTIL_TIMER +#define MBGL_UTIL_TIMER + +#include <mbgl/util/noncopyable.hpp> +#include <mbgl/util/chrono.hpp> + +#include <memory> +#include <functional> + +namespace mbgl { +namespace util { + +class Timer : private util::noncopyable { +public: + Timer(); + ~Timer(); + + void start(Duration timeout, Duration repeat, std::function<void()>&&); + void stop(); + void unref(); + +private: + class Impl; + std::unique_ptr<Impl> impl; +}; + +} +} + +#endif diff --git a/src/mbgl/util/uv.hpp b/src/mbgl/util/uv.hpp new file mode 100644 index 0000000000..73166fe6c3 --- /dev/null +++ b/src/mbgl/util/uv.hpp @@ -0,0 +1,301 @@ +#ifndef MBGL_UTIL_UV +#define MBGL_UTIL_UV + +#include <mbgl/util/noncopyable.hpp> + +#include <functional> +#include <cassert> +#include <memory> +#include <string> +#include <memory> + +#include <uv.h> + +// XXX: uv.h will include <bits/termios.h> that will +// polute the namespace by defining "B0" which +// will conflict with boost macros. +#ifdef B0 +#undef B0 +#endif + +#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10 +#define UV_ASYNC_PARAMS(handle) uv_async_t *handle, int +#define UV_TIMER_PARAMS(timer) uv_timer_t *timer, int +#else +#define UV_ASYNC_PARAMS(handle) uv_async_t *handle +#define UV_TIMER_PARAMS(timer) uv_timer_t *timer +#endif + +#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10 + +// Add thread local storage to libuv API: +// https://github.com/joyent/libuv/commit/5d2434bf71e47802841bad218d521fa254d1ca2d + +typedef pthread_key_t uv_key_t; + +UV_EXTERN int uv_key_create(uv_key_t* key); +UV_EXTERN void uv_key_delete(uv_key_t* key); +UV_EXTERN void* uv_key_get(uv_key_t* key); +UV_EXTERN void uv_key_set(uv_key_t* key, void* value); + +#endif + +namespace uv { + +class loop : public mbgl::util::noncopyable { +public: + inline loop() { +#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10 + l = uv_loop_new(); + if (l == nullptr) { +#else + l = new uv_loop_t; + if (uv_loop_init(l) != 0) { +#endif + throw std::runtime_error("failed to initialize loop"); + } + } + + inline ~loop() { +#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10 + uv_loop_delete(l); +#else + uv_loop_close(l); + delete l; +#endif + } + + inline void run() { + uv_run(l, UV_RUN_DEFAULT); + } + + inline uv_loop_t* operator*() { + return l; + } + + inline uv_loop_t* get() { + return l; + } + +private: + uv_loop_t *l = nullptr; +}; + +template <class T> +class handle : public mbgl::util::noncopyable { +public: + inline handle() : t(reinterpret_cast<uv_handle_t*>(new T)) { + t->data = this; + } + + inline ~handle() { + uv_close(t.release(), [](uv_handle_t* h) { + delete reinterpret_cast<T*>(h); + }); + } + + inline void ref() { + uv_ref(t.get()); + } + + inline void unref() { + uv_unref(t.get()); + } + + inline T* get() { + return reinterpret_cast<T*>(t.get()); + } + +private: + std::unique_ptr<uv_handle_t> t; +}; + +class async : public handle<uv_async_t> { +public: + inline async(uv_loop_t* loop, std::function<void ()> fn_) + : fn(fn_) { + if (uv_async_init(loop, get(), async_cb) != 0) { + throw std::runtime_error("failed to initialize async"); + } + } + + inline void send() { + if (uv_async_send(get()) != 0) { + throw std::runtime_error("failed to async send"); + } + } + +private: + static void async_cb(UV_ASYNC_PARAMS(handle)) { + reinterpret_cast<async*>(handle->data)->fn(); + } + + std::function<void ()> fn; +}; + +class timer : public handle<uv_timer_t> { +public: + inline timer(uv_loop_t* loop) { + if (uv_timer_init(loop, get()) != 0) { + throw std::runtime_error("failed to initialize timer"); + } + } + + inline void start(uint64_t timeout, uint64_t repeat, std::function<void ()> fn_) { + fn = fn_; + if (uv_timer_start(get(), timer_cb, timeout, repeat) != 0) { + throw std::runtime_error("failed to start timer"); + } + } + + inline void stop() { + fn = nullptr; + if (uv_timer_stop(get()) != 0) { + throw std::runtime_error("failed to stop timer"); + } + } + +private: + static void timer_cb(UV_TIMER_PARAMS(t)) { + reinterpret_cast<timer*>(t->data)->fn(); + } + + std::function<void ()> fn; +}; + +class mutex : public mbgl::util::noncopyable { +public: + inline mutex() { + if (uv_mutex_init(&mtx) != 0) { + throw std::runtime_error("failed to initialize mutex lock"); + } + } + inline ~mutex() { uv_mutex_destroy(&mtx); } + inline void lock() { uv_mutex_lock(&mtx); } + inline void unlock() { uv_mutex_unlock(&mtx); } +private: + uv_mutex_t mtx; +}; + +class rwlock : public mbgl::util::noncopyable { +public: + inline rwlock() { + if (uv_rwlock_init(&mtx) != 0) { + throw std::runtime_error("failed to initialize read-write lock"); + } + } + inline ~rwlock() { uv_rwlock_destroy(&mtx); } + inline void rdlock() { uv_rwlock_rdlock(&mtx); } + inline void wrlock() { uv_rwlock_wrlock(&mtx); } + inline void rdunlock() { uv_rwlock_rdunlock(&mtx); } + inline void wrunlock() { uv_rwlock_wrunlock(&mtx); } + +private: + uv_rwlock_t mtx; +}; + +template <class T> +class tls : public mbgl::util::noncopyable { +public: + inline tls(T* val) { + tls(); + set(val); + } + inline tls() { + if (uv_key_create(&key) != 0) { + throw std::runtime_error("failed to initialize thread local storage key"); + } + } + inline ~tls() { uv_key_delete(&key); } + inline T* get() { return reinterpret_cast<T*>(uv_key_get(&key)); } + inline void set(T* val) { uv_key_set(&key, val); } + +private: + uv_key_t key; +}; + +class lock { +public: + lock(mutex &); + lock(const std::unique_ptr<mutex> &); + lock(const lock &) = delete; + lock(lock &&lock); + lock &operator=(const lock &lock) = delete; + lock &operator=(lock &&lock); + ~lock(); +private: + mutex *mtx = nullptr; +}; + +class readlock { +public: + readlock(rwlock &); + readlock(const std::unique_ptr<rwlock> &); + readlock(const readlock &) = delete; + readlock(readlock &&lock); + readlock &operator=(const readlock &lock) = delete; + readlock &operator=(readlock &&lock); + ~readlock(); +private: + rwlock *mtx = nullptr; +}; + +class writelock { +public: + writelock(rwlock &); + writelock(const std::unique_ptr<rwlock> &); + writelock(const writelock &) = delete; + writelock(writelock &&lock); + writelock &operator=(const writelock &lock) = delete; + writelock &operator=(writelock &&lock); + ~writelock(); +private: + rwlock *mtx = nullptr; +}; + +template <class T> +class exclusive { +public: + exclusive(T& val, mutex &mtx) : ptr(&val), lock(mtx) {} + exclusive(T *val, mutex &mtx) : ptr(val), lock(mtx) {} + exclusive(mutex &mtx) : lock(mtx) {} + exclusive(const std::unique_ptr<mutex> &mtx) : lock(mtx) {} + exclusive(const exclusive &) = delete; + exclusive(exclusive &&) = default; + exclusive &operator=(const exclusive &) = delete; + exclusive &operator=(exclusive &&) = default; + + T *operator->() { return ptr; } + const T *operator->() const { return ptr; } + T *operator*() { return ptr; } + const T *operator*() const { return ptr; } + operator T&() { return *ptr; } + operator const T&() const { return *ptr; } + + void operator<<(T& val) { operator<<(&val); } + void operator<<(T *val) { + if (ptr) { + throw std::runtime_error("exclusive<> was assigned before"); + } + ptr = val; + } + +private: + T *ptr = nullptr; + class lock lock; +}; + + + +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 |