00001 /* Copyright (C) 2008 by Marc Maurer <uwog@uwog.net> 00002 * 00003 * This program is free software; you can redistribute it and/or 00004 * modify it under the terms of the GNU General Public License 00005 * as published by the Free Software Foundation; either version 2 00006 * of the License, or (at your option) any later version. 00007 * 00008 * This program is distributed in the hope that it will be useful, 00009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 * GNU General Public License for more details. 00012 * 00013 * You should have received a copy of the GNU General Public License 00014 * along with this program; if not, write to the Free Software 00015 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00016 * 02110-1301 USA. 00017 */ 00018 00019 #ifndef __SYNCHRONIZED_QUEUE__ 00020 #define __SYNCHRONIZED_QUEUE__ 00021 00022 #include <deque> 00023 #include <boost/bind.hpp> 00024 #include <boost/function.hpp> 00025 #include <boost/noncopyable.hpp> 00026 #include <sync/xp/lock.h> 00027 #include <sync/xp/Synchronizer.h> 00028 00029 class EmptyQueueException {}; 00030 00031 template <typename T> 00032 class SynchronizedQueue : public Synchronizer, public boost::noncopyable 00033 { 00034 public: 00035 SynchronizedQueue(boost::function<void (SynchronizedQueue&)> sig) 00036 : Synchronizer(boost::bind(&SynchronizedQueue::_signal, this)), 00037 m_mutex(), 00038 m_queue(), 00039 m_sig(sig) 00040 {} 00041 00042 void push(T t) 00043 { 00044 abicollab::scoped_lock lock(m_mutex); 00045 m_queue.push_back( t ); 00046 Synchronizer::signal(); 00047 } 00048 00049 T pop() 00050 { 00051 if (m_queue.size() == 0) 00052 throw EmptyQueueException(); 00053 abicollab::scoped_lock lock(m_mutex); 00054 T t = m_queue.front(); 00055 m_queue.pop_front(); 00056 return t; 00057 } 00058 00059 bool peek() 00060 { 00061 return m_queue.size() > 0; 00062 } 00063 00064 private: 00065 void _signal() 00066 { 00067 m_sig(*this); 00068 } 00069 00070 abicollab::mutex m_mutex; 00071 std::deque< T > m_queue; 00072 boost::function<void (SynchronizedQueue&)> m_sig; 00073 }; 00074 00075 #endif /* __SYNCHRONIZED_QUEUE__ */