summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2014-09-30 17:28:42 +0200
committerKonstantin Käfer <mail@kkaefer.com>2014-09-30 17:29:10 +0200
commit8fcc74e2531f53b6e09584fb58022f852a32b26c (patch)
treed2575142d5d82a32f03d2ce9ad3f501e8bc8bb76
parenta9039cf5d75f4da667d9279d61f7549c43f7ea51 (diff)
downloadqtlocation-mapboxgl-8fcc74e2531f53b6e09584fb58022f852a32b26c.tar.gz
fix headless tests
-rw-r--r--common/headless_view.cpp4
-rw-r--r--common/headless_view.hpp1
-rw-r--r--include/mbgl/map/tile_data.hpp2
-rw-r--r--include/mbgl/util/uv-worker.h2
-rw-r--r--src/map/map.cpp17
-rw-r--r--src/map/vector_tile_data.cpp16
-rw-r--r--src/storage/file_source.cpp3
-rw-r--r--src/storage/http_request.cpp14
-rw-r--r--src/storage/sqlite_store.cpp2
-rw-r--r--src/util/uv-worker.c28
-rw-r--r--test/fixtures/fixture_request.cpp115
11 files changed, 102 insertions, 102 deletions
diff --git a/common/headless_view.cpp b/common/headless_view.cpp
index ed00f48e82..ace41d38c0 100644
--- a/common/headless_view.cpp
+++ b/common/headless_view.cpp
@@ -163,6 +163,10 @@ HeadlessView::~HeadlessView() {
#endif
}
+void HeadlessView::notify() {
+ // no-op
+}
+
void HeadlessView::notify_map_change(mbgl::MapChange /*change*/, mbgl::timestamp /*delay*/) {
// no-op
}
diff --git a/common/headless_view.hpp b/common/headless_view.hpp
index a8ce4aa325..42f9c46da2 100644
--- a/common/headless_view.hpp
+++ b/common/headless_view.hpp
@@ -21,6 +21,7 @@ public:
void resize(uint16_t width, uint16_t height, float pixelRatio);
+ void notify();
void notify_map_change(MapChange change, timestamp delay = 0);
void make_active();
void swap();
diff --git a/include/mbgl/map/tile_data.hpp b/include/mbgl/map/tile_data.hpp
index 07cf19c5c8..823523679a 100644
--- a/include/mbgl/map/tile_data.hpp
+++ b/include/mbgl/map/tile_data.hpp
@@ -41,7 +41,7 @@ public:
public:
TileData(Tile::ID id, Map &map, const util::ptr<SourceInfo> &source);
- ~TileData();
+ virtual ~TileData();
void request();
void cancel();
diff --git a/include/mbgl/util/uv-worker.h b/include/mbgl/util/uv-worker.h
index a9c9aff500..eff1169a2b 100644
--- a/include/mbgl/util/uv-worker.h
+++ b/include/mbgl/util/uv-worker.h
@@ -21,11 +21,13 @@ struct uv_worker_s {
#ifndef NDEBUG
unsigned long thread_id;
#endif
+ uv_loop_t *loop;
uv_messenger_t *msgr;
uv_chan_t chan;
const char *name;
int count;
uv_worker_close_cb close_cb;
+ int active;
};
int uv_worker_init(uv_worker_t *worker, uv_loop_t *loop, int count, const char *name);
diff --git a/src/map/map.cpp b/src/map/map.cpp
index f71ecdb270..4b797ceae3 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -58,6 +58,15 @@ Map::~Map() {
if (async) {
stop();
}
+
+ // Explicitly reset all pointers.
+ texturepool.reset();
+ sprite.reset();
+ spriteAtlas.reset();
+ glyphStore.reset();
+ glyphAtlas.reset();
+ style.reset();
+ fileSource.reset();
}
uv::worker &Map::getWorker() {
@@ -265,8 +274,14 @@ void Map::setStyleJSON(std::string newStyleJSON, const std::string &base) {
// TODO: Make threadsafe.
styleJSON.swap(newStyleJSON);
sprite.reset();
- assert(style);
+ if (!style) {
+ style = std::make_shared<Style>();
+ }
style->loadJSON((const uint8_t *)styleJSON.c_str());
+ if (!fileSource) {
+ fileSource = std::make_shared<FileSource>(**loop, platform::defaultCacheDatabase());
+ glyphStore = std::make_shared<GlyphStore>(fileSource);
+ }
fileSource->setBase(base);
glyphStore->setURL(util::mapbox::normalizeGlyphsURL(style->glyph_url, getAccessToken()));
update();
diff --git a/src/map/vector_tile_data.cpp b/src/map/vector_tile_data.cpp
index e34ed94188..48b46059a5 100644
--- a/src/map/vector_tile_data.cpp
+++ b/src/map/vector_tile_data.cpp
@@ -30,18 +30,18 @@ void VectorTileData::parse() {
return;
}
-// try {
+ try {
// Parsing creates state that is encapsulated in TileParser. While parsing,
// the TileParser object writes results into this objects. All other state
// is going to be discarded afterwards.
parser->parse();
-// } catch (const std::exception& ex) {
-//#if defined(DEBUG)
-// fprintf(stderr, "[%p] exception [%d/%d/%d]... failed: %s\n", this, id.z, id.x, id.y, ex.what());
-//#endif
-// cancel();
-// return;
-// }
+ } catch (const std::exception& ex) {
+#if defined(DEBUG)
+ fprintf(stderr, "[%p] exception [%d/%d/%d]... failed: %s\n", this, id.z, id.x, id.y, ex.what());
+#endif
+ cancel();
+ return;
+ }
if (state != State::obsolete) {
state = State::parsed;
diff --git a/src/storage/file_source.cpp b/src/storage/file_source.cpp
index 370e36f2e0..12d924416c 100644
--- a/src/storage/file_source.cpp
+++ b/src/storage/file_source.cpp
@@ -10,7 +10,7 @@ namespace mbgl {
FileSource::FileSource(uv_loop_t *loop_, const std::string &path)
: thread_id(uv_thread_self()),
- store(util::ptr<SQLiteStore>(new SQLiteStore(loop_, path))),
+ store(!path.empty() ? util::ptr<SQLiteStore>(new SQLiteStore(loop_, path)) : nullptr),
loop(loop_),
queue(new uv_messenger_t) {
@@ -18,6 +18,7 @@ FileSource::FileSource(uv_loop_t *loop_, const std::string &path)
std::unique_ptr<std::function<void()>> fn { reinterpret_cast<std::function<void()> *>(ptr) };
(*fn)();
});
+ uv_unref((uv_handle_t *)&queue->async);
}
FileSource::~FileSource() {
diff --git a/src/storage/http_request.cpp b/src/storage/http_request.cpp
index 4a35dcc510..1b799d4895 100644
--- a/src/storage/http_request.cpp
+++ b/src/storage/http_request.cpp
@@ -22,7 +22,11 @@ struct CacheRequestBaton {
HTTPRequest::HTTPRequest(ResourceType type_, const std::string &path, uv_loop_t *loop_, util::ptr<SQLiteStore> store_)
: BaseRequest(path), thread_id(uv_thread_self()), loop(loop_), store(store_), type(type_) {
- startCacheRequest();
+ if (store) {
+ startCacheRequest();
+ } else {
+ startHTTPRequest(nullptr);
+ }
}
void HTTPRequest::startCacheRequest() {
@@ -159,14 +163,18 @@ void HTTPRequest::handleHTTPResponse(HTTPResponseType responseType, std::unique_
// The request returned data successfully. We retrieved and decoded the data successfully.
case HTTPResponseType::Successful:
- store->put(path, type, *res);
+ if (store) {
+ store->put(path, type, *res);
+ }
response = std::move(res);
notify();
break;
// The request confirmed that the data wasn't changed. We already have the data.
case HTTPResponseType::NotModified:
- store->updateExpiration(path, res->expires);
+ if (store) {
+ store->updateExpiration(path, res->expires);
+ }
response = std::move(res);
notify();
break;
diff --git a/src/storage/sqlite_store.cpp b/src/storage/sqlite_store.cpp
index 043c62a514..763100f411 100644
--- a/src/storage/sqlite_store.cpp
+++ b/src/storage/sqlite_store.cpp
@@ -58,7 +58,7 @@ namespace mbgl {
SQLiteStore::SQLiteStore(uv_loop_t *loop, const std::string &path)
: thread_id(uv_thread_self()),
- db(!path.empty() ? std::make_shared<Database>(path.c_str(), ReadWrite | Create) : nullptr) {
+ db(std::make_shared<Database>(path.c_str(), ReadWrite | Create)) {
createSchema();
worker = new uv_worker_t;
uv_worker_init(worker, loop, 1, "SQLite");
diff --git a/src/util/uv-worker.c b/src/util/uv-worker.c
index f6122879f0..275989a752 100644
--- a/src/util/uv-worker.c
+++ b/src/util/uv-worker.c
@@ -6,6 +6,7 @@
typedef struct uv__worker_item_s uv__worker_item_t;
struct uv__worker_item_s {
+ uv_worker_t *worker;
void *data;
uv_worker_cb work_cb;
uv_worker_after_cb after_work_cb;
@@ -46,8 +47,14 @@ void uv__worker_after(void *ptr) {
if (item->work_cb) {
// We are finishing a regular work request.
- assert(item->after_work_cb);
- item->after_work_cb(item->data);
+ if (item->after_work_cb) {
+ assert(item->after_work_cb);
+ item->after_work_cb(item->data);
+ }
+ assert(item->worker->active > 0);
+ if (--item->worker->active == 0) {
+ uv_unref((uv_handle_t *)&item->worker->msgr->async);
+ }
} else {
// This is a worker thread termination.
uv__worker_thread_t *worker_thread = (uv__worker_thread_t *)item->data;
@@ -73,13 +80,8 @@ void uv__worker_thread_loop(void *ptr) {
assert(item->work_cb);
item->work_cb(item->data);
- if (item->after_work_cb) {
- // Trigger the after callback in the main thread.
- uv_messenger_send(worker->msgr, item);
- } else {
- // There is no after work callback, so it wouldn't do anything anyway.
- free(item);
- }
+ // Trigger the after callback in the main thread.
+ uv_messenger_send(worker->msgr, item);
}
// Make sure to close all other workers too.
@@ -97,9 +99,11 @@ int uv_worker_init(uv_worker_t *worker, uv_loop_t *loop, int count, const char *
#ifndef NDEBUG
worker->thread_id = uv_thread_self();
#endif
+ worker->loop = loop;
worker->name = name;
worker->count = 0;
worker->close_cb = NULL;
+ worker->active = 0;
worker->msgr = (uv_messenger_t *)malloc(sizeof(uv_messenger_t));
int ret = uv_messenger_init(loop, worker->msgr, uv__worker_after);
if (ret < 0) {
@@ -133,10 +137,12 @@ void uv_worker_send(uv_worker_t *worker, void *data, uv_worker_cb work_cb,
assert(work_cb);
uv__worker_item_t *item = (uv__worker_item_t *)malloc(sizeof(uv__worker_item_t));
+ item->worker = worker;
item->work_cb = work_cb;
item->after_work_cb = after_work_cb;
item->data = data;
uv_chan_send(&worker->chan, item);
+ worker->active++;
}
void uv_worker_close(uv_worker_t *worker, uv_worker_close_cb close_cb) {
@@ -149,4 +155,8 @@ void uv_worker_close(uv_worker_t *worker, uv_worker_close_cb close_cb) {
worker->close_cb = close_cb;
uv_chan_send(&worker->chan, NULL);
+ assert(worker->active >= 0);
+ if (worker->active++ == 0) {
+ uv_ref((uv_handle_t *)&worker->msgr->async);
+ }
}
diff --git a/test/fixtures/fixture_request.cpp b/test/fixtures/fixture_request.cpp
index 7e351ecfac..3f72b890db 100644
--- a/test/fixtures/fixture_request.cpp
+++ b/test/fixtures/fixture_request.cpp
@@ -1,9 +1,15 @@
-#include <mbgl/platform/platform.hpp>
-#include <mbgl/platform/request.hpp>
-#include <mbgl/util/uv_detail.hpp>
+#include <mbgl/storage/http_request_baton.hpp>
+#include <mbgl/storage/file_request_baton.hpp>
+#include <mbgl/storage/response.hpp>
#include <mbgl/util/url.hpp>
+#include <mbgl/util/std.hpp>
#include <mbgl/platform/log.hpp>
+#include <uv.h>
+
+#include <cassert>
+
+
const std::string base_directory = []{
std::string fn = __FILE__;
fn.erase(fn.find_last_of("/"));
@@ -12,95 +18,48 @@ const std::string base_directory = []{
return fn + "/node_modules/mapbox-gl-test-suite/";
}();
-
namespace mbgl {
-std::shared_ptr<platform::Request>
-platform::request_http(const std::string &url,
- std::function<void(Response *)> callback,
- std::shared_ptr<uv::loop> loop) {
- uv_loop_t *l = nullptr;
- if (loop) {
- l = **loop;
- } else {
- l = uv_default_loop();
- }
+void HTTPRequestBaton::start(const util::ptr<HTTPRequestBaton> &baton) {
+ assert(uv_thread_self() == baton->thread_id);
- std::string clean_url = util::percentDecode(url);
+ std::string clean_url = util::percentDecode(baton->path);
if (clean_url.find("local://") == 0) {
clean_url = base_directory + clean_url.substr(8);
}
- std::shared_ptr<Request> req = std::make_shared<Request>(url, callback, loop);
-
- int err;
-
- uv_fs_t open_req;
- err = uv_fs_open(l, &open_req, clean_url.c_str(), O_RDONLY, S_IRUSR, nullptr);
- uv_fs_req_cleanup(&open_req);
- if (err < 0) {
- req->res->code = err;
- req->res->error_message = uv_strerror(err);
- Log::Warning(Event::HttpRequest, err, url + ": " + uv_strerror(err));
- req->complete();
- return req;
- }
- uv_file fd = err;
-
- uv_fs_t stat_req;
- uv_fs_fstat(l, &stat_req, fd, nullptr);
- uv_fs_req_cleanup(&stat_req);
- err = uv_fs_fstat(l, &stat_req, fd, nullptr);
- if (err < 0) {
- req->res->code = err;
- req->res->error_message = uv_strerror(err);
- Log::Warning(Event::HttpRequest, err, url + ": " + uv_strerror(err));
- req->complete();
- return req;
- }
-
- const uint64_t size = static_cast<const uv_stat_t*>(stat_req.ptr)->st_size;
-
-
- std::string body;
- body.resize(size);
- uv_buf_t uvbuf = uv_buf_init(const_cast<char *>(body.data()), body.size());
-
- uv_fs_t read_req;
- err = uv_fs_read(l, &read_req, fd, &uvbuf, 1, 0, nullptr);
- uv_fs_req_cleanup(&read_req);
- if (err < 0) {
- req->res->code = err;
- req->res->error_message = uv_strerror(err);
- Log::Warning(Event::HttpRequest, err, url + ": " + uv_strerror(err));
- req->complete();
- return req;
+ baton->response = std::make_unique<Response>();
+ FILE *file = fopen(clean_url.c_str(),"rb");
+ if (file != NULL) {
+ fseek(file, 0, SEEK_END);
+ const size_t size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+ baton->response->data.resize(size);
+ fread(&baton->response->data[0], size, 1, file);
+ fclose(file);
+
+ baton->response->code = 200;
+ baton->type = HTTPResponseType::Successful;
+ } else {
+ baton->type = HTTPResponseType::PermanentError;
+ baton->response->code = 404;
}
+ uv_async_send(baton->async);
+}
- uv_fs_t close_req;
- err = uv_fs_close(l, &close_req, fd, nullptr);
- uv_fs_req_cleanup(&close_req);
- if (err < 0) {
- req->res->code = err;
- req->res->error_message = uv_strerror(err);
- Log::Warning(Event::HttpRequest, err, url + ": " + uv_strerror(err));
- req->complete();
- return req;
- }
+void HTTPRequestBaton::stop(const util::ptr<HTTPRequestBaton> &baton) {
+ fprintf(stderr, "HTTP request cannot be canceled because it is answered immediately");
+ abort();
+}
- req->res->body.swap(body);
- req->res->code = 200;
- Log::Info(Event::HttpRequest, 200, url);
- req->complete();
+namespace platform {
- return req;
+std::string defaultCacheDatabase() {
+ // Disables the cache.
+ return "";
}
-void platform::cancel_request_http(const std::shared_ptr<Request> &req) {
- if (req) {
- req->cancelled = true;
- }
}
}