00001 #ifndef QPID_SYS_BLOCKINGQUEUE_H
00002 #define QPID_SYS_BLOCKINGQUEUE_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "Waitable.h"
00026
00027 #include <queue>
00028
00029 namespace qpid {
00030 namespace sys {
00031
00035 template <class T>
00036 class BlockingQueue
00037 {
00038 mutable sys::Waitable waitable;
00039 std::queue<T> queue;
00040
00041 public:
00042 BlockingQueue() {}
00043 ~BlockingQueue() { close(); }
00044
00050 bool pop(T& result, Duration timeout=TIME_INFINITE) {
00051 Mutex::ScopedLock l(waitable);
00052 {
00053 Waitable::ScopedWait w(waitable);
00054 if (timeout == TIME_INFINITE) {
00055 while (queue.empty()) waitable.wait();
00056 } else {
00057 AbsTime deadline(now(),timeout);
00058 while (queue.empty() && deadline > now()) waitable.wait(deadline);
00059 }
00060 }
00061 if (queue.empty()) return false;
00062 result = queue.front();
00063 queue.pop();
00064 if (!queue.empty())
00065 waitable.notify();
00066 return true;
00067 }
00068
00069 T pop() {
00070 T result;
00071 bool ok = pop(result);
00072 assert(ok); (void) ok;
00073 return result;
00074 }
00075
00077 void push(const T& t) {
00078 Mutex::ScopedLock l(waitable);
00079 queue.push(t);
00080 waitable.notify();
00081 }
00082
00087 void close(const ExceptionHolder& ex=ExceptionHolder(new ClosedException()))
00088 {
00089 Mutex::ScopedLock l(waitable);
00090 if (!waitable.hasException()) {
00091 waitable.setException(ex);
00092 waitable.notifyAll();
00093 waitable.waitWaiters();
00094 }
00095 }
00096
00098 void open() {
00099 Mutex::ScopedLock l(waitable);
00100 waitable.resetException();
00101 }
00102
00103 bool isClosed() const {
00104 Mutex::ScopedLock l(waitable);
00105 return waitable.hasException();
00106 }
00107
00108 bool empty() const {
00109 Mutex::ScopedLock l(waitable);
00110 return queue.empty();
00111 }
00112 size_t size() const {
00113 Mutex::ScopedLock l(waitable);
00114 return queue.size();
00115 }
00116 };
00117
00118 }}
00119
00120
00121
00122 #endif