summaryrefslogtreecommitdiff
path: root/src/mbgl/storage
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2015-04-13 18:28:18 +0200
committerKonstantin Käfer <mail@kkaefer.com>2015-04-13 18:28:18 +0200
commit452d12e6e653d61c2182f4464d4365f0b96c9739 (patch)
treea96bcdba373ca23d832364d7bce6b5912864c1f5 /src/mbgl/storage
parent16849a341b72c0633be1e3c89498c883d6efb000 (diff)
downloadqtlocation-mapboxgl-452d12e6e653d61c2182f4464d4365f0b96c9739.tar.gz
make implementation files private headers
Diffstat (limited to 'src/mbgl/storage')
-rw-r--r--src/mbgl/storage/asset_request.hpp24
-rw-r--r--src/mbgl/storage/default_file_source.cpp7
-rw-r--r--src/mbgl/storage/default_file_source_impl.hpp40
-rw-r--r--src/mbgl/storage/http_context.hpp76
-rw-r--r--src/mbgl/storage/http_request.hpp26
-rw-r--r--src/mbgl/storage/request.cpp2
-rw-r--r--src/mbgl/storage/request.hpp60
-rw-r--r--src/mbgl/storage/shared_request_base.hpp106
-rw-r--r--src/mbgl/storage/thread_context.hpp78
9 files changed, 414 insertions, 5 deletions
diff --git a/src/mbgl/storage/asset_request.hpp b/src/mbgl/storage/asset_request.hpp
new file mode 100644
index 0000000000..48d421c3be
--- /dev/null
+++ b/src/mbgl/storage/asset_request.hpp
@@ -0,0 +1,24 @@
+#ifndef MBGL_STORAGE_DEFAULT_ASSET_REQUEST
+#define MBGL_STORAGE_DEFAULT_ASSET_REQUEST
+
+#include "shared_request_base.hpp"
+
+namespace mbgl {
+
+class AssetRequest : public SharedRequestBase {
+public:
+ AssetRequest(DefaultFileSource::Impl *source, const Resource &resource);
+
+ void start(uv_loop_t *loop, std::shared_ptr<const Response> response = nullptr);
+ void cancel();
+
+private:
+ ~AssetRequest();
+ void *ptr = nullptr;
+
+ friend class AssetRequestImpl;
+};
+
+}
+
+#endif
diff --git a/src/mbgl/storage/default_file_source.cpp b/src/mbgl/storage/default_file_source.cpp
index ee4042459b..b28e096414 100644
--- a/src/mbgl/storage/default_file_source.cpp
+++ b/src/mbgl/storage/default_file_source.cpp
@@ -1,7 +1,7 @@
#include <mbgl/storage/default_file_source_impl.hpp>
-#include <mbgl/storage/default/request.hpp>
-#include <mbgl/storage/default/asset_request.hpp>
-#include <mbgl/storage/default/http_request.hpp>
+#include <mbgl/storage/request.hpp>
+#include <mbgl/storage/asset_request.hpp>
+#include <mbgl/storage/http_request.hpp>
#include <mbgl/storage/response.hpp>
#include <mbgl/platform/platform.hpp>
@@ -9,7 +9,6 @@
#include <mbgl/util/uv_detail.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/thread.hpp>
-#include <mbgl/util/run_loop.hpp>
#include <mbgl/platform/log.hpp>
#pragma GCC diagnostic push
diff --git a/src/mbgl/storage/default_file_source_impl.hpp b/src/mbgl/storage/default_file_source_impl.hpp
new file mode 100644
index 0000000000..82a3b9a1a0
--- /dev/null
+++ b/src/mbgl/storage/default_file_source_impl.hpp
@@ -0,0 +1,40 @@
+#ifndef MBGL_STORAGE_DEFAULT_DEFAULT_FILE_SOURCE_IMPL
+#define MBGL_STORAGE_DEFAULT_DEFAULT_FILE_SOURCE_IMPL
+
+#include <mbgl/storage/default_file_source.hpp>
+#include <mbgl/util/run_loop.hpp>
+
+#include <set>
+#include <unordered_map>
+
+namespace mbgl {
+
+class SharedRequestBase;
+
+class DefaultFileSource::Impl : public util::RunLoop {
+ friend class util::Thread<DefaultFileSource::Impl>;
+
+public:
+ Impl(FileCache *cache, const std::string &root = "");
+
+public:
+ void notify(SharedRequestBase *sharedRequest, const std::set<Request *> &observers,
+ std::shared_ptr<const Response> response, FileCache::Hint hint);
+ SharedRequestBase *find(const Resource &resource);
+
+ void processAdd(Request* request);
+ void processCancel(Request* request);
+ void processResult(const Resource& resource, std::shared_ptr<const Response> response);
+ void processAbort(const Environment& env);
+
+public:
+ const std::string assetRoot;
+
+private:
+ std::unordered_map<Resource, SharedRequestBase *, Resource::Hash> pending;
+ FileCache *cache = nullptr;
+};
+
+}
+
+#endif
diff --git a/src/mbgl/storage/http_context.hpp b/src/mbgl/storage/http_context.hpp
new file mode 100644
index 0000000000..6b9518dab3
--- /dev/null
+++ b/src/mbgl/storage/http_context.hpp
@@ -0,0 +1,76 @@
+#ifndef MBGL_STORAGE_DEFAULT_HTTP_CONTEXT
+#define MBGL_STORAGE_DEFAULT_HTTP_CONTEXT
+
+#include "thread_context.hpp"
+#include <mbgl/storage/network_status.hpp>
+
+#include <set>
+
+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 <typename Context>
+class HTTPContext : public ThreadContext<Context> {
+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<HTTPRequest *> requests;
+};
+
+template <typename Context>
+HTTPContext<Context>::HTTPContext(uv_loop_t *loop_)
+ : ThreadContext<Context>(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<Context *>(async->data)->requests) {
+ request->retryImmediately();
+ }
+ });
+ // Allow the loop to quit even though this handle is still active.
+ uv_unref(reinterpret_cast<uv_handle_t *>(reachability));
+ NetworkStatus::Subscribe(reachability);
+}
+
+template <typename Context>
+HTTPContext<Context>::~HTTPContext() {
+ MBGL_VERIFY_THREAD(HTTPContext<Context>::tid);
+
+ assert(requests.empty());
+
+ NetworkStatus::Unsubscribe(reachability);
+ uv::close(reachability);
+}
+
+template <typename Context>
+void HTTPContext<Context>::addRequest(HTTPRequest *request) {
+ requests.insert(request);
+}
+
+template <typename Context>
+void HTTPContext<Context>::removeRequest(HTTPRequest *request) {
+ requests.erase(request);
+}
+
+}
+
+#endif
diff --git a/src/mbgl/storage/http_request.hpp b/src/mbgl/storage/http_request.hpp
new file mode 100644
index 0000000000..54e9a77ef0
--- /dev/null
+++ b/src/mbgl/storage/http_request.hpp
@@ -0,0 +1,26 @@
+#ifndef MBGL_STORAGE_DEFAULT_HTTP_REQUEST
+#define MBGL_STORAGE_DEFAULT_HTTP_REQUEST
+
+#include "shared_request_base.hpp"
+
+namespace mbgl {
+
+class HTTPRequest : public SharedRequestBase {
+public:
+ HTTPRequest(DefaultFileSource::Impl *source, const Resource &resource);
+
+ void start(uv_loop_t *loop, std::shared_ptr<const Response> response = nullptr);
+ void cancel();
+
+ void retryImmediately();
+
+private:
+ ~HTTPRequest();
+ void *ptr = nullptr;
+
+ friend class HTTPRequestImpl;
+};
+
+}
+
+#endif
diff --git a/src/mbgl/storage/request.cpp b/src/mbgl/storage/request.cpp
index ed7f625e86..ea80e59503 100644
--- a/src/mbgl/storage/request.cpp
+++ b/src/mbgl/storage/request.cpp
@@ -1,4 +1,4 @@
-#include <mbgl/storage/default/request.hpp>
+#include <mbgl/storage/request.hpp>
#include <mbgl/storage/response.hpp>
diff --git a/src/mbgl/storage/request.hpp b/src/mbgl/storage/request.hpp
new file mode 100644
index 0000000000..00157329be
--- /dev/null
+++ b/src/mbgl/storage/request.hpp
@@ -0,0 +1,60 @@
+#ifndef MBGL_STORAGE_DEFAULT_REQUEST
+#define MBGL_STORAGE_DEFAULT_REQUEST
+
+#include <mbgl/storage/resource.hpp>
+
+#include <mbgl/util/util.hpp>
+#include <mbgl/util/noncopyable.hpp>
+
+#include <mutex>
+#include <thread>
+#include <functional>
+#include <memory>
+
+typedef struct uv_async_s uv_async_t;
+typedef struct uv_loop_s uv_loop_t;
+
+namespace mbgl {
+
+class Response;
+class Environment;
+
+class Request : private util::noncopyable {
+ MBGL_STORE_THREAD(tid)
+
+public:
+ using Callback = std::function<void(const Response &)>;
+ Request(const Resource &resource, uv_loop_t *loop, const Environment &env, Callback callback);
+
+public:
+ // May be called from any thread.
+ void notify(const std::shared_ptr<const Response> &response);
+ void destruct();
+
+ // May be called only from the thread the Request was created in.
+ void cancel();
+
+private:
+ ~Request();
+ void invoke();
+ void notifyCallback();
+
+private:
+ uv_async_t *async = nullptr;
+ struct Canceled;
+ std::unique_ptr<Canceled> canceled;
+ Callback callback;
+ std::shared_ptr<const Response> response;
+
+public:
+ const Resource resource;
+
+ // The environment ref is used to associate requests with a particular environment. This allows
+ // us to only terminate requests associated with that environment, e.g. when the map the env
+ // belongs to is discarded.
+ const Environment &env;
+};
+
+}
+
+#endif
diff --git a/src/mbgl/storage/shared_request_base.hpp b/src/mbgl/storage/shared_request_base.hpp
new file mode 100644
index 0000000000..d7ed00264a
--- /dev/null
+++ b/src/mbgl/storage/shared_request_base.hpp
@@ -0,0 +1,106 @@
+#ifndef MBGL_STORAGE_DEFAULT_SHARED_REQUEST_BASE
+#define MBGL_STORAGE_DEFAULT_SHARED_REQUEST_BASE
+
+#include <mbgl/storage/resource.hpp>
+#include <mbgl/storage/file_cache.hpp>
+#include <mbgl/storage/default_file_source_impl.hpp>
+#include <mbgl/storage/request.hpp>
+#include <mbgl/util/util.hpp>
+#include <mbgl/util/noncopyable.hpp>
+
+#include <string>
+#include <set>
+#include <vector>
+#include <cassert>
+
+typedef struct uv_loop_s uv_loop_t;
+
+namespace mbgl {
+
+class Request;
+class Response;
+class DefaultFileSource;
+
+class SharedRequestBase : private util::noncopyable {
+protected:
+ MBGL_STORE_THREAD(tid)
+
+public:
+ SharedRequestBase(DefaultFileSource::Impl *source_, const Resource &resource_)
+ : resource(resource_), source(source_) {}
+
+ virtual void start(uv_loop_t *loop, std::shared_ptr<const Response> response = nullptr) = 0;
+ virtual void cancel() = 0;
+
+ void notify(std::shared_ptr<const Response> response, FileCache::Hint hint) {
+ MBGL_VERIFY_THREAD(tid);
+
+ if (source) {
+ source->notify(this, observers, response, hint);
+ }
+ }
+
+ void subscribe(Request *request) {
+ MBGL_VERIFY_THREAD(tid);
+
+ observers.insert(request);
+ }
+
+ void unsubscribe(Request *request) {
+ MBGL_VERIFY_THREAD(tid);
+
+ observers.erase(request);
+
+ if (abandoned()) {
+ // There are no observers anymore. We are initiating cancelation.
+ if (source) {
+ // First, remove this SharedRequestBase from the source.
+ source->notify(this, observers, nullptr, FileCache::Hint::No);
+ }
+
+ // Then, initiate cancelation of this request
+ cancel();
+ }
+ }
+
+ bool abandoned() const {
+ return observers.empty();
+ }
+
+ std::vector<Request *> removeAllInEnvironment(const Environment &env) {
+ MBGL_VERIFY_THREAD(tid);
+
+ std::vector<Request *> result;
+
+ // Removes all Requests in the supplied environment and returns a list
+ // of them.
+ util::erase_if(observers, [&](Request *req) -> bool {
+ if (&req->env == &env) {
+ result.push_back(req);
+ return true;
+ } else {
+ return false;
+ }
+ });
+
+ return result;
+ }
+
+protected:
+ virtual ~SharedRequestBase() {
+ MBGL_VERIFY_THREAD(tid);
+ }
+
+public:
+ const Resource resource;
+
+protected:
+ DefaultFileSource::Impl *source = nullptr;
+
+private:
+ std::set<Request *> observers;
+};
+
+}
+
+#endif
diff --git a/src/mbgl/storage/thread_context.hpp b/src/mbgl/storage/thread_context.hpp
new file mode 100644
index 0000000000..763c83a25b
--- /dev/null
+++ b/src/mbgl/storage/thread_context.hpp
@@ -0,0 +1,78 @@
+#ifndef MBGL_STORAGE_DEFAULT_THREAD_CONTEXT
+#define MBGL_STORAGE_DEFAULT_THREAD_CONTEXT
+
+#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/std.hpp>
+#include <mbgl/util/util.hpp>
+#include <mbgl/util/uv.hpp>
+
+#include <uv.h>
+#include <pthread.h>
+
+#include <map>
+#include <cassert>
+
+namespace mbgl {
+
+// This is a template class that provides a per-thread and per-loop Context object. It can be used
+// by implementations to store global state.
+
+template <typename Context>
+class ThreadContext : private util::noncopyable {
+protected:
+ MBGL_STORE_THREAD(tid)
+ using Map = std::map<uv_loop_t *, std::unique_ptr<Context>>;
+
+public:
+ static Context *Get(uv_loop_t *loop);
+
+private:
+ static pthread_key_t key;
+ static pthread_once_t once;
+
+public:
+ ThreadContext(uv_loop_t *loop);
+ ~ThreadContext();
+
+public:
+ uv_loop_t *loop;
+};
+
+template <typename Context>
+Context *ThreadContext<Context>::Get(uv_loop_t *loop) {
+ pthread_once(&once, []() {
+ pthread_key_create(&key, [](void *ptr) {
+ assert(ptr);
+ delete reinterpret_cast<Map *>(ptr);
+ });
+ });
+ auto contexts = reinterpret_cast<Map *>(pthread_getspecific(key));
+ if (!contexts) {
+ contexts = new Map();
+ pthread_setspecific(key, contexts);
+ }
+
+ // Now find a ThreadContext that matches the requested loop.
+ auto it = contexts->find(loop);
+ if (it == contexts->end()) {
+ auto result = contexts->emplace(loop, util::make_unique<Context>(loop));
+ assert(result.second); // Make sure it was actually inserted.
+ return result.first->second.get();
+ } else {
+ return it->second.get();
+ }
+}
+
+template <typename Context>
+ThreadContext<Context>::ThreadContext(uv_loop_t *loop_) : loop(loop_) {
+}
+
+template <typename Context>
+ThreadContext<Context>::~ThreadContext() {
+ MBGL_VERIFY_THREAD(tid);
+}
+
+
+}
+
+#endif