diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2014-04-25 14:26:59 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2014-04-25 14:26:59 +0200 |
commit | 666f593803d29ff88173714e373a35886b51efe1 (patch) | |
tree | 8b2671142d865099e9f15d9d9a87b321f8ef92dd /common | |
parent | a0d935eac7b9e9c68653140cee3a2b8a0600fceb (diff) | |
download | qtlocation-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.cpp | 14 | ||||
-rw-r--r-- | common/foundation_request.mm | 20 | ||||
-rw-r--r-- | common/glfw_view.cpp | 73 | ||||
-rw-r--r-- | common/glfw_view.hpp | 3 |
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 |