[core] Add Scheduler::scheduleAndReplyValue() API
This commit is contained in:
@@ -50,6 +50,18 @@ public:
|
||||
// first invoked, the call is ignored.
|
||||
std::function<void()> bindOnce(std::function<void()>);
|
||||
|
||||
// Enqueues the given |task| for execution into this scheduler's task queue and
|
||||
// then enqueues the |reply| with the captured task result to the current
|
||||
// task queue.
|
||||
//
|
||||
// The |TaskFn| return type must be compatible with the |ReplyFn| argument type.
|
||||
// Note: the task result is copied and passed by value.
|
||||
template <typename TaskFn, typename ReplyFn>
|
||||
void scheduleAndReplyValue(const TaskFn& task, const ReplyFn& reply) {
|
||||
assert(GetCurrent());
|
||||
scheduleAndReplyValue(task, reply, GetCurrent()->makeWeakPtr());
|
||||
}
|
||||
|
||||
// Set/Get the current Scheduler for this thread
|
||||
static Scheduler* GetCurrent();
|
||||
static void SetCurrent(Scheduler*);
|
||||
@@ -58,6 +70,21 @@ public:
|
||||
// will lazily initialize a shared worker pool when ran
|
||||
// from the first time.
|
||||
static std::shared_ptr<Scheduler> GetBackground();
|
||||
|
||||
protected:
|
||||
template <typename TaskFn, typename ReplyFn>
|
||||
void scheduleAndReplyValue(const TaskFn& task,
|
||||
const ReplyFn& reply,
|
||||
mapbox::base::WeakPtr<Scheduler> replyScheduler) {
|
||||
auto scheduled = [replyScheduler, task, reply] {
|
||||
auto lock = replyScheduler.lock();
|
||||
if (!replyScheduler) return;
|
||||
auto scheduledReply = [reply, result = task()] { reply(result); };
|
||||
replyScheduler->schedule(std::move(scheduledReply));
|
||||
};
|
||||
|
||||
schedule(std::move(scheduled));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -60,11 +60,11 @@ private:
|
||||
static_assert(N > 0, "Thread count must be more than zero.");
|
||||
};
|
||||
|
||||
using SequencedScheduler = ThreadedScheduler<1>;
|
||||
class SequencedScheduler : public ThreadedScheduler<1> {};
|
||||
|
||||
template <std::size_t extra>
|
||||
using ParallelScheduler = ThreadedScheduler<1 + extra>;
|
||||
|
||||
using ThreadPool = ParallelScheduler<3>;
|
||||
class ThreadPool : public ParallelScheduler<3> {};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -151,3 +151,22 @@ TEST(AsyncTask, ThreadSafety) {
|
||||
// a valid result, although very unlikely (I hope).
|
||||
EXPECT_GT(count, 0u);
|
||||
}
|
||||
|
||||
TEST(AsyncTask, scheduleAndReplyValue) {
|
||||
RunLoop loop;
|
||||
std::thread::id caller_id = std::this_thread::get_id();
|
||||
|
||||
auto runInBackground = [caller_id]() -> int {
|
||||
EXPECT_NE(caller_id, std::this_thread::get_id());
|
||||
return 42;
|
||||
};
|
||||
auto onResult = [caller_id, &loop](int res) {
|
||||
EXPECT_EQ(caller_id, std::this_thread::get_id());
|
||||
EXPECT_EQ(42, res);
|
||||
loop.stop();
|
||||
};
|
||||
|
||||
auto sheduler = Scheduler::GetBackground();
|
||||
sheduler->scheduleAndReplyValue(runInBackground, onResult);
|
||||
loop.run();
|
||||
}
|
||||
Reference in New Issue
Block a user