68 lines
2.5 KiB
C
68 lines
2.5 KiB
C
|
#pragma once
|
||
|
|
||
|
#include <QMutexLocker>
|
||
|
#include <QWaitCondition>
|
||
|
#include <queue>
|
||
|
|
||
|
using namespace std;
|
||
|
|
||
|
const int BUFFSIZE = 100;
|
||
|
|
||
|
template<typename T>
|
||
|
class Monitor {
|
||
|
private:
|
||
|
QMutex l;
|
||
|
QWaitCondition full, empty;
|
||
|
// full: Condition variable for queue itemQ.
|
||
|
// empty: Condition variable for queue emptySpotsQ.
|
||
|
|
||
|
queue<T *> emptySpotsQ; // Queue of free item buffer places for items to be produced
|
||
|
queue<T *> itemQ; // Queue of item buffer places with items to be consumed
|
||
|
T *buffer; // Item buffer
|
||
|
public:
|
||
|
T *canPut() {
|
||
|
QMutexLocker ml(&l); // Lock entry controlling mutex l
|
||
|
while (emptySpotsQ.size() == 0) // If no free place in emptySpots queue:
|
||
|
full.wait(&l); // Block until condition variable full is given free by mutex l
|
||
|
T *aux = emptySpotsQ.front(); // Get place in emptySpotsQ
|
||
|
emptySpotsQ.pop(); // ?? Free one place in emptySpotsQ ?? (documentation of class queue currently not available)
|
||
|
return aux; // Return pointer to place in emptySpotsQ for item to be produced
|
||
|
|
||
|
};
|
||
|
|
||
|
T *canGet() {
|
||
|
QMutexLocker ml(&l); // Lock entry controlling mutex l
|
||
|
while (itemQ.size() == 0) // If no item in itemQ:
|
||
|
empty.wait(&l); // Block until condition variable empty is given free by mutex l
|
||
|
T *temp = itemQ.front(); // Get item out of itemQ
|
||
|
itemQ.pop(); // ?? Free one place in itemQ ?? (documentation of class queue currently not available)
|
||
|
return temp; // Return pointer to item in itemQ, which will be consumed
|
||
|
|
||
|
};
|
||
|
|
||
|
void donePutting(T *x) {
|
||
|
QMutexLocker ml(&l); // Lock entry controlling mutex l
|
||
|
itemQ.push(x); // Push place with produced item into itemQ
|
||
|
empty.wakeOne(); // Notify one consumer thread waiting for condition variable empty
|
||
|
|
||
|
};
|
||
|
|
||
|
void doneGetting(T *x) {
|
||
|
QMutexLocker ml(&l); // Lock entry controlling mutex l
|
||
|
emptySpotsQ.push(
|
||
|
x); // Give free the buffer place which had hold the consumed item by pushing in into emptySpotsQ
|
||
|
full.wakeOne(); // Notify one producer thread waiting for condition variable empty
|
||
|
|
||
|
};
|
||
|
|
||
|
Monitor(int n = BUFFSIZE) {
|
||
|
buffer = new T[n];
|
||
|
for (int i = 0; i < n; i++)
|
||
|
emptySpotsQ.push(&buffer[i]);
|
||
|
};
|
||
|
|
||
|
~Monitor() {
|
||
|
delete[]buffer;
|
||
|
};
|
||
|
};
|