Main MRPT website > C++ reference
MRPT logo
CThreadSafeQueue.h
Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                       http://www.mrpt.org/                                |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 #ifndef  CThreadSafeQueue_H
00029 #define  CThreadSafeQueue_H
00030 
00031 #include <mrpt/utils/CMessage.h>
00032 #include <mrpt/synch/CCriticalSection.h>
00033 #include <queue>
00034 
00035 namespace mrpt
00036 {
00037         namespace utils
00038         {
00039                 /** A thread-safe template queue for object passing between threads; for a template argument of T, the objects being passed in the queue are "T*".
00040                   *
00041                   *  Usage example:
00042                   *
00043                   * \code
00044                   * // Declaration:
00045                   * CThreadSafeQueue<MyMsgType>  tsq;
00046                   * ...
00047                   *
00048                   * // Thread 1: Write
00049                   * {
00050                   *   MyMsgType *msg = new MyMsgType;
00051                   *   msg->...
00052                   *   tsq.push(msg);  // Insert in the queue
00053                   * }
00054                   *
00055                   * // Thread 2: Read
00056                   * {
00057                   *   MyMsgType *msg = tsq.get();
00058                   *   if (msg)
00059                   *   {
00060                   *      // Process "msg"...
00061                   *      delete msg;
00062                   *   }
00063                   * }
00064                   * \endcode
00065                   *
00066                   *  Note that only dynamically allocated objects can be inserted with \a push() and that freeing that memory
00067                   *   if responsibility of the receiver of this queue as it receives objects with \a get(). However, elements
00068                   *   still in the queue upon destruction will be deleted automatically.
00069                   *
00070                   * \sa mrpt::utils::CMessageQueue
00071                  * \ingroup mrpt_base_grp
00072                   */
00073                 template <class T>
00074                 class CThreadSafeQueue
00075                 {
00076                 protected:
00077                         std::queue<T*> m_msgs; //!< The queue of messages. Memory is freed at destructor or by clients gathering messages.
00078                         mrpt::synch::CCriticalSection                   m_csQueue; //!< The critical section
00079                 public:
00080                         /** Default ctor. */
00081                         CThreadSafeQueue() { }
00082 
00083                         virtual ~CThreadSafeQueue()
00084                         {
00085                                 clear();
00086                         }
00087 
00088                         /** Clear the queue of messages, freeing memory as required. */
00089                         void clear()
00090                         {
00091                                 mrpt::synch::CCriticalSectionLocker locker( &m_csQueue );
00092                                 while (!m_msgs.empty())
00093                                 {
00094                                         delete m_msgs.front();
00095                                         m_msgs.pop();
00096                                 }
00097                         }
00098 
00099                         /** Insert a new message in the queue - The object must be created with "new", and do not delete is after calling this, it must be deleted later.
00100                           */
00101                         inline void push( T *msg )
00102                         {
00103                                 mrpt::synch::CCriticalSectionLocker locker( &m_csQueue );
00104                                 m_msgs.push( msg );
00105                         }
00106 
00107                         /** Retrieve the next message in the queue, or NULL if there is no message.
00108                           *  The user MUST call "delete" with the returned object after use.
00109                           */
00110                         inline T *get( )
00111                         {
00112                                 mrpt::synch::CCriticalSectionLocker locker( &m_csQueue );
00113                                 if (m_msgs.empty())
00114                                         return NULL;
00115                                 else
00116                                 {
00117                                         T *ret = m_msgs.front();
00118                                         m_msgs.pop();
00119                                         return ret;
00120                                 }
00121                         }
00122 
00123                         /** Skip all old messages in the queue and directly return the last one (the most recent, at the bottom of the queue), or NULL if there is no message.
00124                           *  \note The memory of all skipped messages is freed with "delete".
00125                           *  \note The user MUST call "delete" with the returned object after use.
00126                           */
00127                         inline T *get_lastest_purge_old( )
00128                         {
00129                                 mrpt::synch::CCriticalSectionLocker locker( &m_csQueue );
00130                                 if (m_msgs.empty())
00131                                         return NULL;
00132                                 else
00133                                 {
00134                                         for (;;)
00135                                         {
00136                                                 T *ret = m_msgs.front();
00137                                                 m_msgs.pop();
00138                                                 if (m_msgs.empty()) return ret;
00139                                                 else delete ret;
00140                                         }
00141                                 }
00142                         }
00143 
00144                         /** Return true if there are no messages. */
00145                         bool empty() const
00146                         {
00147                                 mrpt::synch::CCriticalSectionLocker locker( &m_csQueue );
00148                                 return m_msgs.empty();
00149                         }
00150 
00151                         /** Return the number of queued messages. */
00152                         size_t size() const
00153                         {
00154                                 mrpt::synch::CCriticalSectionLocker locker( &m_csQueue );
00155                                 return m_msgs.size();
00156                         }
00157 
00158                 }; // End of class def.
00159 
00160         } // End of namespace
00161 } // end of namespace
00162 #endif



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011