#ifndef MBGL_STORAGE_DEFAULT_HTTP_CONTEXT #define MBGL_STORAGE_DEFAULT_HTTP_CONTEXT #include "thread_context.hpp" #include #include namespace mbgl { class HTTPRequest; // This is a template class that provides a per-thread Context object. It can be used by HTTP // implementations to store global state. It also implements the NetworkStatus mechanism and // triggers immediate retries on all requests waiting for network status changes. template class HTTPContext : public ThreadContext { public: HTTPContext(uv_loop_t *loop); ~HTTPContext(); void addRequest(HTTPRequest *request); void removeRequest(HTTPRequest *baton); public: // Will be fired when the network status becomes reachable. uv_async_t *reachability = nullptr; // A list of all pending HTTPRequestImpls that we need to notify when the network status // changes. std::set requests; }; template HTTPContext::HTTPContext(uv_loop_t *loop_) : ThreadContext(loop_) { reachability = new uv_async_t; reachability->data = this; #if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10 uv_async_init(loop_, reachability, [](uv_async_t *async, int) { #else uv_async_init(loop_, reachability, [](uv_async_t *async) { #endif for (auto request : reinterpret_cast(async->data)->requests) { request->retryImmediately(); } }); // Allow the loop to quit even though this handle is still active. uv_unref(reinterpret_cast(reachability)); NetworkStatus::Subscribe(reachability); } template HTTPContext::~HTTPContext() { MBGL_VERIFY_THREAD(HTTPContext::tid); assert(requests.empty()); NetworkStatus::Unsubscribe(reachability); uv::close(reachability); } template void HTTPContext::addRequest(HTTPRequest *request) { requests.insert(request); } template void HTTPContext::removeRequest(HTTPRequest *request) { requests.erase(request); } } #endif