/** * @file include/di/Mailbox.h * @brief Mailbox FIFO queue * @date Aug 16, 2015 * @author R.W.A. van der Heijden * @copyright 2015 Dual Inventive Technology Centre B.V. * * IPC Mailbox, implements a thread-safe FIFO */ #ifndef INCLUDE_DI_MAILBOX_H_ #define INCLUDE_DI_MAILBOX_H_ #include #include #include #include #include namespace Di { /** * @class Mailbox * * IPC Mailbox, implements a thread-safe FIFO */ template class Mailbox { public: Mailbox() : __notified(false) { } void post(std::shared_ptr item) { std::lock_guard lock(_lock); __items.push_back(item); __notified = true; __cond.notify_one(); } void postAhead(std::shared_ptr item) { std::lock_guard lock(_lock); auto it = __items.begin(); __items.insert(it, item); __notified = true; __cond.notify_one(); } bool fetch(std::shared_ptr *item) { return fetch(item, true); } bool fetch(std::shared_ptr *item, bool wait) { return fetch(item, wait, std::chrono::milliseconds(0)); } bool fetch(std::shared_ptr *item, bool wait, std::chrono::milliseconds timeout) { if (wait) { std::unique_lock lk(_lock); if (timeout == std::chrono::milliseconds(0)) { while (!__items.size()) { __cond.wait(lk); } } else { std::cv_status ret; while (!__items.size()) { ret = __cond.wait_for(lk, timeout); if (ret == std::cv_status::timeout) { lk.unlock(); return false; } } } __notified = false; auto it = __items.begin(); *item = *it; __items.erase(it); lk.unlock(); return true; } else if (__items.size()) { if (_lock.try_lock()) { auto it = __items.begin(); __notified = false; *item = *it; __items.erase(it); _lock.unlock(); return true; } } return false; } bool isEmpty(void) { _lock.lock(); bool ret = __items.size() ? false : true; _lock.unlock(); return ret; } void reset(void) { std::lock_guard lock(_lock); __items.clear(); } protected: std::mutex _lock; private: std::vector> __items; std::condition_variable __cond; bool __notified; }; } // namespace Di #endif // INCLUDE_DI_MAILBOX_H_