summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2014-04-25 14:26:59 +0200
committerKonstantin Käfer <mail@kkaefer.com>2014-04-25 14:26:59 +0200
commit666f593803d29ff88173714e373a35886b51efe1 (patch)
tree8b2671142d865099e9f15d9d9a87b321f8ef92dd /common
parenta0d935eac7b9e9c68653140cee3a2b8a0600fceb (diff)
downloadqtlocation-mapboxgl-666f593803d29ff88173714e373a35886b51efe1.tar.gz
use an event loop per map that is not the render thread
Diffstat (limited to 'common')
-rw-r--r--common/curl_request.cpp14
-rw-r--r--common/foundation_request.mm20
-rw-r--r--common/glfw_view.cpp73
-rw-r--r--common/glfw_view.hpp3
4 files changed, 35 insertions, 75 deletions
diff --git a/common/curl_request.cpp b/common/curl_request.cpp
index cca50447f4..e00e805786 100644
--- a/common/curl_request.cpp
+++ b/common/curl_request.cpp
@@ -88,9 +88,10 @@ static std::queue<CURL *> curl_handle_cache;
class CURLRequest : public llmr::platform::Request {
public:
CURLRequest(const std::string &url,
- std::function<void(llmr::platform::Response *)> background_function,
- std::function<void()> foreground_callback)
- : Request(url, background_function, foreground_callback) {}
+ std::function<void(llmr::platform::Response *)> background_function,
+ std::function<void()> foreground_callback,
+ uv_loop_t *loop)
+ : Request(url, background_function, foreground_callback, loop) {}
CURL *curl = nullptr;
};
@@ -177,7 +178,7 @@ void curl_perform(uv_poll_t *req, int /*status*/, int events) {
// Executes the background_function in a libuv thread pool, and the after_work_cb back
// in the *main* event loop.
- uv_queue_work(uv_default_loop(), work, Request::work_callback, Request::after_work_callback);
+ uv_queue_work((*req)->loop, work, Request::work_callback, Request::after_work_callback);
CURL *handle = message->easy_handle;
remove_curl_handle(handle);
@@ -367,10 +368,11 @@ void thread_init_cb() {
std::shared_ptr<platform::Request>
platform::request_http(const std::string &url,
std::function<void(Response *)> background_function,
- std::function<void()> foreground_callback) {
+ std::function<void()> foreground_callback,
+ uv_loop_t *loop) {
using namespace request;
init_thread_once(thread_init_cb);
- std::shared_ptr<CURLRequest> req = std::make_shared<CURLRequest>(url, background_function, foreground_callback);
+ std::shared_ptr<CURLRequest> req = std::make_shared<CURLRequest>(url, background_function, foreground_callback, loop);
// Note that we are creating a new shared_ptr pointer(!) because the lockless queue can't store
// objects with nontrivial destructors. We have to make absolutely sure that we manually delete
diff --git a/common/foundation_request.mm b/common/foundation_request.mm
index 2bd651808a..c0b12cc734 100644
--- a/common/foundation_request.mm
+++ b/common/foundation_request.mm
@@ -41,8 +41,9 @@ class FoundationRequest : public llmr::platform::Request {
public:
FoundationRequest(const std::string &url,
std::function<void(llmr::platform::Response *)> background_function,
- std::function<void()> foreground_callback)
- : Request(url, background_function, foreground_callback) {
+ std::function<void()> foreground_callback,
+ uv_loop_t *loop)
+ : Request(url, background_function, foreground_callback, loop) {
#if TARGET_OS_IPHONE
active_tasks++;
dispatch_async(dispatch_get_main_queue(), ^(void) {
@@ -68,11 +69,12 @@ public:
std::shared_ptr<llmr::platform::Request>
llmr::platform::request_http(const std::string &url,
std::function<void(Response *)> background_function,
- std::function<void()> foreground_callback) {
+ std::function<void()> foreground_callback,
+ uv_loop_t *loop) {
uv_once(&request_initialize, request_initialize_cb);
std::shared_ptr<FoundationRequest> req =
- std::make_shared<FoundationRequest>(url, background_function, foreground_callback);
+ std::make_shared<FoundationRequest>(url, background_function, foreground_callback, loop);
// Note that we are creating a new shared_ptr pointer(!) to make sure there is at least one
// shared_ptr in existence while the NSURLSession is loading our data. We are making sure in the
@@ -91,13 +93,13 @@ llmr::platform::request_http(const std::string &url,
return;
}
- req->res = std::make_unique<Response>();
+ (*req_ptr)->res = std::make_unique<Response>();
if (!error && [response isKindOfClass:[NSHTTPURLResponse class]]) {
- req->res->code = [(NSHTTPURLResponse *)response statusCode];
- req->res->body = {(const char *)[data bytes], [data length]};
+ (*req_ptr)->res->code = [(NSHTTPURLResponse *)response statusCode];
+ (*req_ptr)->res->body = {(const char *)[data bytes], [data length]};
} else {
- req->res->error_message = [[error localizedDescription] UTF8String];
+ (*req_ptr)->res->error_message = [[error localizedDescription] UTF8String];
}
// We're currently in the request thread. We're going to schedule a uv_work request that
@@ -111,7 +113,7 @@ llmr::platform::request_http(const std::string &url,
// Executes the background_function in a libuv thread pool, and the after_work_cb back in
// the *main* event loop.
- uv_queue_work(uv_default_loop(), work, Request::work_callback,
+ uv_queue_work((*req_ptr)->loop, work, Request::work_callback,
Request::after_work_callback);
}];
diff --git a/common/glfw_view.cpp b/common/glfw_view.cpp
index 82e9aad745..d3034016fc 100644
--- a/common/glfw_view.cpp
+++ b/common/glfw_view.cpp
@@ -33,8 +33,7 @@
MapView::MapView(llmr::Settings &settings, bool fullscreen)
- : fullscreen(fullscreen), settings(settings), map(settings),
- stop_event_listener(false) {}
+ : fullscreen(fullscreen), settings(settings), map(settings) {}
MapView::~MapView() { glfwTerminate(); }
@@ -196,69 +195,27 @@ void MapView::mousemove(GLFWwindow *window, double x, double y) {
mapView->last_y = y;
}
-void MapView::eventloop(void *arg) {
- MapView *view = static_cast<MapView *>(arg);
- int r = 0;
- int fd = 0;
- int timeout;
-
- while (!view->stop_event_listener) {
- fd = uv_backend_fd(uv_default_loop());
- timeout = uv_backend_timeout(uv_default_loop());
-
- do {
-#if defined(HAVE_KQUEUE)
- struct timespec ts;
- ts.tv_sec = timeout / 1000;
- ts.tv_nsec = (timeout % 1000) * 1000000;
- r = kevent(fd, NULL, 0, NULL, 0, &ts);
-#elif defined(HAVE_EPOLL)
- {
- struct epoll_event ev;
- r = epoll_wait(fd, &ev, 1, timeout);
- }
-#endif
- } while (r == -1 && errno == EINTR);
- glfwPostEmptyEvent();
- uv_sem_wait(&view->event_listener);
- }
-}
-
int MapView::run() {
- uv_thread_t embed_thread;
-
- uv_run(uv_default_loop(), UV_RUN_NOWAIT);
-
- /* Start worker that will interrupt external loop */
- stop_event_listener = false;
- uv_sem_init(&event_listener, 0);
- uv_thread_create(&embed_thread, eventloop, this);
+ map.start();
while (!glfwWindowShouldClose(window)) {
-
- bool dirty = false;
- try {
- dirty = map.render();
- }
- catch (std::exception &ex) {
- fprintf(stderr, "exception: %s\n", ex.what());
- }
- glfwSwapBuffers(window);
- fps();
-
- if (dirty) {
- glfwPollEvents();
- } else {
- glfwWaitEvents();
+ if (map.clean.test_and_set() == false) {
+ // This branch is executed when the previous value of the "clean"
+ // flag is false (i.e. it is unclean == dirty).
+ try {
+ map.render();
+ }
+ catch (std::exception &ex) {
+ fprintf(stderr, "exception: %s\n", ex.what());
+ }
+ glfwSwapBuffers(window);
+ fps();
}
- uv_run(uv_default_loop(), UV_RUN_NOWAIT);
- uv_sem_post(&event_listener);
+ glfwWaitEvents();
}
- stop_event_listener = true;
-
- uv_thread_join(&embed_thread);
+ map.stop();
return 0;
}
diff --git a/common/glfw_view.hpp b/common/glfw_view.hpp
index 8647c8ad67..5dbb64efb2 100644
--- a/common/glfw_view.hpp
+++ b/common/glfw_view.hpp
@@ -37,8 +37,7 @@ public:
llmr::Settings &settings;
llmr::Map map;
- uv_sem_t event_listener;
- std::atomic<bool> stop_event_listener;
+ uv_loop_t *loop = nullptr;
};
#endif