00001 #ifndef QPID_CLUSTER_POLLABLEQUEUE_H
00002 #define QPID_CLUSTER_POLLABLEQUEUE_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 "qpid/cluster/PollableCondition.h"
00026 #include "qpid/sys/Dispatcher.h"
00027 #include "qpid/sys/Mutex.h"
00028 #include <boost/function.hpp>
00029 #include <boost/bind.hpp>
00030 #include <deque>
00031
00032 namespace qpid {
00033
00034 namespace sys { class Poller; }
00035
00036 namespace cluster {
00037
00038
00039
00040
00046 template <class T>
00047 class PollableQueue {
00048 typedef std::deque<T> Queue;
00049
00050 public:
00051 typedef typename Queue::iterator iterator;
00052
00054 typedef boost::function<void (const iterator&, const iterator&)> Callback;
00055
00057 explicit PollableQueue(const Callback& cb);
00058
00060 void push(const T& t) { ScopedLock l(lock); queue.push_back(t); condition.set(); }
00061
00063 void start(const boost::shared_ptr<sys::Poller>& poller) { handle.startWatch(poller); }
00064
00066 void stop() { handle.stopWatch(); }
00067
00068 private:
00069 typedef sys::Mutex::ScopedLock ScopedLock;
00070 typedef sys::Mutex::ScopedUnlock ScopedUnlock;
00071
00072 void dispatch(sys::DispatchHandle&);
00073
00074 sys::Mutex lock;
00075 Callback callback;
00076 PollableCondition condition;
00077 sys::DispatchHandle handle;
00078 Queue queue;
00079 Queue batch;
00080 };
00081
00082 template <class T> PollableQueue<T>::PollableQueue(const Callback& cb)
00083 : callback(cb),
00084 handle(condition, boost::bind(&PollableQueue<T>::dispatch, this, _1), 0, 0)
00085 {}
00086
00087 template <class T> void PollableQueue<T>::dispatch(sys::DispatchHandle& h) {
00088 ScopedLock l(lock);
00089 batch.clear();
00090 batch.swap(queue);
00091 condition.clear();
00092 ScopedUnlock u(lock);
00093 callback(batch.begin(), batch.end());
00094 h.rewatch();
00095 }
00096
00097 }}
00098
00099 #endif