#pragma region Header//********************************************************************// created: 2006/12/04// file path: c:\dev\projects\Sage\Sage\Threading// file: MessageProxy.h// author: Thomas "zeroflag" Kraemer// author email: zeroflag@zeroflag.de// // Copyright (C) 2006 Thomas "zeroflag" Kraemer// // license: (LGPL)// // This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA//// http://www.gnu.org/licenses/lgpl.html#TOC1////*********************************************************************#pragma endregion#pragma once#pragma region Includes// basic project header files#include "../Basics/Basics.h"// header file for std::queue#include <queue>using std::queue;// header for boost::function#include <boost/function.hpp>using boost::function;// header for boost::recursive_mutex#include <boost/thread/recursive_mutex.hpp>typedef boost::recursive_mutex Mutex;typedef boost::function<void(void)> Message;#include "MessageQueue.h"#pragma endregionnamespace Sage{ class Module; namespace Threading { typedef boost::function<void (void)> Message; typedef Mutex::scoped_lock Lock; /** * Serves as an unidirectional, double-buffered message queue between 2 modules. * @remark Only one writer and one reader are allowed. */ class SAGE_API MessageProxy : public MessageQueue { public: virtual ~MessageProxy(); /** * Pushes a new message to the WriteQueue. * @return void * @param Message message */ virtual void push(Message message); /** * Reads and removes the first Message from the ReadQueue. * @return Sage::Threading::Message */ virtual shared_ptr<Message> pop(); /** * Swap the read- with the write-queue. * @remark This method locks both, read and write operations. It should only be used from the reader's end and only if isMessageWaiting() returns true. */ void swap(); /** * Locks and clears the Read queue. Should only be done from the Read thread (really!). */ void clearReadQueue(); /** * Locks and clears the Write queue. Should only be done from the Write thread. * @return void */ void clearWriteQueue(); /** * Locks and clears both queues. Use with care. */ void clear(); /** * Returns a scoped lock for the read-queue. * @remark You need to store the returned Lock value in order to keep it locked. * @return Sage::Threading::Lock */ Lock getReadLock(); /** * Returns a scoped lock for the write-queue. * @remark You need to store the returned Lock value in order to keep it locked. * @return Sage::Threading::Lock */ Lock getWriteLock(); virtual bool isEmpty(); virtual void update() {} //TODO: move to protected after debugging. MessageProxy(); protected: /** * Whether there is a message waiting on the write queue. * @remark this uses a volatile boolean that is set by push operations. yield writer- and reader-threads before/after operations if you want to make sure that this method returns the current value. * @return bool */ bool isMessageWaiting() const; queue<shared_ptr<Message>>* mReadQueue; queue<shared_ptr<Message>>* mWriteQueue; Mutex mReadMutex; Mutex mWriteMutex; volatile bool mMessageWaiting; friend class Sage::Module; }; }}