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 |