aca-tasks/task4/include/monitor.h

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;
};
};