00001 #ifndef _sys_ThreadSafeQueue_h
00002 #define _sys_ThreadSafeQueue_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <deque>
00023 #include "ProducerConsumer.h"
00024 #include "qpid/Exception.h"
00025
00026 namespace qpid {
00027 namespace sys {
00028
00032 template <class T, class ContainerType=std::deque<T> >
00033 class ThreadSafeQueue
00034 {
00035 public:
00036
00037 ThreadSafeQueue() {}
00038
00040 void push(const T& value) {
00041 ProducerConsumer::ProducerLock producer(pc);
00042 if (producer.isOk()) {
00043 producer.confirm();
00044 container.push_back(value);
00045 }
00046 }
00047
00051 T pop() {
00052 ProducerConsumer::ConsumerLock consumer(pc);
00053 if (consumer.isOk()) {
00054 consumer.confirm();
00055 T value(container.front());
00056 container.pop_front();
00057 return value;
00058 }
00059 throw ShutdownException();
00060 }
00061
00066 bool pop(T& outValue, const Time& timeout) {
00067 ProducerConsumer::ConsumerLock consumer(pc, timeout);
00068 if (consumer.isOk()) {
00069 consumer.confirm();
00070 outValue = container.front();
00071 container.pop_front();
00072 return true;
00073 }
00074 return false;
00075 }
00076
00078 void shutdown() { pc.shutdown(); }
00079
00081 bool isShutdown() { return pc.isShutdown(); }
00082
00084 size_t size() { ProducerConsumer::Lock l(pc); return container.size(); }
00085
00087 bool empty() { ProducerConsumer::Lock l(pc); return container.empty(); }
00088
00089 private:
00090 ProducerConsumer pc;
00091 ContainerType container;
00092 };
00093
00094 }}
00095
00096
00097
00098 #endif