|
|
|
|
|
|
|
|
#include <set> |
|
|
#include <set> |
|
|
#include <vector> |
|
|
#include <vector> |
|
|
#include <string> |
|
|
#include <string> |
|
|
|
|
|
#include <queue>
|
|
|
|
|
|
|
|
|
using namespace std; |
|
|
using namespace std; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
public: |
|
|
ScopeThreadLock(Thread* T); // Locks T in ThreadManager if it can. |
|
|
ScopeThreadLock(Thread* T); // Locks T in ThreadManager if it can. |
|
|
~ScopeThreadLock(); // Unlocks T in ThreadManager if locked. |
|
|
|
|
|
|
|
|
~ScopeThreadLock(); // Unlocks T in ThreadManager if locked. |
|
|
bool isGood(); // True if T was locked. |
|
|
bool isGood(); // True if T was locked. |
|
|
bool isBad(); // False if T was not locked. |
|
|
bool isBad(); // False if T was not locked. |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
// End Thread Manager |
|
|
// End Thread Manager |
|
|
//////////////////////////////////////////////////////////////////////////////// |
|
|
//////////////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// A ProductionQueue is a templated, thread safe mechanism for implementing
|
|
|
|
|
|
// a producer/consumer relationship. The objects in the queue should be simple
|
|
|
|
|
|
// data so that they can be created, destroyed, and copied without trouble. Put
|
|
|
|
|
|
// another way - the objects in the ProductionQueue should be lightweight
|
|
|
|
|
|
// handles for other things. Those things should be created and destroyed
|
|
|
|
|
|
// elsewhere.
|
|
|
|
|
|
|
|
|
|
|
|
template<typename T> // Templatized
|
|
|
|
|
|
class ProductionQueue { // Production Queue Class
|
|
|
|
|
|
private:
|
|
|
|
|
|
Mutex myMutex; // Contains a mutex and
|
|
|
|
|
|
volatile int LatestSize; // a volatile (blinking light) size
|
|
|
|
|
|
ProductionGateway myGateway; // integrated with a production
|
|
|
|
|
|
queue<T> myQueue; // gateway and a queue.
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
ProductionQueue() : LatestSize(0) {} // The size always starts at zero.
|
|
|
|
|
|
|
|
|
|
|
|
T take() { // To consume a queued object
|
|
|
|
|
|
myGateway.consume(); // we wait on the production gateway
|
|
|
|
|
|
ScopeMutex OneAtATimePlease(myMutex); // and when we get through we lock
|
|
|
|
|
|
T O = myQueue.front(); // the mutext, take the object on the
|
|
|
|
|
|
myQueue.pop(); // front of the queue, pop it out,
|
|
|
|
|
|
LatestSize = myQueue.size(); // and rest our size (blinking light).
|
|
|
|
|
|
return O; // Then return the object we got.
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void give(T O) { // To produce a queued object
|
|
|
|
|
|
ScopeMutex OneAtATimePlease(myMutex); // we wait on the mutex. When we
|
|
|
|
|
|
myQueue.push(O); // get through we push our object
|
|
|
|
|
|
LatestSize = myQueue.size(); // into the queue, reset our size
|
|
|
|
|
|
myGateway.produce(); // indicator and tell the gateway.
|
|
|
|
|
|
} // When we're done it can be grabbed.
|
|
|
|
|
|
|
|
|
|
|
|
int size() { // To check the size we look at
|
|
|
|
|
|
return LatestSize; // the blinking light.
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// End Production Queue
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|