diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2014-04-24 17:39:19 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2014-04-24 17:39:19 +0200 |
commit | a0d935eac7b9e9c68653140cee3a2b8a0600fceb (patch) | |
tree | 37acede4eab47679f3fada8dbdaa2c725c5946e5 /common/curl_request.cpp | |
parent | 6628b94b147b5d9330a8a367d669e1009e6ddbf3 (diff) | |
download | qtlocation-mapboxgl-a0d935eac7b9e9c68653140cee3a2b8a0600fceb.tar.gz |
unify request object to use uv_queue_work for both corefoundation + curl
Diffstat (limited to 'common/curl_request.cpp')
-rw-r--r-- | common/curl_request.cpp | 74 |
1 files changed, 20 insertions, 54 deletions
diff --git a/common/curl_request.cpp b/common/curl_request.cpp index 7cfe8fcabd..cca50447f4 100644 --- a/common/curl_request.cpp +++ b/common/curl_request.cpp @@ -1,6 +1,6 @@ -#include "curl_request.hpp" #include <llmr/platform/platform.hpp> +#include <llmr/platform/request.hpp> #include <llmr/util/uv.hpp> #include <llmr/util/std.hpp> @@ -84,6 +84,18 @@ static CURLSH *curl_share = nullptr; // all the time. 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) {} + + CURL *curl = nullptr; +}; + + // Implementation starts here. // Locks the CURL share handle @@ -165,14 +177,14 @@ 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_cb, Request::after_work_cb); + uv_queue_work(uv_default_loop(), work, Request::work_callback, Request::after_work_callback); CURL *handle = message->easy_handle; remove_curl_handle(handle); // We're setting this to NULL because there might still be shared_ptrs around that could // be cancelled. - (*req)->curl = nullptr; + ((CURLRequest *)req->get())->curl = nullptr; break; } @@ -310,7 +322,7 @@ void async_add_cb(uv_async_t * /*async*/) { handle = curl_easy_init(); } - (*req)->curl = handle; + ((CURLRequest *)req->get())->curl = handle; curl_easy_setopt(handle, CURLOPT_PRIVATE, req); curl_easy_setopt(handle, CURLOPT_URL, (*req)->url.c_str()); @@ -328,10 +340,10 @@ void async_cancel_cb(uv_async_t * /*async*/) { // It is possible that the request has not yet been started, but that it already has been // added to the queue for scheduling new requests. In this case, the CURL handle is invalid // and we manually mark the Request as cancelled. - CURL *handle = (*req)->curl; + CURL *handle = ((CURLRequest *)req->get())->curl; if (handle && !(*req)->cancelled) { remove_curl_handle(handle); - (*req)->curl = nullptr; + ((CURLRequest *)req->get())->curl = nullptr; } (*req)->cancelled = true; @@ -350,61 +362,15 @@ void thread_init_cb() { } } // end namespace request } // end namespace platform -} // end namespace llmr - -using namespace llmr::platform; - -Request::Request(const std::string &url, - std::function<void(Response *)> background_function, - std::function<void()> foreground_callback) - : url(url), - background_function(background_function), - foreground_callback(foreground_callback) { - - // Add a check handle without a callback to keep the default loop running. - // We don't have a real handler attached to the default loop right from the - // beginning, because we're using asynchronous messaging to perform the actual - // CURL request in the request thread. Only after the request is complete, we - // create an actual work request that is attached to the default loop. - check = new uv_check_t(); - uv_check_init(uv_default_loop(), check); - uv_check_start(check, [](uv_check_t *) {}); -} - -Request::~Request() { - // We need to remove our no-op handle again to allow the main event loop to exit. - uv_check_stop(check); -} - -void Request::work_cb(uv_work_t *work) { - std::shared_ptr<Request> &req = *static_cast<std::shared_ptr<Request> *>(work->data); - req->background_function(req->res.get()); -} - -// This callback is executed in the main loop. -void Request::after_work_cb(uv_work_t *work, int /*status*/) { - std::shared_ptr<Request> &req = *static_cast<std::shared_ptr<Request> *>(work->data); - - req->foreground_callback(); - - // This finally deletes the *pointer* to the shared pointer we've been holding on since we - // pushed it on the add_queue on request creation. - delete static_cast<std::shared_ptr<Request> *>(work->data); -} - - - -namespace llmr { - std::shared_ptr<platform::Request> platform::request_http(const std::string &url, std::function<void(Response *)> background_function, std::function<void()> foreground_callback) { using namespace request; init_thread_once(thread_init_cb); - std::shared_ptr<Request> req = std::make_shared<Request>(url, background_function, foreground_callback); + std::shared_ptr<CURLRequest> req = std::make_shared<CURLRequest>(url, background_function, foreground_callback); // 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 @@ -427,4 +393,4 @@ void platform::cancel_request_http(const std::shared_ptr<Request> &req) { uv_async_send(&async_cancel); } } -}
\ No newline at end of file +} // end namespace llmr |