summaryrefslogtreecommitdiff
path: root/include/mbgl
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2015-03-04 12:32:14 +0100
committerKonstantin Käfer <mail@kkaefer.com>2015-03-06 08:21:47 -0800
commit9781785ab73e8394e8b92625cc4741952f47955d (patch)
tree1b9e6b86c1c9ca19bb1bf1c52bcd0e41410ced66 /include/mbgl
parent8c0acecbe362be4a40638491b67ee5fe3d23a65e (diff)
downloadqtlocation-mapboxgl-9781785ab73e8394e8b92625cc4741952f47955d.tar.gz
scope Requests to an Environment object for easier cancelation
we are now scoping all file requests to an environment object. The FileSource implementation treats this as an opaque pointer, but allows canceling all Requests that are associated with that pointer. This is necessary to abort all file requests that originated from a particular Map object. Aborting a file request is different from canceling a file request: A canceled request doesn't have its callback called, while an aborted request will have its callback called with an error, indicating that the environment is going to be shut down.
Diffstat (limited to 'include/mbgl')
-rw-r--r--include/mbgl/map/map.hpp14
-rw-r--r--include/mbgl/storage/default/request.hpp8
-rw-r--r--include/mbgl/storage/default/shared_request_base.hpp35
-rw-r--r--include/mbgl/storage/default_file_source.hpp17
-rw-r--r--include/mbgl/storage/file_source.hpp12
5 files changed, 57 insertions, 29 deletions
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index 8711aa3d08..00719aa382 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -36,11 +36,7 @@ class View;
class GlyphAtlas;
class SpriteAtlas;
class LineAtlas;
-
-struct exception : std::runtime_error {
- inline exception(const char *msg) : std::runtime_error(msg) {
- }
-};
+class Environment;
class Map : private util::noncopyable {
friend class View;
@@ -182,8 +178,8 @@ private:
Mode mode = Mode::None;
-public: // TODO: make private again
- std::unique_ptr<uv::loop> loop;
+ const std::unique_ptr<Environment> env;
+ View &view;
private:
std::unique_ptr<uv::worker> workers;
@@ -214,12 +210,8 @@ private:
// Stores whether the map thread has been stopped already.
std::atomic_bool isStopped;
- View &view;
-
-#ifdef DEBUG
const std::thread::id mainThread;
std::thread::id mapThread;
-#endif
Transform transform;
TransformState state;
diff --git a/include/mbgl/storage/default/request.hpp b/include/mbgl/storage/default/request.hpp
index 648585f304..b686d1fe90 100644
--- a/include/mbgl/storage/default/request.hpp
+++ b/include/mbgl/storage/default/request.hpp
@@ -15,13 +15,14 @@ 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, Callback callback);
+ Request(const Resource &resource, uv_loop_t *loop, const Environment &env, Callback callback);
public:
// May be called from any thread.
@@ -45,6 +46,11 @@ private:
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;
};
}
diff --git a/include/mbgl/storage/default/shared_request_base.hpp b/include/mbgl/storage/default/shared_request_base.hpp
index 2d56615608..59e38efc2f 100644
--- a/include/mbgl/storage/default/shared_request_base.hpp
+++ b/include/mbgl/storage/default/shared_request_base.hpp
@@ -4,11 +4,13 @@
#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;
@@ -45,20 +47,12 @@ public:
observers.insert(request);
}
- void unsubscribeAll() {
- MBGL_VERIFY_THREAD(tid);
-
- source = nullptr;
- observers.clear();
- cancel();
- }
-
void unsubscribe(Request *request) {
MBGL_VERIFY_THREAD(tid);
observers.erase(request);
- if (observers.empty()) {
+ if (abandoned()) {
// There are no observers anymore. We are initiating cancelation.
if (source) {
// First, remove this SharedRequestBase from the source.
@@ -70,6 +64,29 @@ public:
}
}
+ 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);
diff --git a/include/mbgl/storage/default_file_source.hpp b/include/mbgl/storage/default_file_source.hpp
index 86e2414041..14b4db6eff 100644
--- a/include/mbgl/storage/default_file_source.hpp
+++ b/include/mbgl/storage/default_file_source.hpp
@@ -20,11 +20,14 @@ class DefaultFileSource : public FileSource {
public:
DefaultFileSource(FileCache *cache, const std::string &root = "");
DefaultFileSource(FileCache *cache, uv_loop_t *loop, const std::string &root = "");
- ~DefaultFileSource();
+ ~DefaultFileSource() override;
- Request *request(const Resource &resource, uv_loop_t *loop, Callback callback);
- void cancel(Request *request);
- void request(const Resource &resource, Callback callback);
+ Request *request(const Resource &resource, uv_loop_t *loop, const Environment &env,
+ Callback callback) override;
+ void cancel(Request *request) override;
+ void request(const Resource &resource, const Environment &env, Callback callback) override;
+
+ void abort(const Environment &env) override;
enum class CacheHint : uint8_t { Full, Refresh, No };
void notify(SharedRequestBase *sharedRequest, const std::set<Request *> &observers,
@@ -39,14 +42,16 @@ private:
struct RemoveRequestAction;
struct ResultAction;
struct StopAction;
- using Action =
- mapbox::util::variant<AddRequestAction, RemoveRequestAction, ResultAction, 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);
diff --git a/include/mbgl/storage/file_source.hpp b/include/mbgl/storage/file_source.hpp
index 8517d6e4a6..30e88c39f6 100644
--- a/include/mbgl/storage/file_source.hpp
+++ b/include/mbgl/storage/file_source.hpp
@@ -15,6 +15,7 @@ typedef struct uv_loop_s uv_loop_t;
namespace mbgl {
class Request;
+class Environment;
class FileSource : private util::noncopyable {
protected:
@@ -27,12 +28,19 @@ public:
// These can be called from any thread. The callback will be invoked in the loop.
// You can only cancel a request from the same thread it was created in.
- virtual Request *request(const Resource &resource, uv_loop_t *loop, Callback callback) = 0;
+ virtual Request *request(const Resource &resource, uv_loop_t *loop, const Environment &env,
+ Callback callback) = 0;
virtual void cancel(Request *request) = 0;
// These can be called from any thread. The callback will be invoked in an arbitrary other thread.
// You cannot cancel these requests.
- virtual void request(const Resource &resource, Callback callback) = 0;
+ virtual void request(const Resource &resource, const Environment &env, Callback callback) = 0;
+
+ // This can be called from any thread. All requests with the environment pointer env should be
+ // notified as errored. Note that this is /different/ from canceling requests; a canceled
+ // request's callback is never called, while an aborted request's callback is called with
+ // a error message.
+ virtual void abort(const Environment &env) = 0;
};
}