diff options
Diffstat (limited to 'src/mbgl')
-rw-r--r-- | src/mbgl/map/map_context.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/map/raster_tile_data.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/map/source.cpp | 3 | ||||
-rw-r--r-- | src/mbgl/map/vector_tile.cpp | 3 | ||||
-rw-r--r-- | src/mbgl/sprite/sprite_store.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/storage/default_file_source.cpp | 6 | ||||
-rw-r--r-- | src/mbgl/text/glyph_pbf.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/text/glyph_store.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/util/run_loop.hpp | 159 | ||||
-rw-r--r-- | src/mbgl/util/uv_detail.hpp | 220 | ||||
-rw-r--r-- | src/mbgl/util/work_request.hpp | 24 | ||||
-rw-r--r-- | src/mbgl/util/work_task.hpp | 21 |
12 files changed, 9 insertions, 438 deletions
diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp index 031fbb57ca..f97cbb4dc7 100644 --- a/src/mbgl/map/map_context.cpp +++ b/src/mbgl/map/map_context.cpp @@ -105,7 +105,7 @@ void MapContext::setStyleURL(const std::string& url) { } FileSource* fs = util::ThreadContext::getFileSource(); - styleRequest = fs->request({ Resource::Kind::Style, styleURL }, util::RunLoop::getLoop(), [this, base](const Response &res) { + styleRequest = fs->request({ Resource::Kind::Style, styleURL }, [this, base](const Response &res) { if (res.stale) { // Only handle fresh responses. return; diff --git a/src/mbgl/map/raster_tile_data.cpp b/src/mbgl/map/raster_tile_data.cpp index f29fa86b8e..2ba03f0f0e 100644 --- a/src/mbgl/map/raster_tile_data.cpp +++ b/src/mbgl/map/raster_tile_data.cpp @@ -30,7 +30,7 @@ void RasterTileData::request(float pixelRatio, state = State::loading; FileSource* fs = util::ThreadContext::getFileSource(); - req = fs->request({ Resource::Kind::Tile, url }, util::RunLoop::getLoop(), [url, callback, this](const Response &res) { + req = fs->request({ Resource::Kind::Tile, url }, [url, callback, this](const Response &res) { if (res.stale) { // Only handle fresh responses. return; diff --git a/src/mbgl/map/source.cpp b/src/mbgl/map/source.cpp index a6fd9665bb..6a97d00f2d 100644 --- a/src/mbgl/map/source.cpp +++ b/src/mbgl/map/source.cpp @@ -16,7 +16,6 @@ #include <mbgl/storage/file_source.hpp> #include <mbgl/style/style_layer.hpp> #include <mbgl/platform/log.hpp> -#include <mbgl/util/uv_detail.hpp> #include <mbgl/util/std.hpp> #include <mbgl/util/token.hpp> #include <mbgl/util/string.hpp> @@ -148,7 +147,7 @@ void Source::load() { } FileSource* fs = util::ThreadContext::getFileSource(); - req = fs->request({ Resource::Kind::Source, info.url }, util::RunLoop::getLoop(), [this](const Response &res) { + req = fs->request({ Resource::Kind::Source, info.url }, [this](const Response &res) { if (res.stale) { // Only handle fresh responses. return; diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index b044250f8c..3cffed13ac 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -4,7 +4,6 @@ #include <mbgl/storage/response.hpp> #include <mbgl/storage/file_source.hpp> #include <mbgl/util/thread_context.hpp> -#include <mbgl/util/run_loop.hpp> #include <sstream> @@ -183,7 +182,7 @@ VectorTileMonitor::VectorTileMonitor(const SourceInfo& source, const TileID& id, } Request* VectorTileMonitor::monitorTile(std::function<void (std::exception_ptr, std::unique_ptr<GeometryTile>)> callback) { - return util::ThreadContext::getFileSource()->request({ Resource::Kind::Tile, url }, util::RunLoop::getLoop(), [callback, this](const Response& res) { + return util::ThreadContext::getFileSource()->request({ Resource::Kind::Tile, url }, [callback, this](const Response& res) { if (res.data && data == res.data) { // We got the same data again. Abort early. return; diff --git a/src/mbgl/sprite/sprite_store.cpp b/src/mbgl/sprite/sprite_store.cpp index 27b33e51e3..723204a916 100644 --- a/src/mbgl/sprite/sprite_store.cpp +++ b/src/mbgl/sprite/sprite_store.cpp @@ -40,7 +40,7 @@ void SpriteStore::setURL(const std::string& url) { loader = std::make_unique<Loader>(); FileSource* fs = util::ThreadContext::getFileSource(); - loader->jsonRequest = fs->request({ Resource::Kind::SpriteJSON, jsonURL }, util::RunLoop::getLoop(), + loader->jsonRequest = fs->request({ Resource::Kind::SpriteJSON, jsonURL }, [this, jsonURL](const Response& res) { if (res.stale) { // Only handle fresh responses. @@ -60,7 +60,7 @@ void SpriteStore::setURL(const std::string& url) { }); loader->spriteRequest = - fs->request({ Resource::Kind::SpriteImage, spriteURL }, util::RunLoop::getLoop(), + fs->request({ Resource::Kind::SpriteImage, spriteURL }, [this, spriteURL](const Response& res) { if (res.stale) { // Only handle fresh responses. diff --git a/src/mbgl/storage/default_file_source.cpp b/src/mbgl/storage/default_file_source.cpp index bfab5bfcaf..47873f76f4 100644 --- a/src/mbgl/storage/default_file_source.cpp +++ b/src/mbgl/storage/default_file_source.cpp @@ -39,9 +39,7 @@ DefaultFileSource::~DefaultFileSource() { MBGL_VERIFY_THREAD(tid); } -Request* DefaultFileSource::request(const Resource& resource, uv_loop_t* l, Callback callback) { - assert(l); - +Request* DefaultFileSource::request(const Resource& resource, Callback callback) { if (!callback) { throw util::MisuseException("FileSource callback can't be empty"); } @@ -70,7 +68,7 @@ Request* DefaultFileSource::request(const Resource& resource, uv_loop_t* l, Call url = resource.url; } - auto req = new Request({ resource.kind, url }, l, std::move(callback)); + auto req = new Request({ resource.kind, url }, util::RunLoop::getLoop(), std::move(callback)); thread->invoke(&Impl::add, req); return req; } diff --git a/src/mbgl/text/glyph_pbf.cpp b/src/mbgl/text/glyph_pbf.cpp index 66327b333f..635c434a80 100644 --- a/src/mbgl/text/glyph_pbf.cpp +++ b/src/mbgl/text/glyph_pbf.cpp @@ -92,7 +92,7 @@ GlyphPBF::GlyphPBF(GlyphStore* store, }; FileSource* fs = util::ThreadContext::getFileSource(); - req = fs->request({ Resource::Kind::Glyphs, url }, util::RunLoop::getLoop(), requestCallback); + req = fs->request({ Resource::Kind::Glyphs, url }, requestCallback); } GlyphPBF::~GlyphPBF() = default; diff --git a/src/mbgl/text/glyph_store.hpp b/src/mbgl/text/glyph_store.hpp index f8de6cbaf5..1f569664f2 100644 --- a/src/mbgl/text/glyph_store.hpp +++ b/src/mbgl/text/glyph_store.hpp @@ -6,7 +6,6 @@ #include <mbgl/text/glyph_pbf.hpp> #include <mbgl/util/exclusive.hpp> #include <mbgl/util/noncopyable.hpp> -#include <mbgl/util/run_loop.hpp> #include <mbgl/util/work_queue.hpp> #include <exception> diff --git a/src/mbgl/util/run_loop.hpp b/src/mbgl/util/run_loop.hpp deleted file mode 100644 index 6113ac2215..0000000000 --- a/src/mbgl/util/run_loop.hpp +++ /dev/null @@ -1,159 +0,0 @@ -#ifndef MBGL_UTIL_RUN_LOOP -#define MBGL_UTIL_RUN_LOOP - -#include <mbgl/util/noncopyable.hpp> -#include <mbgl/util/work_task.hpp> -#include <mbgl/util/work_request.hpp> -#include <mbgl/util/uv_detail.hpp> - -#include <functional> -#include <utility> -#include <queue> -#include <mutex> -#include <atomic> - -namespace mbgl { -namespace util { - -class RunLoop : private util::noncopyable { -public: - RunLoop(uv_loop_t*); - ~RunLoop(); - - static RunLoop* Get() { - return current.get(); - } - - static uv_loop_t* getLoop() { - return current.get()->get(); - } - - void stop(); - - // Invoke fn(args...) on this RunLoop. - template <class Fn, class... Args> - void invoke(Fn&& fn, Args&&... args) { - auto tuple = std::make_tuple(std::move(args)...); - auto task = std::make_shared<Invoker<Fn, decltype(tuple)>>( - std::move(fn), - std::move(tuple)); - - withMutex([&] { queue.push(task); }); - async.send(); - } - - // Post the cancellable work fn(args...) to this RunLoop. - template <class Fn, class... Args> - std::unique_ptr<WorkRequest> - invokeCancellable(Fn&& fn, Args&&... args) { - auto flag = std::make_shared<std::atomic<bool>>(); - *flag = false; - - auto tuple = std::make_tuple(std::move(args)...); - auto task = std::make_shared<Invoker<Fn, decltype(tuple)>>( - std::move(fn), - std::move(tuple), - flag); - - withMutex([&] { queue.push(task); }); - async.send(); - - return std::make_unique<WorkRequest>(task); - } - - // Invoke fn(args...) on this RunLoop, then invoke callback(results...) on the current RunLoop. - template <class Fn, class Cb, class... Args> - std::unique_ptr<WorkRequest> - invokeWithCallback(Fn&& fn, Cb&& callback, Args&&... args) { - auto flag = std::make_shared<std::atomic<bool>>(); - *flag = false; - - // Create a lambda L1 that invokes another lambda L2 on the current RunLoop R, that calls - // the callback C. Both lambdas check the flag before proceeding. L1 needs to check the flag - // because if the request was cancelled, then R might have been destroyed. L2 needs to check - // the flag because the request may have been cancelled after L2 was invoked but before it - // began executing. - auto after = [flag, current = RunLoop::current.get(), callback1 = std::move(callback)] (auto&&... results1) { - if (!*flag) { - current->invoke([flag, callback2 = std::move(callback1)] (auto&&... results2) { - if (!*flag) { - callback2(std::move(results2)...); - } - }, std::move(results1)...); - } - }; - - auto tuple = std::make_tuple(std::move(args)..., after); - auto task = std::make_shared<Invoker<Fn, decltype(tuple)>>( - std::move(fn), - std::move(tuple), - flag); - - withMutex([&] { queue.push(task); }); - async.send(); - - return std::make_unique<WorkRequest>(task); - } - - uv_loop_t* get() { return async.get()->loop; } - -private: - template <class F, class P> - class Invoker : public WorkTask { - public: - Invoker(F&& f, P&& p, std::shared_ptr<std::atomic<bool>> canceled_ = nullptr) - : canceled(canceled_), - func(std::move(f)), - params(std::move(p)) { - } - - void operator()() override { - // Lock the mutex while processing so that cancel() will block. - std::lock_guard<std::recursive_mutex> lock(mutex); - if (!canceled || !*canceled) { - invoke(std::make_index_sequence<std::tuple_size<P>::value>{}); - } - } - - // If the task has not yet begun, this will cancel it. - // If the task is in progress, this will block until it completed. (Currently - // necessary because of shared state, but should be removed.) It will also - // cancel the after callback. - // If the task has completed, but the after callback has not executed, this - // will cancel the after callback. - // If the task has completed and the after callback has executed, this will - // do nothing. - void cancel() override { - std::lock_guard<std::recursive_mutex> lock(mutex); - *canceled = true; - } - - private: - template <std::size_t... I> - void invoke(std::index_sequence<I...>) { - func(std::get<I>(std::forward<P>(params))...); - } - - std::recursive_mutex mutex; - std::shared_ptr<std::atomic<bool>> canceled; - - F func; - P params; - }; - - using Queue = std::queue<std::shared_ptr<WorkTask>>; - - void withMutex(std::function<void()>&&); - void process(); - - Queue queue; - std::mutex mutex; - uv::async async; - - static uv::tls<RunLoop> current; -}; - -} -} - -#endif diff --git a/src/mbgl/util/uv_detail.hpp b/src/mbgl/util/uv_detail.hpp deleted file mode 100644 index 86a64d33f2..0000000000 --- a/src/mbgl/util/uv_detail.hpp +++ /dev/null @@ -1,220 +0,0 @@ -#ifndef MBGL_UTIL_UV_DETAIL -#define MBGL_UTIL_UV_DETAIL - -#include <mbgl/util/uv.hpp> -#include <mbgl/util/noncopyable.hpp> - -#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 - -#include <functional> -#include <cassert> -#include <memory> -#include <string> - -#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; -}; - -} - -#endif diff --git a/src/mbgl/util/work_request.hpp b/src/mbgl/util/work_request.hpp deleted file mode 100644 index f2aa2bbacc..0000000000 --- a/src/mbgl/util/work_request.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef MBGL_UTIL_WORK_REQUEST -#define MBGL_UTIL_WORK_REQUEST - -#include <mbgl/util/noncopyable.hpp> - -#include <memory> - -namespace mbgl { - -class WorkTask; - -class WorkRequest : public util::noncopyable { -public: - using Task = std::shared_ptr<WorkTask>; - WorkRequest(Task); - ~WorkRequest(); - -private: - std::shared_ptr<WorkTask> task; -}; - -} - -#endif diff --git a/src/mbgl/util/work_task.hpp b/src/mbgl/util/work_task.hpp deleted file mode 100644 index 2224b211c4..0000000000 --- a/src/mbgl/util/work_task.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef MBGL_UTIL_WORK_TASK -#define MBGL_UTIL_WORK_TASK - -#include <mbgl/util/noncopyable.hpp> - -namespace mbgl { - -// A movable type-erasing function wrapper. This allows to store arbitrary invokable -// things (like std::function<>, or the result of a movable-only std::bind()) in the queue. -// Source: http://stackoverflow.com/a/29642072/331379 -class WorkTask : private util::noncopyable { -public: - virtual ~WorkTask() = default; - - virtual void operator()() = 0; - virtual void cancel() = 0; -}; - -} - -#endif |