#pragma once #include #include #include #include #include #include namespace mbgl { class Scheduler; class Message; class Mailbox : public std::enable_shared_from_this { public: /// Create a "holding" mailbox, messages to which will remain queued, /// unconsumed, until the mailbox is associated with a Scheduler using /// start(). This allows a Mailbox object to be created on one thread and /// later transferred to a different target thread that may not yet exist. Mailbox(); Mailbox(Scheduler&); /// Attach the given scheduler to this mailbox and begin processing messages /// sent to it. The mailbox must be a "holding" mailbox, as created by the /// default constructor Mailbox(). void open(Scheduler& scheduler_); void close(); // Indicate this mailbox will no longer be checked for messages void abandon(); bool isOpen() const; void push(std::unique_ptr); void receive(); static void maybeReceive(const std::weak_ptr&); static std::function makeClosure(std::weak_ptr); private: enum class State : uint32_t { Idle = 0, Processing, Abandoned }; mapbox::base::WeakPtr weakScheduler; std::recursive_mutex receivingMutex; std::mutex pushingMutex; std::atomic state{State::Idle}; bool closed{false}; std::mutex queueMutex; std::queue> queue; }; } // namespace mbgl