diff options
author | Thiago Marcos P. Santos <thiago@mapbox.com> | 2015-11-25 16:35:08 +0200 |
---|---|---|
committer | Thiago Marcos P. Santos <thiago@mapbox.com> | 2015-12-01 11:49:02 +0200 |
commit | ed29223e5a626980100b7dc4f85737852f1a5319 (patch) | |
tree | f82e6764ad1d668dcdc41389eb1dd7a933c9d0dc | |
parent | 7caaebb16236ae014f534b490b05f5b5d6a90213 (diff) | |
download | qtlocation-mapboxgl-ed29223e5a626980100b7dc4f85737852f1a5319.tar.gz |
[core] Remove mbgl/util/uv.hpp
Now only a few things depend on libuv and they can use it directly.
-rw-r--r-- | platform/default/async_task.cpp | 45 | ||||
-rw-r--r-- | platform/default/run_loop.cpp | 4 | ||||
-rw-r--r-- | platform/default/timer.cpp | 65 | ||||
-rw-r--r-- | src/mbgl/util/uv.cpp | 114 | ||||
-rw-r--r-- | src/mbgl/util/uv.hpp | 301 |
5 files changed, 95 insertions, 434 deletions
diff --git a/platform/default/async_task.cpp b/platform/default/async_task.cpp index 6dccd9bcb0..064e8dad06 100644 --- a/platform/default/async_task.cpp +++ b/platform/default/async_task.cpp @@ -1,35 +1,62 @@ #include <mbgl/util/async_task.hpp> #include <mbgl/util/run_loop.hpp> -#include <mbgl/util/uv.hpp> #include <atomic> #include <functional> +#include <uv.h> + +#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 { class AsyncTask::Impl { public: Impl(std::function<void()>&& fn) - : async(reinterpret_cast<uv_loop_t*>(RunLoop::getLoopHandle()), [this] { runTask(); }) - , task(std::move(fn)) { + : async(new uv_async_t), + task(std::move(fn)) { + + uv_loop_t* loop = reinterpret_cast<uv_loop_t*>(RunLoop::getLoopHandle()); + if (uv_async_init(loop, async, asyncCallback) != 0) { + throw std::runtime_error("Failed to initialize async."); + } + + handle()->data = this; } - void maySend() { - async.send(); + ~Impl() { + uv_close(handle(), [](uv_handle_t* h) { + delete reinterpret_cast<uv_async_t*>(h); + }); } - void runTask() { - task(); + void maySend() { + // uv_async_send will do the call coalescing for us. + if (uv_async_send(async) != 0) { + throw std::runtime_error("Failed to async send."); + } } void unref() { - async.unref(); + uv_unref(handle()); } private: - uv::async async; + static void asyncCallback(UV_ASYNC_PARAMS(handle)) { + reinterpret_cast<Impl*>(handle->data)->task(); + } + + uv_handle_t* handle() { + return reinterpret_cast<uv_handle_t*>(async); + } + + uv_async_t* async; std::function<void()> task; }; diff --git a/platform/default/run_loop.cpp b/platform/default/run_loop.cpp index 9ca7cc9207..a37fbbb67e 100644 --- a/platform/default/run_loop.cpp +++ b/platform/default/run_loop.cpp @@ -1,8 +1,10 @@ #include <mbgl/util/run_loop.hpp> #include <mbgl/util/async_task.hpp> -#include <mbgl/util/uv.hpp> #include <mbgl/util/thread_local.hpp> +#include <uv.h> + +#include <cassert> #include <functional> #include <unordered_map> diff --git a/platform/default/timer.cpp b/platform/default/timer.cpp index 78275814a6..4df1a28bf9 100644 --- a/platform/default/timer.cpp +++ b/platform/default/timer.cpp @@ -1,18 +1,65 @@ #include <mbgl/util/timer.hpp> #include <mbgl/util/run_loop.hpp> -#include <mbgl/util/uv.hpp> + +#include <uv.h> + +#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10 +#define UV_TIMER_PARAMS(timer) uv_timer_t *timer, int +#else +#define UV_TIMER_PARAMS(timer) uv_timer_t *timer +#endif namespace mbgl { namespace util { class Timer::Impl { public: - Impl() - : timer(reinterpret_cast<uv_loop_t*>(RunLoop::getLoopHandle())) { + Impl() : timer(new uv_timer_t) { + uv_loop_t* loop = reinterpret_cast<uv_loop_t*>(RunLoop::getLoopHandle()); + if (uv_timer_init(loop, timer) != 0) { + throw std::runtime_error("Failed to initialize timer."); + } + + handle()->data = this; + } + + ~Impl() { + uv_close(handle(), [](uv_handle_t* h) { + delete reinterpret_cast<uv_timer_t*>(h); + }); + } + + void start(uint64_t timeout, uint64_t repeat, std::function<void ()>&& cb_) { + cb = std::move(cb_); + if (uv_timer_start(timer, timerCallback, timeout, repeat) != 0) { + throw std::runtime_error("Failed to start timer."); + } + } + + void stop() { + cb = nullptr; + if (uv_timer_stop(timer) != 0) { + throw std::runtime_error("Failed to stop timer."); + } + } + + void unref() { + uv_unref(handle()); + } + +private: + static void timerCallback(UV_TIMER_PARAMS(handle)) { + reinterpret_cast<Impl*>(handle->data)->cb(); + } + + uv_handle_t* handle() { + return reinterpret_cast<uv_handle_t*>(timer); } - uv::timer timer; + uv_timer_t* timer; + + std::function<void()> cb; }; Timer::Timer() @@ -23,17 +70,17 @@ Timer::~Timer() { } void Timer::start(Duration timeout, Duration repeat, std::function<void()>&& cb) { - impl->timer.start(std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count(), - std::chrono::duration_cast<std::chrono::milliseconds>(repeat).count(), - std::move(cb)); + impl->start(std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count(), + std::chrono::duration_cast<std::chrono::milliseconds>(repeat).count(), + std::move(cb)); } void Timer::stop() { - impl->timer.stop(); + impl->stop(); } void Timer::unref() { - impl->timer.unref(); + impl->unref(); } } diff --git a/src/mbgl/util/uv.cpp b/src/mbgl/util/uv.cpp deleted file mode 100644 index 4f56b419e7..0000000000 --- a/src/mbgl/util/uv.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include <mbgl/util/uv.hpp> -#include <mbgl/util/string.hpp> - -#include <uv.h> - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-variable" -// Check libuv library version. -const static bool uvVersionCheck = []() { - const unsigned int version = uv_version(); - const unsigned int major = (version >> 16) & 0xFF; - const unsigned int minor = (version >> 8) & 0xFF; - const unsigned int patch = version & 0xFF; -#pragma GCC diagnostic pop - -#ifndef UV_VERSION_PATCH - // 0.10 doesn't have UV_VERSION_PATCH defined, so we "fake" it by using the library patch level. - const unsigned int UV_VERSION_PATCH = version & 0xFF; -#endif - - if (major != UV_VERSION_MAJOR || (major == 0 && minor != UV_VERSION_MINOR)) { - throw std::runtime_error(mbgl::util::sprintf<96>( - "libuv version mismatch: headers report %d.%d.%d, but library reports %d.%d.%d", UV_VERSION_MAJOR, - UV_VERSION_MINOR, UV_VERSION_PATCH, major, minor, patch)); - } - return true; -}(); - -#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10 - -int uv_key_create(uv_key_t* key) { - return -pthread_key_create(key, NULL); -} - -void uv_key_delete(uv_key_t* key) { - if (pthread_key_delete(*key)) - abort(); -} - -void* uv_key_get(uv_key_t* key) { - return pthread_getspecific(*key); -} - -void uv_key_set(uv_key_t* key, void* value) { - if (pthread_setspecific(*key, value)) - abort(); -} - -#endif - -namespace uv { - -lock::lock(mutex &mtx_) : mtx(&mtx_) { - if (mtx) { mtx->lock(); } -} -lock::lock(const std::unique_ptr<mutex> &mtx_) : mtx(mtx_.get()) { - if (mtx) { mtx->lock(); } -} -lock::~lock() { - if (mtx) { mtx->unlock(); } -} -lock::lock(lock &&other) { - std::swap(mtx, other.mtx); -} -lock &lock::operator=(lock &&other) { - std::swap(mtx, other.mtx); - return *this; -} - - -readlock::readlock(rwlock &mtx_) : mtx(&mtx_) { - if (mtx) { mtx->rdlock(); } -} -readlock::readlock(const std::unique_ptr<rwlock> &mtx_) : mtx(mtx_.get()) { - if (mtx) { mtx->rdlock(); } -} -readlock::~readlock() { - if (mtx) { mtx->rdunlock(); } -} -readlock::readlock(readlock &&lock) { - std::swap(mtx, lock.mtx); -} -readlock &readlock::operator=(readlock &&lock) { - std::swap(mtx, lock.mtx); - return *this; -} - - -writelock::writelock(rwlock &mtx_) : mtx(&mtx_) { - if (mtx) { mtx->wrlock(); } -} -writelock::writelock(const std::unique_ptr<rwlock> &mtx_) : mtx(mtx_.get()) { - if (mtx) { mtx->wrlock(); } -} -writelock::~writelock() { - if (mtx) { mtx->wrunlock(); } -} -writelock::writelock(writelock &&lock) { - std::swap(mtx, lock.mtx); -} -writelock &writelock::operator=(writelock &&lock) { - std::swap(mtx, lock.mtx); - return *this; -} - -const char *getFileRequestError(uv_fs_t *req) { -#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10 - return uv_strerror(uv_last_error(req->loop)); -#else - return uv_strerror(int(req->result)); -#endif -} - -} diff --git a/src/mbgl/util/uv.hpp b/src/mbgl/util/uv.hpp deleted file mode 100644 index 73166fe6c3..0000000000 --- a/src/mbgl/util/uv.hpp +++ /dev/null @@ -1,301 +0,0 @@ -#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 |