[core] Introduce Pass<> class and use it for Scheduler
Thus we enforce client to retain the returned `Scheduler` objects.
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -45,6 +45,7 @@ add_compile_options(
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<NOT:$<PLATFORM_ID:Windows>>>:-Werror>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<PLATFORM_ID:Android>>:-Wno-error=tautological-constant-compare>
|
||||
$<$<CXX_COMPILER_ID:GNU>:-Wno-error=maybe-uninitialized>
|
||||
$<$<CXX_COMPILER_ID:GNU>:-Wno-error=return-type>
|
||||
$<$<CXX_COMPILER_ID:GNU>:-Wno-error=unknown-pragmas>
|
||||
$<$<CXX_COMPILER_ID:AppleClang>:-Wno-error=deprecated-declarations>
|
||||
$<$<CXX_COMPILER_ID:AppleClang>:-Wno-error=unused-parameter>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -38,11 +38,11 @@ std::shared_ptr<Scheduler> Scheduler::GetBackground() {
|
||||
weak = scheduler = std::make_shared<ThreadPool>();
|
||||
}
|
||||
|
||||
return scheduler;
|
||||
return PassRefPtr<Scheduler>(std::move(scheduler));
|
||||
}
|
||||
|
||||
// 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;
|
||||
@@ -65,7 +65,7 @@ std::shared_ptr<Scheduler> Scheduler::GetSequenced() {
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
return PassRefPtr<Scheduler>(std::move(result));
|
||||
}
|
||||
|
||||
} //namespace mbgl
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
EXPECT_EQ(shedulers.front(), std::shared_ptr<Scheduler>(Scheduler::GetSequenced()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user