diff options
Diffstat (limited to 'src/mbgl/actor/mailbox.cpp')
-rw-r--r-- | src/mbgl/actor/mailbox.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/mbgl/actor/mailbox.cpp b/src/mbgl/actor/mailbox.cpp new file mode 100644 index 0000000000..ae3c0967af --- /dev/null +++ b/src/mbgl/actor/mailbox.cpp @@ -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 |