diff --git a/platform/android/src/asset_manager_file_source.cpp b/platform/android/src/asset_manager_file_source.cpp index 6a3113d69..71e03f10b 100644 --- a/platform/android/src/asset_manager_file_source.cpp +++ b/platform/android/src/asset_manager_file_source.cpp @@ -1,8 +1,9 @@ #include "asset_manager_file_source.hpp" +#include #include #include -#include +#include #include #include @@ -12,10 +13,10 @@ namespace mbgl { class AssetManagerFileSource::Impl { public: - Impl(AAssetManager* assetManager_) : assetManager(assetManager_) { + Impl(ActorRef, AAssetManager* assetManager_) : assetManager(assetManager_) { } - void request(const std::string& url, FileSource::Callback callback) { + void request(const std::string& url, ActorRef req) { // Note: AssetManager already prepends "assets" to the filename. const std::string path = mbgl::util::percentDecode(url.substr(8)); @@ -30,7 +31,7 @@ public: "Could not read asset"); } - callback(response); + req.invoke(&FileSourceRequest::setResponse, response); } private: @@ -39,15 +40,18 @@ private: AssetManagerFileSource::AssetManagerFileSource(jni::JNIEnv& env, jni::Object assetManager_) : assetManager(assetManager_.NewGlobalRef(env)), - thread(std::make_unique>( - util::ThreadContext{"AssetManagerFileSource", util::ThreadPriority::Low}, - AAssetManager_fromJava(&env, jni::Unwrap(**assetManager)))) { + impl(std::make_unique>("AssetManagerFileSource", + AAssetManager_fromJava(&env, jni::Unwrap(**assetManager)))) { } AssetManagerFileSource::~AssetManagerFileSource() = default; std::unique_ptr AssetManagerFileSource::request(const Resource& resource, Callback callback) { - return thread->invokeWithCallback(&Impl::request, resource.url, callback); + auto req = std::make_unique(std::move(callback)); + + impl->actor().invoke(&Impl::request, resource.url, req->actor()); + + return std::move(req); } } // namespace mbgl diff --git a/platform/android/src/asset_manager_file_source.hpp b/platform/android/src/asset_manager_file_source.hpp index 7a447a2c6..9a86da6c4 100644 --- a/platform/android/src/asset_manager_file_source.hpp +++ b/platform/android/src/asset_manager_file_source.hpp @@ -9,7 +9,7 @@ namespace mbgl { namespace util { -template class Thread; +template class ThreadedObject; } // namespace util class AssetManagerFileSource : public FileSource { @@ -20,9 +20,10 @@ public: std::unique_ptr request(const Resource&, Callback) override; private: - jni::UniqueObject assetManager; class Impl; - std::unique_ptr> thread; + + jni::UniqueObject assetManager; + std::unique_ptr> impl; }; } // namespace mbgl diff --git a/platform/android/src/run_loop.cpp b/platform/android/src/run_loop.cpp index 49d28f2eb..9a63c9929 100644 --- a/platform/android/src/run_loop.cpp +++ b/platform/android/src/run_loop.cpp @@ -1,9 +1,8 @@ #include "run_loop_impl.hpp" #include -#include -#include #include +#include #include #include @@ -62,9 +61,13 @@ namespace util { // timeout, but on the main thread `ALooper_pollAll` is called by the activity // automatically, thus we cannot set the timeout. Instead we wake the loop // with an external file descriptor event coming from this thread. +// +// Usually an actor should not carry pointers to other threads, but in +// this case the RunLoop itself owns the Alarm and calling wake() is the most +// efficient way of waking up the RunLoop and it is also thread-safe. class Alarm { public: - Alarm(RunLoop::Impl* loop_) : loop(loop_) {} + Alarm(ActorRef, RunLoop::Impl* loop_) : loop(loop_) {} void set(const Milliseconds& timeout) { alarm.start(timeout, mbgl::Duration::zero(), [this]() { loop->wake(); }); @@ -102,7 +105,7 @@ RunLoop::Impl::Impl(RunLoop* runLoop_, RunLoop::Type type) : runLoop(runLoop_) { case Type::Default: ret = ALooper_addFd(loop, fds[PIPE_OUT], ALOOPER_POLL_CALLBACK, ALOOPER_EVENT_INPUT, looperCallbackDefault, this); - alarm = std::make_unique>(ThreadContext{"Alarm"}, this); + alarm = std::make_unique>("Alarm", this); running = true; break; } @@ -190,7 +193,7 @@ Milliseconds RunLoop::Impl::processRunnables() { auto timeout = std::chrono::duration_cast(nextDue - now); if (alarm) { - alarm->invoke(&Alarm::set, timeout); + alarm->actor().invoke(&Alarm::set, timeout); } return timeout; diff --git a/platform/android/src/run_loop_impl.hpp b/platform/android/src/run_loop_impl.hpp index 15cbfa14a..1706051be 100644 --- a/platform/android/src/run_loop_impl.hpp +++ b/platform/android/src/run_loop_impl.hpp @@ -15,7 +15,7 @@ struct ALooper; namespace mbgl { namespace util { -template class Thread; +template class ThreadedObject; class Alarm; class RunLoop::Impl { @@ -53,7 +53,7 @@ private: JNIEnv *env = nullptr; bool detach = false; - std::unique_ptr> alarm; + std::unique_ptr> alarm; std::recursive_mutex mtx; std::list runnables;