diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2015-04-16 08:50:24 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2015-04-16 08:50:24 -0700 |
commit | 7000a4faf082b899c97923168fba343dff2888f4 (patch) | |
tree | a9c4f798f03bec30118807f15db3e028c22a7fe0 /include | |
parent | 39bd83946fc36d3400682eb68ee9841eb1f9cd10 (diff) | |
parent | ac25d32a094f83ed51d5854c9f234b10eedbeac0 (diff) | |
download | qtlocation-mapboxgl-7000a4faf082b899c97923168fba343dff2888f4.tar.gz |
Merge pull request #1250 from mapbox/1250-separate-thread-object
Separate objects from Thread management
Diffstat (limited to 'include')
-rw-r--r-- | include/mbgl/android/native_map_view.hpp | 2 | ||||
-rw-r--r-- | include/mbgl/storage/default/asset_request.hpp | 24 | ||||
-rw-r--r-- | include/mbgl/storage/default/http_context.hpp | 76 | ||||
-rw-r--r-- | include/mbgl/storage/default/http_request.hpp | 26 | ||||
-rw-r--r-- | include/mbgl/storage/default/request.hpp | 60 | ||||
-rw-r--r-- | include/mbgl/storage/default/shared_request_base.hpp | 107 | ||||
-rw-r--r-- | include/mbgl/storage/default/sqlite_cache.hpp | 54 | ||||
-rw-r--r-- | include/mbgl/storage/default/thread_context.hpp | 78 | ||||
-rw-r--r-- | include/mbgl/storage/default_file_source.hpp | 45 | ||||
-rw-r--r-- | include/mbgl/storage/file_cache.hpp | 4 | ||||
-rw-r--r-- | include/mbgl/storage/sqlite_cache.hpp | 30 |
11 files changed, 39 insertions, 467 deletions
diff --git a/include/mbgl/android/native_map_view.hpp b/include/mbgl/android/native_map_view.hpp index 21784f5315..14ccaba3f7 100644 --- a/include/mbgl/android/native_map_view.hpp +++ b/include/mbgl/android/native_map_view.hpp @@ -4,7 +4,7 @@ #include <mbgl/map/map.hpp> #include <mbgl/map/view.hpp> #include <mbgl/util/noncopyable.hpp> -#include <mbgl/storage/default/sqlite_cache.hpp> +#include <mbgl/storage/sqlite_cache.hpp> #include <mbgl/storage/default_file_source.hpp> #include <string> diff --git a/include/mbgl/storage/default/asset_request.hpp b/include/mbgl/storage/default/asset_request.hpp deleted file mode 100644 index c582c025fb..0000000000 --- a/include/mbgl/storage/default/asset_request.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#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 *source, const Resource &resource); - - void start(uv_loop_t *loop, std::unique_ptr<Response> response = nullptr); - void cancel(); - -private: - ~AssetRequest(); - void *ptr = nullptr; - - friend class AssetRequestImpl; -}; - -} - -#endif diff --git a/include/mbgl/storage/default/http_context.hpp b/include/mbgl/storage/default/http_context.hpp deleted file mode 100644 index 6b9518dab3..0000000000 --- a/include/mbgl/storage/default/http_context.hpp +++ /dev/null @@ -1,76 +0,0 @@ -#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/include/mbgl/storage/default/http_request.hpp b/include/mbgl/storage/default/http_request.hpp deleted file mode 100644 index 914e622f13..0000000000 --- a/include/mbgl/storage/default/http_request.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#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 *source, const Resource &resource); - - void start(uv_loop_t *loop, std::unique_ptr<Response> response = nullptr); - void cancel(); - - void retryImmediately(); - -private: - ~HTTPRequest(); - void *ptr = nullptr; - - friend class HTTPRequestImpl; -}; - -} - -#endif diff --git a/include/mbgl/storage/default/request.hpp b/include/mbgl/storage/default/request.hpp deleted file mode 100644 index 00157329be..0000000000 --- a/include/mbgl/storage/default/request.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#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/include/mbgl/storage/default/shared_request_base.hpp b/include/mbgl/storage/default/shared_request_base.hpp deleted file mode 100644 index 59e38efc2f..0000000000 --- a/include/mbgl/storage/default/shared_request_base.hpp +++ /dev/null @@ -1,107 +0,0 @@ -#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.hpp> -#include <mbgl/storage/default/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 *source_, const Resource &resource_) - : resource(resource_), source(source_) {} - - virtual void start(uv_loop_t *loop, std::unique_ptr<Response> response = nullptr) = 0; - virtual void cancel() = 0; - - void notify(std::unique_ptr<Response> response, FileCache::Hint hint) { - MBGL_VERIFY_THREAD(tid); - - if (source) { - source->notify(this, observers, std::shared_ptr<const Response>(std::move(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 *source = nullptr; - -private: - std::set<Request *> observers; -}; - -} - -#endif diff --git a/include/mbgl/storage/default/sqlite_cache.hpp b/include/mbgl/storage/default/sqlite_cache.hpp deleted file mode 100644 index fe80a41b52..0000000000 --- a/include/mbgl/storage/default/sqlite_cache.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef MBGL_STORAGE_DEFAULT_SQLITE_CACHE -#define MBGL_STORAGE_DEFAULT_SQLITE_CACHE - -#include <mbgl/storage/file_cache.hpp> - -#include <string> -#include <thread> - -typedef struct uv_loop_s uv_loop_t; - -namespace mapbox { namespace util { template<typename... Types> class variant; } } -namespace mapbox { namespace sqlite { class Database; class Statement; } } - -namespace mbgl { - -namespace util { template <typename T> class AsyncQueue; } - -class SQLiteCache : public FileCache { - struct GetAction; - struct PutAction; - struct RefreshAction; - struct StopAction; - using Action = mapbox::util::variant<GetAction, PutAction, RefreshAction, StopAction>; - using Queue = util::AsyncQueue<Action>; - -public: - SQLiteCache(const std::string &path = ":memory:"); - ~SQLiteCache(); - - void get(const Resource &resource, std::function<void(std::unique_ptr<Response>)> callback); - void put(const Resource &resource, std::shared_ptr<const Response> response, Hint hint); - -private: - struct ActionDispatcher; - void process(GetAction &action); - void process(PutAction &action); - void process(RefreshAction &action); - void process(StopAction &action); - - void createDatabase(); - void createSchema(); - - const std::string path; - uv_loop_t *loop = nullptr; - Queue *queue = nullptr; - std::thread thread; - std::unique_ptr<::mapbox::sqlite::Database> db; - std::unique_ptr<::mapbox::sqlite::Statement> getStmt, putStmt, refreshStmt; - bool schema = false; -}; - -} - -#endif diff --git a/include/mbgl/storage/default/thread_context.hpp b/include/mbgl/storage/default/thread_context.hpp deleted file mode 100644 index 763c83a25b..0000000000 --- a/include/mbgl/storage/default/thread_context.hpp +++ /dev/null @@ -1,78 +0,0 @@ -#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 diff --git a/include/mbgl/storage/default_file_source.hpp b/include/mbgl/storage/default_file_source.hpp index 7aab54f731..f393747168 100644 --- a/include/mbgl/storage/default_file_source.hpp +++ b/include/mbgl/storage/default_file_source.hpp @@ -4,24 +4,18 @@ #include <mbgl/storage/file_source.hpp> #include <mbgl/storage/file_cache.hpp> -#include <set> -#include <unordered_map> -#include <thread> - -namespace mapbox { namespace util { template<typename... Types> class variant; } } - namespace mbgl { -namespace util { template <typename T> class AsyncQueue; } - -class SharedRequestBase; +namespace util { +template <typename T> class Thread; +} class DefaultFileSource : public FileSource { public: DefaultFileSource(FileCache *cache, const std::string &root = ""); - DefaultFileSource(FileCache *cache, uv_loop_t *loop, const std::string &root = ""); ~DefaultFileSource() override; + // FileSource API Request *request(const Resource &resource, uv_loop_t *loop, const Environment &env, Callback callback) override; void cancel(Request *request) override; @@ -29,37 +23,10 @@ public: void abort(const Environment &env) override; - void notify(SharedRequestBase *sharedRequest, const std::set<Request *> &observers, - std::shared_ptr<const Response> response, FileCache::Hint hint); - public: - const std::string assetRoot; - + class Impl; private: - struct ActionDispatcher; - struct AddRequestAction; - struct RemoveRequestAction; - struct ResultAction; - struct StopAction; - struct AbortAction; - using Action = mapbox::util::variant<AddRequestAction, RemoveRequestAction, ResultAction, - StopAction, AbortAction>; - using Queue = util::AsyncQueue<Action>; - - void process(AddRequestAction &action); - void process(RemoveRequestAction &action); - void process(ResultAction &action); - void process(StopAction &action); - void process(AbortAction &action); - - SharedRequestBase *find(const Resource &resource); - - std::unordered_map<Resource, SharedRequestBase *, Resource::Hash> pending; - - uv_loop_t *loop = nullptr; - FileCache *cache = nullptr; - Queue *queue = nullptr; - std::thread thread; + const std::unique_ptr<util::Thread<Impl>> thread; }; } diff --git a/include/mbgl/storage/file_cache.hpp b/include/mbgl/storage/file_cache.hpp index 97e75a5d85..f815d5b8c2 100644 --- a/include/mbgl/storage/file_cache.hpp +++ b/include/mbgl/storage/file_cache.hpp @@ -16,9 +16,9 @@ public: virtual ~FileCache() = default; enum class Hint : uint8_t { Full, Refresh, No }; + using Callback = std::function<void(std::unique_ptr<Response>)>; - virtual void get(const Resource &resource, - std::function<void(std::unique_ptr<Response>)> callback) = 0; + virtual void get(const Resource &resource, Callback callback) = 0; virtual void put(const Resource &resource, std::shared_ptr<const Response> response, Hint hint) = 0; }; diff --git a/include/mbgl/storage/sqlite_cache.hpp b/include/mbgl/storage/sqlite_cache.hpp new file mode 100644 index 0000000000..b216f74d7b --- /dev/null +++ b/include/mbgl/storage/sqlite_cache.hpp @@ -0,0 +1,30 @@ +#ifndef MBGL_STORAGE_DEFAULT_SQLITE_CACHE +#define MBGL_STORAGE_DEFAULT_SQLITE_CACHE + +#include <mbgl/storage/file_cache.hpp> + +#include <string> + +namespace mbgl { + +namespace util { +template <typename T> class Thread; +} + +class SQLiteCache : public FileCache { +public: + SQLiteCache(const std::string &path = ":memory:"); + ~SQLiteCache() override; + + // FileCache API + void get(const Resource &resource, Callback callback) override; + void put(const Resource &resource, std::shared_ptr<const Response> response, Hint hint) override; + +private: + class Impl; + const std::unique_ptr<util::Thread<Impl>> thread; +}; + +} + +#endif |