src.dualinventive.com/dinet/sec-multi-proxy/libdipp/include/di/Mailbox.h

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_