message.h
00001 /* 00002 * Player - One Hell of a Robot Server 00003 * Copyright (C) 2000 00004 * Brian Gerkey, Kasper Stoy, Richard Vaughan, & Andrew Howard 00005 * 00006 * 00007 * This program is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 * 00021 */ 00022 /******************************************************************** 00023 * 00024 * This library is free software; you can redistribute it and/or 00025 * modify it under the terms of the GNU Lesser General Public 00026 * License as published by the Free Software Foundation; either 00027 * version 2.1 of the License, or (at your option) any later version. 00028 * 00029 * This library is distributed in the hope that it will be useful, 00030 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00031 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00032 * Lesser General Public License for more details. 00033 * 00034 * You should have received a copy of the GNU Lesser General Public 00035 * License along with this library; if not, write to the Free Software 00036 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00037 * 00038 ********************************************************************/ 00039 00040 /* 00041 * Desc: Message class and message queues 00042 * CVS: $Id: message.h 8004 2009-07-13 14:03:44Z thjc $ 00043 * Author: Toby Collett - Jan 2005 00044 */ 00045 00046 #ifndef MESSAGE_H 00047 #define MESSAGE_H 00048 00049 #if defined (WIN32) 00050 #if defined (PLAYER_STATIC) 00051 #define PLAYERCORE_EXPORT 00052 #elif defined (playercore_EXPORTS) 00053 #define PLAYERCORE_EXPORT __declspec (dllexport) 00054 #else 00055 #define PLAYERCORE_EXPORT __declspec (dllimport) 00056 #endif 00057 #else 00058 #define PLAYERCORE_EXPORT 00059 #endif 00060 00061 #include <pthread.h> 00062 00063 #include <libplayerinterface/player.h> 00064 00065 class MessageQueue; 00066 00073 class PLAYERCORE_EXPORT QueuePointer 00074 { 00075 public: 00077 QueuePointer(); 00079 QueuePointer(bool _Replace, size_t _Maxlen); 00081 ~QueuePointer(); 00083 QueuePointer(const QueuePointer & CopyFrom); 00084 00086 QueuePointer & operator = (const QueuePointer & rhs); 00088 MessageQueue * operator -> (); 00090 MessageQueue * get() const; 00092 MessageQueue & operator * (); 00094 bool operator == (const QueuePointer & rhs); 00096 bool operator == (void * pointer); 00098 bool operator != (const QueuePointer & rhs); 00100 bool operator != (void * pointer); 00101 00102 private: 00104 void DecRef(); 00105 00107 MessageQueue * Queue; 00108 00110 unsigned int * RefCount; 00111 00113 pthread_mutex_t * Lock; 00114 }; 00115 00116 00117 00132 class PLAYERCORE_EXPORT Message 00133 { 00134 public: 00137 Message(const struct player_msghdr & Header, 00138 void* data, 00139 bool copy = true); 00140 00143 Message(const struct player_msghdr & Header, 00144 void* data, 00145 QueuePointer &_queue, 00146 bool copy = true); 00147 00149 Message(const Message & rhs); 00150 00152 ~Message(); 00153 00159 static bool MatchMessage(player_msghdr_t* hdr, 00160 int type, 00161 int subtype, 00162 player_devaddr_t addr) 00163 { 00164 return(((type < 0) || (hdr->type == (uint8_t)type)) && 00165 ((subtype < 0) || (hdr->subtype == (uint8_t)subtype)) && 00166 (hdr->addr.host == addr.host) && 00167 (hdr->addr.robot == addr.robot) && 00168 (hdr->addr.interf == addr.interf) && 00169 (hdr->addr.index == addr.index)); 00170 } 00171 00177 static bool MatchMessage(player_msghdr_t* hdr, 00178 int type, 00179 int subtype) 00180 { 00181 return(((type < 0) || (hdr->type == (uint8_t)type)) && 00182 ((subtype < 0) || (hdr->subtype == (uint8_t)subtype))); 00183 } 00184 00186 player_msghdr_t * GetHeader() {return &Header;}; 00188 void* GetPayload() {return (void*)Data;}; 00190 unsigned int GetDataSize() {return Header.size;}; 00192 bool Compare(Message &other); 00194 void DecRef(); 00195 00197 QueuePointer Queue; 00198 00200 unsigned int * RefCount; 00201 00202 private: 00203 void CreateMessage(const struct player_msghdr & Header, 00204 void* data, 00205 bool copy = true); 00206 00208 player_msghdr_t Header; 00210 uint8_t * Data; 00212 pthread_mutex_t * Lock; 00213 }; 00214 00218 class PLAYERCORE_EXPORT MessageQueueElement 00219 { 00220 public: 00222 MessageQueueElement(); 00224 ~MessageQueueElement(); 00225 00227 Message* msg; 00228 private: 00230 MessageQueueElement * prev; 00232 MessageQueueElement * next; 00233 00234 friend class MessageQueue; 00235 }; 00236 00243 class PLAYERCORE_EXPORT MessageReplaceRule 00244 { 00245 private: 00246 // The address to match (not using a player_devaddr_t so that we can 00247 // use -1 to indicate don't care) 00248 int host, robot, interf, index; 00249 // The type and subtype to match (-1 is don't care) 00250 int type, subtype; 00251 public: 00252 MessageReplaceRule(int _host, int _robot, int _interf, int _index, 00253 int _type, int _subtype, int _replace) : 00254 host(_host), robot(_robot), interf(_interf), index(_index), 00255 type(_type), subtype(_subtype), replace(_replace), next(NULL) {} 00256 00257 bool Match(player_msghdr_t* hdr) 00258 { 00259 return(((this->host < 0) || 00260 ((uint32_t)this->host == hdr->addr.host)) && 00261 ((this->robot < 0) || 00262 ((uint32_t)this->robot == hdr->addr.robot)) && 00263 ((this->interf < 0) || 00264 ((uint16_t)this->interf == hdr->addr.interf)) && 00265 ((this->index < 0) || 00266 ((uint16_t)this->index == hdr->addr.index)) && 00267 ((this->type < 0) || 00268 ((uint8_t)this->type == hdr->type)) && 00269 ((this->subtype < 0) || 00270 ((uint8_t)this->subtype == hdr->subtype))); 00271 } 00272 00273 bool Equivalent (int _host, int _robot, int _interf, int _index, int _type, int _subtype) 00274 { 00275 return (host == _host && robot == _robot && interf ==_interf && index == _index && 00276 type == _type && subtype == _subtype); 00277 } 00278 00279 // To replace, or not to replace 00280 // That is the question 00281 int replace; 00282 // Next rule in the list 00283 MessageReplaceRule* next; 00284 }; 00285 00337 class PLAYERCORE_EXPORT MessageQueue 00338 { 00339 public: 00341 MessageQueue(bool _Replace, size_t _Maxlen); 00343 ~MessageQueue(); 00345 bool Empty() { return(this->head == NULL); } 00348 bool Push(Message& msg); 00349 00354 void PushFront(Message & msg, bool haveLock); 00355 00360 void PushBack(Message & msg, bool haveLock); 00361 00365 Message* Pop(); 00369 void SetReplace(bool _Replace) { this->Replace = _Replace; }; 00376 void AddReplaceRule(int _host, int _robot, int _interf, int _index, 00377 int _type, int _subtype, int _replace); 00383 void AddReplaceRule(const player_devaddr_t &device, 00384 int _type, int _subtype, int _replace); 00387 int CheckReplace(player_msghdr_t* hdr); 00394 bool Wait(double TimeOut=0.0); 00397 void DataAvailable(void); 00399 bool Filter(Message& msg); 00401 void ClearFilter(void); 00403 void SetFilter(int host, int robot, int interf, int index, 00404 int type, int subtype); 00406 void SetPull (bool _pull) { this->pull = _pull; } 00407 00409 size_t GetLength(void); 00410 00412 void SetDataRequested(bool d, bool haveLock); 00413 00414 private: 00416 void Lock() {pthread_mutex_lock(&lock);}; 00418 void Unlock() {pthread_mutex_unlock(&lock);}; 00421 void Remove(MessageQueueElement* el); 00423 MessageQueueElement* head; 00425 MessageQueueElement* tail; 00427 pthread_mutex_t lock; 00429 size_t Maxlen; 00431 MessageReplaceRule* replaceRules; 00434 bool Replace; 00436 size_t Length; 00440 pthread_cond_t cond; 00442 pthread_mutex_t condMutex; 00444 bool filter_on; 00445 int filter_host, filter_robot, filter_interf, 00446 filter_index, filter_type, filter_subtype; 00449 bool pull; 00452 bool data_requested; 00454 bool data_delivered; 00456 bool drop_count; 00457 }; 00458 00459 00460 00461 00462 #endif