#pragma once
#include <config.h>
#ifdef HAVE_FOX
#include "fxheader.h"
#endif
#include <list>
#include <cassert>
#include <algorithm>
#ifdef DEBUG_LOCKING
#include <iostream>
#include "MFXWorkerThread.h"
#endif
template<class T, class Container = std::list<T> >
class MFXSynchQue {
public:
MFXSynchQue(const bool condition = true):
#ifdef HAVE_FOX
myMutex(true),
#endif
myCondition(condition)
{}
T top() {
assert(myItems.size() != 0);
#ifdef HAVE_FOX
if (myCondition) {
myMutex.lock();
}
#endif
T ret = myItems.front();
#ifdef HAVE_FOX
if (myCondition) {
myMutex.unlock();
}
#endif
return ret;
}
void pop() {
#ifdef HAVE_FOX
if (myCondition) {
myMutex.lock();
}
#endif
myItems.erase(myItems.begin());
#ifdef HAVE_FOX
if (myCondition) {
myMutex.unlock();
}
#endif
}
void unsetCondition() {
myCondition = false;
}
Container& getContainer() {
#ifdef HAVE_FOX
if (myCondition) {
myMutex.lock();
}
#endif
#ifdef DEBUG_LOCKING
if (debugflag) {
std::cout << " MFXSynchQue::getContainer thread=" << MFXWorkerThread::current() << "\n";
}
myOwningThread = MFXWorkerThread::current();
#endif
return myItems;
}
void unlock() {
#ifdef HAVE_FOX
if (myCondition) {
myMutex.unlock();
}
#endif
#ifdef DEBUG_LOCKING
if (debugflag) {
std::cout << " MFXSynchQue::unlock thread=" << MFXWorkerThread::current() << "\n";
}
myOwningThread = 0;
#endif
}
void push_back(T what) {
#ifdef HAVE_FOX
if (myCondition) {
myMutex.lock();
}
#endif
myItems.push_back(what);
#ifdef HAVE_FOX
if (myCondition) {
myMutex.unlock();
}
#endif
}
bool empty() {
#ifdef HAVE_FOX
if (myCondition) {
myMutex.lock();
}
#endif
const bool ret = myItems.size() == 0;
#ifdef HAVE_FOX
if (myCondition) {
myMutex.unlock();
}
#endif
return ret;
}
void clear() {
#ifdef HAVE_FOX
if (myCondition) {
myMutex.lock();
}
#endif
myItems.clear();
#ifdef HAVE_FOX
if (myCondition) {
myMutex.unlock();
}
#endif
}
size_t size() const {
#ifdef HAVE_FOX
if (myCondition) {
myMutex.lock();
}
#endif
size_t res = myItems.size();
#ifdef HAVE_FOX
if (myCondition) {
myMutex.unlock();
}
#endif
return res;
}
bool contains(const T& item) const {
#ifdef HAVE_FOX
if (myCondition) {
myMutex.lock();
}
#endif
bool res = std::find(myItems.begin(), myItems.end(), item) != myItems.end();
#ifdef HAVE_FOX
if (myCondition) {
myMutex.unlock();
}
#endif
return res;
}
bool isLocked() const {
#ifdef HAVE_FOX
return myMutex.locked();
#else
return false;
#endif
}
private:
#ifdef HAVE_FOX
mutable FXMutex myMutex;
#endif
Container myItems;
bool myCondition;
#ifdef DEBUG_LOCKING
mutable long long int myOwningThread = 0;
public:
mutable bool debugflag = false;
#endif
};