summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThiago Marcos P. Santos <thiago@mapbox.com>2015-08-31 14:40:09 +0300
committerJohn Firebaugh <john.firebaugh@gmail.com>2015-11-16 12:25:47 -0800
commit36581f3d3015d525db92248004e9dc7477705694 (patch)
tree6f5d6fb38f3ef925a1afbbf41762581b3e0dbf66 /src
parent2eb0203bf43e635b756bbf1322c53b8d299d4b37 (diff)
downloadqtlocation-mapboxgl-36581f3d3015d525db92248004e9dc7477705694.tar.gz
[core] Do not pass uv_loop_t around
This should be abstracted by util::RunLoop
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/map/map_context.cpp2
-rw-r--r--src/mbgl/map/raster_tile_data.cpp2
-rw-r--r--src/mbgl/map/source.cpp3
-rw-r--r--src/mbgl/map/vector_tile.cpp3
-rw-r--r--src/mbgl/sprite/sprite_store.cpp4
-rw-r--r--src/mbgl/storage/default_file_source.cpp6
-rw-r--r--src/mbgl/text/glyph_pbf.cpp2
-rw-r--r--src/mbgl/text/glyph_store.hpp1
-rw-r--r--src/mbgl/util/run_loop.hpp159
-rw-r--r--src/mbgl/util/uv_detail.hpp220
-rw-r--r--src/mbgl/util/work_request.hpp24
-rw-r--r--src/mbgl/util/work_task.hpp21
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