summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer/image_manager.cpp
diff options
context:
space:
mode:
authorAlexander Shalamov <alexander.shalamov@mapbox.com>2019-05-09 10:49:10 +0300
committerAlexander Shalamov <alexander.shalamov@mapbox.com>2019-05-09 20:45:06 +0300
commita53c4593d64bbe23a34b0ade142c94d09f64b02c (patch)
tree1fd9053112a06a96ff398a4bd2cc6a0d6faea659 /src/mbgl/renderer/image_manager.cpp
parent6fa1d357b384fd347c5a7a83586cd923128ff52e (diff)
downloadqtlocation-mapboxgl-a53c4593d64bbe23a34b0ade142c94d09f64b02c.tar.gz
[core] Schedule invocation of onStyleImageMissing completion callback on the same thread
Before this change, ImageManger's 'done' callback for onStyleImageMissing observer notification that was created on renderer thread, could be called from different thread, therefore, is not thread safe. For example, on Android platform, callback was invoked from UI thread. This change makes callback to be scheduled on originating thread.
Diffstat (limited to 'src/mbgl/renderer/image_manager.cpp')
-rw-r--r--src/mbgl/renderer/image_manager.cpp28
1 files changed, 20 insertions, 8 deletions
diff --git a/src/mbgl/renderer/image_manager.cpp b/src/mbgl/renderer/image_manager.cpp
index 8e584ffd34..860de487e7 100644
--- a/src/mbgl/renderer/image_manager.cpp
+++ b/src/mbgl/renderer/image_manager.cpp
@@ -1,4 +1,6 @@
#include <mbgl/renderer/image_manager.hpp>
+#include <mbgl/actor/actor.hpp>
+#include <mbgl/actor/scheduler.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/gfx/context.hpp>
#include <mbgl/renderer/image_manager_observer.hpp>
@@ -128,7 +130,7 @@ void ImageManager::removeRequestor(ImageRequestor& requestor) {
void ImageManager::notifyIfMissingImageAdded() {
for (auto it = missingImageRequestors.begin(); it != missingImageRequestors.end();) {
- if (it->second.callbacksRemaining == 0) {
+ if (it->second.callbacks.empty()) {
notify(*it->first, it->second.pair);
it = missingImageRequestors.erase(it);
} else {
@@ -162,19 +164,29 @@ void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageR
if (missing > 0) {
ImageRequestor* requestorPtr = &requestor;
- missingImageRequestors.emplace(requestorPtr, MissingImageRequestPair { std::move(pair), missing });
+ auto emplaced = missingImageRequestors.emplace(requestorPtr, MissingImageRequestPair { pair, {} });
+ assert(emplaced.second);
for (const auto& dependency : pair.first) {
auto it = images.find(dependency.first);
if (it == images.end()) {
assert(observer != nullptr);
- observer->onStyleImageMissing(dependency.first, [this, requestorPtr]() {
- auto requestorIt = missingImageRequestors.find(requestorPtr);
- if (requestorIt != missingImageRequestors.end()) {
- assert(requestorIt->second.callbacksRemaining > 0);
- requestorIt->second.callbacksRemaining--;
- }
+ auto callback = std::make_unique<ActorCallback>(
+ *Scheduler::GetCurrent(),
+ [this, requestorPtr, imageId = dependency.first] {
+ auto requestorIt = missingImageRequestors.find(requestorPtr);
+ if (requestorIt != missingImageRequestors.end()) {
+ assert(requestorIt->second.callbacks.find(imageId) != requestorIt->second.callbacks.end());
+ requestorIt->second.callbacks.erase(imageId);
+ }
+ });
+
+ auto actorRef = callback->self();
+ emplaced.first->second.callbacks.emplace(dependency.first, std::move(callback));
+ observer->onStyleImageMissing(dependency.first, [actorRef]() mutable {
+ actorRef.invoke(&Callback::operator());
});
+
}
}