Add CachingHTTPFileSource::clearLoop()

So loop state can be cleaned up in the appropriate thread.
This is a hack; loop needs to be externalized from Map.

Fixes #686
This commit is contained in:
John Firebaugh
2014-12-04 12:09:27 -08:00
parent 16fe8e64c4
commit 36500b9f95
4 changed files with 27 additions and 19 deletions

View File

@@ -21,6 +21,7 @@ public:
// Stores and checks the libuv loop for requests
void setLoop(uv_loop_t*);
bool hasLoop();
void clearLoop();
// Stores and retrieves the base path/URL for relative requests
void setBase(const std::string &value);

View File

@@ -16,8 +16,11 @@ namespace mbgl {
class FileSource : public util::noncopyable {
public:
virtual ~FileSource() = default;
virtual void setLoop(uv_loop_t*) = 0;
virtual bool hasLoop() = 0;
virtual void clearLoop() = 0;
virtual void setBase(const std::string &value) = 0;
virtual std::unique_ptr<Request> request(ResourceType type, const std::string &url) = 0;
virtual void prepare(std::function<void()> fn) = 0;

View File

@@ -151,6 +151,8 @@ void Map::start() {
workers.reset();
activeSources.clear();
fileSource.clearLoop();
// Closes all open handles on the loop. This means that the loop will automatically terminate.
asyncCleanup.reset();
asyncRender.reset();
@@ -310,10 +312,7 @@ void Map::setStyleJSON(std::string newStyleJSON, const std::string &base) {
style = std::make_shared<Style>();
}
style->loadJSON((const uint8_t *)styleJSON.c_str());
if (!fileSource.hasLoop()) {
fileSource.setLoop(**loop);
glyphStore = std::make_shared<GlyphStore>(fileSource);
}
glyphStore = std::make_shared<GlyphStore>(fileSource);
fileSource.setBase(base);
glyphStore->setURL(util::mapbox::normalizeGlyphsURL(style->glyph_url, getAccessToken()));
update();

View File

@@ -13,21 +13,6 @@ CachingHTTPFileSource::CachingHTTPFileSource(const std::string &path_)
: path(path_) {}
CachingHTTPFileSource::~CachingHTTPFileSource() {
if (hasLoop()) {
assert(thread_id == std::this_thread::get_id());
uv_messenger_stop(queue, [](uv_messenger_t *msgr) {
delete msgr;
});
util::ptr<BaseRequest> req;
// Send a cancel() message to all requests that we are still holding.
for (const std::pair<std::string, std::weak_ptr<BaseRequest>> &pair : pending) {
if ((req = pair.second.lock())) {
req->cancel();
}
}
}
}
void CachingHTTPFileSource::setLoop(uv_loop_t* loop_) {
@@ -47,6 +32,26 @@ bool CachingHTTPFileSource::hasLoop() {
return loop;
}
void CachingHTTPFileSource::clearLoop() {
assert(thread_id == std::this_thread::get_id());
assert(loop);
uv_messenger_stop(queue, [](uv_messenger_t *msgr) {
delete msgr;
});
util::ptr<BaseRequest> req;
// Send a cancel() message to all requests that we are still holding.
for (const std::pair<std::string, std::weak_ptr<BaseRequest>> &pair : pending) {
if ((req = pair.second.lock())) {
req->cancel();
}
}
store.reset();
}
void CachingHTTPFileSource::setBase(const std::string &value) {
assert(thread_id == std::this_thread::get_id());
base = value;