115 lines
2.3 KiB
C++
115 lines
2.3 KiB
C++
/**
|
|
* @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 <chrono>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <vector>
|
|
#include <condition_variable>
|
|
|
|
namespace Di {
|
|
|
|
/**
|
|
* @class Mailbox
|
|
*
|
|
* IPC Mailbox, implements a thread-safe FIFO
|
|
*/
|
|
template <typename ValueType>
|
|
class Mailbox {
|
|
public:
|
|
Mailbox() : __notified(false) {
|
|
}
|
|
|
|
void post(std::shared_ptr<ValueType> item) {
|
|
std::lock_guard<std::mutex> lock(_lock);
|
|
__items.push_back(item);
|
|
__notified = true;
|
|
__cond.notify_one();
|
|
}
|
|
|
|
void postAhead(std::shared_ptr<ValueType> item) {
|
|
std::lock_guard<std::mutex> lock(_lock);
|
|
auto it = __items.begin();
|
|
__items.insert(it, item);
|
|
__notified = true;
|
|
__cond.notify_one();
|
|
}
|
|
|
|
bool fetch(std::shared_ptr<ValueType> *item) {
|
|
return fetch(item, true);
|
|
}
|
|
|
|
bool fetch(std::shared_ptr<ValueType> *item, bool wait) {
|
|
return fetch(item, wait, std::chrono::milliseconds(0));
|
|
}
|
|
|
|
bool fetch(std::shared_ptr<ValueType> *item, bool wait, std::chrono::milliseconds timeout) {
|
|
if (wait) {
|
|
std::unique_lock<std::mutex> 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<std::mutex> lock(_lock);
|
|
__items.clear();
|
|
}
|
|
|
|
protected:
|
|
std::mutex _lock;
|
|
|
|
private:
|
|
std::vector<std::shared_ptr<ValueType>> __items;
|
|
std::condition_variable __cond;
|
|
bool __notified;
|
|
};
|
|
|
|
} // namespace Di
|
|
|
|
#endif // INCLUDE_DI_MAILBOX_H_
|