[core] Use an actor model for tile worker concurrency
This commit is contained in:
55
src/mbgl/actor/mailbox.cpp
Normal file
55
src/mbgl/actor/mailbox.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <mbgl/actor/mailbox.hpp>
|
||||
#include <mbgl/actor/message.hpp>
|
||||
#include <mbgl/actor/scheduler.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
Mailbox::Mailbox(Scheduler& scheduler_)
|
||||
: scheduler(scheduler_) {
|
||||
}
|
||||
|
||||
void Mailbox::push(std::unique_ptr<Message> message) {
|
||||
assert(!closing);
|
||||
|
||||
std::lock_guard<std::mutex> queueLock(queueMutex);
|
||||
bool wasEmpty = queue.empty();
|
||||
queue.push(std::move(message));
|
||||
if (wasEmpty) {
|
||||
scheduler.schedule(shared_from_this());
|
||||
}
|
||||
}
|
||||
|
||||
void Mailbox::close() {
|
||||
// Block until the scheduler is guaranteed not to be executing receive().
|
||||
std::lock_guard<std::mutex> closingLock(closingMutex);
|
||||
closing = true;
|
||||
}
|
||||
|
||||
void Mailbox::receive() {
|
||||
std::lock_guard<std::mutex> closingLock(closingMutex);
|
||||
|
||||
if (closing) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<Message> message;
|
||||
bool wasEmpty;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> queueLock(queueMutex);
|
||||
assert(!queue.empty());
|
||||
message = std::move(queue.front());
|
||||
queue.pop();
|
||||
wasEmpty = queue.empty();
|
||||
}
|
||||
|
||||
(*message)();
|
||||
|
||||
if (!wasEmpty) {
|
||||
scheduler.schedule(shared_from_this());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
Reference in New Issue
Block a user