diff options
author | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2019-12-02 10:40:59 +0200 |
---|---|---|
committer | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2019-12-02 11:06:58 +0200 |
commit | 23523621fd44135102bd6e0ceea9a392eaebaae3 (patch) | |
tree | 172657739f55d069522197ab0f80a7712a375cda | |
parent | 3947d5fa98263d3b2b4b319b4f6629daca8c91ff (diff) | |
download | qtlocation-mapboxgl-upstream/mikhail_pass_aux_class.tar.gz |
[core] Introduce Pass<> class and use it for Schedulerupstream/mikhail_pass_aux_class
Thus we enforce client to retain the returned `Scheduler` objects.
-rw-r--r-- | include/mbgl/actor/scheduler.hpp | 21 | ||||
-rw-r--r-- | src/mbgl/actor/scheduler.cpp | 4 | ||||
-rw-r--r-- | test/actor/actor.test.cpp | 2 | ||||
-rw-r--r-- | test/util/async_task.test.cpp | 14 |
4 files changed, 29 insertions, 12 deletions
diff --git a/include/mbgl/actor/scheduler.hpp b/include/mbgl/actor/scheduler.hpp index 04cbc389e5..d7fec41ea6 100644 --- a/include/mbgl/actor/scheduler.hpp +++ b/include/mbgl/actor/scheduler.hpp @@ -9,6 +9,23 @@ namespace mbgl { class Mailbox; +// Using this type as a return type enforces the client to retain the returned object. +// TODO: Move to a separate file if/when other clients for this aux API turn up. +template <typename T> +class Pass { +public: + Pass(T&& obj_) : obj(std::forward<T>(obj_)) {} + Pass(Pass&&) = default; + Pass(const Pass&) = delete; + operator T() && { return std::move(obj); } + +private: + T obj; +}; + +template <typename T> +using PassRefPtr = Pass<std::shared_ptr<T>>; + /* A `Scheduler` is responsible for coordinating the processing of messages by one or more actors via their mailboxes. It's an abstract interface. Currently, @@ -72,7 +89,7 @@ public: // The scheduled tasks might run in parallel on different // threads. // TODO : Rename to GetPool() - static std::shared_ptr<Scheduler> GetBackground(); + static PassRefPtr<Scheduler> GetBackground(); // Get the *sequenced* scheduler for asynchronous tasks. // Unlike the method above, the returned scheduler @@ -82,7 +99,7 @@ public: // // Sequenced scheduler can be used for running tasks // on the same thread-unsafe object. - static std::shared_ptr<Scheduler> GetSequenced(); + static PassRefPtr<Scheduler> GetSequenced(); protected: template <typename TaskFn, typename ReplyFn> diff --git a/src/mbgl/actor/scheduler.cpp b/src/mbgl/actor/scheduler.cpp index 0e051d0273..c9e258b50a 100644 --- a/src/mbgl/actor/scheduler.cpp +++ b/src/mbgl/actor/scheduler.cpp @@ -27,7 +27,7 @@ Scheduler* Scheduler::GetCurrent() { } // static -std::shared_ptr<Scheduler> Scheduler::GetBackground() { +PassRefPtr<Scheduler> Scheduler::GetBackground() { static std::weak_ptr<Scheduler> weak; static std::mutex mtx; @@ -42,7 +42,7 @@ std::shared_ptr<Scheduler> Scheduler::GetBackground() { } // static -std::shared_ptr<Scheduler> Scheduler::GetSequenced() { +PassRefPtr<Scheduler> Scheduler::GetSequenced() { const std::size_t kSchedulersCount = 10; static std::vector<std::weak_ptr<Scheduler>> weaks(kSchedulersCount); static std::mutex mtx; diff --git a/test/actor/actor.test.cpp b/test/actor/actor.test.cpp index c2a41fe787..03eb9b8301 100644 --- a/test/actor/actor.test.cpp +++ b/test/actor/actor.test.cpp @@ -156,7 +156,7 @@ TEST(Actor, DestructionAllowedInReceiveOnSameThread) { }; std::promise<void> callbackFiredPromise; - auto retainer = Scheduler::GetBackground(); + std::shared_ptr<Scheduler> retainer = Scheduler::GetBackground(); auto test = std::make_unique<Actor<Test>>(retainer); // Callback (triggered while mutex is locked in Mailbox::receive()) diff --git a/test/util/async_task.test.cpp b/test/util/async_task.test.cpp index 8c79c51405..e2f988751e 100644 --- a/test/util/async_task.test.cpp +++ b/test/util/async_task.test.cpp @@ -105,7 +105,7 @@ TEST(AsyncTask, RequestCoalescingMultithreaded) { unsigned count = 0, numThreads = 25; AsyncTask async([&count] { ++count; }); - auto retainer = Scheduler::GetBackground(); + std::shared_ptr<Scheduler> retainer = Scheduler::GetBackground(); auto mailbox = std::make_shared<Mailbox>(*retainer); TestWorker worker(&async); @@ -134,7 +134,7 @@ TEST(AsyncTask, ThreadSafety) { AsyncTask async([&count] { ++count; }); - auto retainer = Scheduler::GetBackground(); + std::shared_ptr<Scheduler> retainer = Scheduler::GetBackground(); auto mailbox = std::make_shared<Mailbox>(*retainer); TestWorker worker(&async); @@ -166,7 +166,7 @@ TEST(AsyncTask, scheduleAndReplyValue) { loop.stop(); }; - auto sheduler = Scheduler::GetBackground(); + std::shared_ptr<Scheduler> sheduler = Scheduler::GetBackground(); sheduler->scheduleAndReplyValue(runInBackground, onResult); loop.run(); } @@ -194,7 +194,7 @@ TEST(AsyncTask, SequencedScheduler) { loop.stop(); }; - auto sheduler = Scheduler::GetSequenced(); + std::shared_ptr<Scheduler> sheduler = Scheduler::GetSequenced(); sheduler->schedule(first); sheduler->schedule(second); @@ -206,10 +206,10 @@ TEST(AsyncTask, MultipleSequencedSchedulers) { std::vector<std::shared_ptr<Scheduler>> shedulers; for (int i = 0; i < 10; ++i) { - auto scheduler = Scheduler::GetSequenced(); + std::shared_ptr<Scheduler> scheduler = Scheduler::GetSequenced(); EXPECT_TRUE(std::none_of( shedulers.begin(), shedulers.end(), [&scheduler](const auto &item) { return item == scheduler; })); shedulers.emplace_back(std::move(scheduler)); } - EXPECT_EQ(shedulers.front(), Scheduler::GetSequenced()); -}
\ No newline at end of file + EXPECT_EQ(shedulers.front(), std::shared_ptr<Scheduler>(Scheduler::GetSequenced())); +} |