// Copyright (c) 2011-2016 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #pragma once #include #include "IntrusiveLinkedList.h" #include "System/Event.h" #include "System/InterruptedException.h" namespace CryptoNote { template class MessageQueue { public: MessageQueue(System::Dispatcher& dispatcher); const MessageType& front(); void pop(); void push(const MessageType& message); void stop(); typename IntrusiveLinkedList>::hook& getHook(); private: void wait(); std::queue messageQueue; System::Event event; bool stopped; typename IntrusiveLinkedList>::hook hook; }; template class MesageQueueGuard { public: MesageQueueGuard(MessageQueueContainer& container, MessageQueue& messageQueue) : container(container), messageQueue(messageQueue) { container.addMessageQueue(messageQueue); } MesageQueueGuard(const MesageQueueGuard& other) = delete; MesageQueueGuard& operator=(const MesageQueueGuard& other) = delete; ~MesageQueueGuard() { container.removeMessageQueue(messageQueue); } private: MessageQueueContainer& container; MessageQueue& messageQueue; }; template MessageQueue::MessageQueue(System::Dispatcher& dispatcher) : event(dispatcher), stopped(false) {} template void MessageQueue::wait() { if (messageQueue.empty()) { if (stopped) { throw System::InterruptedException(); } event.clear(); while (!event.get()) { event.wait(); } } } template const MessageType& MessageQueue::front() { wait(); return messageQueue.front(); } template void MessageQueue::pop() { wait(); messageQueue.pop(); } template void MessageQueue::push(const MessageType& message) { messageQueue.push(message); event.set(); } template void MessageQueue::stop() { stopped = true; event.set(); } template typename IntrusiveLinkedList>::hook& MessageQueue::getHook() { return hook; } }