#pragma once #include #include #include using namespace std; const int BUFFSIZE = 100; template class Monitor { private: QMutex l; QWaitCondition full, empty; // full: Condition variable for queue itemQ. // empty: Condition variable for queue emptySpotsQ. queue emptySpotsQ; // Queue of free item buffer places for items to be produced queue 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; }; };