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 6450 2008-05-21 01:08:44Z thjc $
00043  * Author: Toby Collett - Jan 2005
00044  */
00045 
00046 #ifndef MESSAGE_H
00047 #define MESSAGE_H
00048 
00049 #include <pthread.h>
00050 
00051 #include <libplayercore/player.h>
00052 
00053 class MessageQueue;
00054 
00061 class QueuePointer
00062 {
00063   public:
00065     QueuePointer();
00067     QueuePointer(bool _Replace, size_t _Maxlen);
00069         ~QueuePointer();
00071         QueuePointer(const QueuePointer & CopyFrom);
00072         
00074         QueuePointer & operator = (const QueuePointer & rhs);
00076         MessageQueue * operator -> ();
00078         MessageQueue * get() const;
00080         MessageQueue & operator * ();
00082         bool operator == (const QueuePointer & rhs);
00084         bool operator == (void * pointer);
00086         bool operator != (const QueuePointer & rhs);
00088         bool operator != (void * pointer);
00089         
00090   private:
00092     void DecRef();
00093 
00095     MessageQueue * Queue;
00096 
00098     unsigned int * RefCount;
00099 
00101     pthread_mutex_t * Lock;
00102 };
00103 
00104 
00105 
00120 class Message
00121 {
00122   public:
00125     Message(const struct player_msghdr & Header,
00126             void* data,
00127             bool copy = true);
00128 
00131     Message(const struct player_msghdr & Header,
00132             void* data,
00133             QueuePointer &_queue,
00134             bool copy = true);
00135 
00137     Message(const Message & rhs);
00138 
00140     ~Message();
00141 
00147     static bool MatchMessage(player_msghdr_t* hdr,
00148                              int type,
00149                              int subtype,
00150                              player_devaddr_t addr)
00151     {
00152       return(((type < 0) || (hdr->type == (uint8_t)type)) &&
00153              ((subtype < 0) || (hdr->subtype == (uint8_t)subtype)) &&
00154              (hdr->addr.host == addr.host) &&
00155              (hdr->addr.robot == addr.robot) &&
00156              (hdr->addr.interf == addr.interf) &&
00157              (hdr->addr.index == addr.index));
00158     }
00159 
00165     static bool MatchMessage(player_msghdr_t* hdr,
00166                              int type,
00167                              int subtype)
00168     {
00169       return(((type < 0) || (hdr->type == (uint8_t)type)) &&
00170              ((subtype < 0) || (hdr->subtype == (uint8_t)subtype)));
00171     }    
00172     
00174     player_msghdr_t * GetHeader() {return &Header;};
00176     void* GetPayload() {return (void*)Data;};
00178     unsigned int GetDataSize() {return Header.size;};
00180     bool Compare(Message &other);
00182     void DecRef();
00183 
00185     QueuePointer Queue;
00186 
00188     unsigned int * RefCount;
00189 
00190   private:
00191     void CreateMessage(const struct player_msghdr & Header,
00192             void* data,
00193             bool copy = true);
00194           
00196     player_msghdr_t Header;
00198     uint8_t * Data;
00200     pthread_mutex_t * Lock;
00201 };
00202 
00206 class MessageQueueElement
00207 {
00208   public:
00210     MessageQueueElement();
00212     ~MessageQueueElement();
00213 
00215     Message* msg;
00216   private:
00218     MessageQueueElement * prev;
00220     MessageQueueElement * next;
00221 
00222     friend class MessageQueue;
00223 };
00224 
00231 class MessageReplaceRule
00232 {
00233   private:
00234     // The address to match (not using a player_devaddr_t so that we can
00235     // use -1 to indicate don't care)
00236     int host, robot, interf, index;
00237     // The type and subtype to match (-1 is don't care)
00238     int type, subtype;
00239   public:
00240     MessageReplaceRule(int _host, int _robot, int _interf, int _index,
00241                        int _type, int _subtype, int _replace) :
00242             host(_host), robot(_robot), interf(_interf), index(_index),
00243             type(_type), subtype(_subtype), replace(_replace), next(NULL) {}
00244 
00245     bool Match(player_msghdr_t* hdr)
00246     {
00247       return(((this->host < 0) ||
00248               ((uint32_t)this->host == hdr->addr.host)) &&
00249              ((this->robot < 0) ||
00250               ((uint32_t)this->robot == hdr->addr.robot)) &&
00251              ((this->interf < 0) ||
00252               ((uint16_t)this->interf == hdr->addr.interf)) &&
00253              ((this->index < 0) ||
00254               ((uint16_t)this->index == hdr->addr.index)) &&
00255              ((this->type < 0) ||
00256               ((uint8_t)this->type == hdr->type)) &&
00257              ((this->subtype < 0) ||
00258               ((uint8_t)this->subtype == hdr->subtype)));
00259     }
00260 
00261     bool Equivalent (int _host, int _robot, int _interf, int _index, int _type, int _subtype)
00262     {
00263       return (host == _host && robot == _robot && interf ==_interf && index == _index &&
00264           type == _type && subtype == _subtype);
00265     }
00266 
00267     // To replace, or not to replace
00268     // That is the question
00269     int replace;
00270     // Next rule in the list
00271     MessageReplaceRule* next;
00272 };
00273 
00325 class MessageQueue
00326 {
00327   public:
00329     MessageQueue(bool _Replace, size_t _Maxlen);
00331     ~MessageQueue();
00333     bool Empty() { return(this->head == NULL); }
00336     bool Push(Message& msg);
00337 
00342     void PushFront(Message & msg, bool haveLock);
00343 
00348     void PushBack(Message & msg, bool haveLock);
00349 
00353     Message* Pop();
00357     void SetReplace(bool _Replace) { this->Replace = _Replace; };
00364     void AddReplaceRule(int _host, int _robot, int _interf, int _index,
00365                         int _type, int _subtype, int _replace);
00371     void AddReplaceRule(const player_devaddr_t &device,
00372                         int _type, int _subtype, int _replace);
00375     int CheckReplace(player_msghdr_t* hdr);
00382     bool Wait(double TimeOut=0.0);
00385     void DataAvailable(void);
00387     bool Filter(Message& msg);
00389     void ClearFilter(void);
00391     void SetFilter(int host, int robot, int interf, int index,
00392                    int type, int subtype);
00394     void SetPull (bool _pull) { this->pull = _pull; }
00395 
00397     size_t GetLength(void);
00398 
00400     void SetDataRequested(bool d, bool haveLock);
00401 
00402   private:
00404     void Lock() {pthread_mutex_lock(&lock);};
00406     void Unlock() {pthread_mutex_unlock(&lock);};
00409     void Remove(MessageQueueElement* el);
00411     MessageQueueElement* head;
00413     MessageQueueElement* tail;
00415     pthread_mutex_t lock;
00417     size_t Maxlen;
00419     MessageReplaceRule* replaceRules;
00422     bool Replace;
00424     size_t Length;
00428     pthread_cond_t cond;
00430     pthread_mutex_t condMutex;
00432     bool filter_on;
00433     int filter_host, filter_robot, filter_interf,
00434         filter_index, filter_type, filter_subtype;
00437     bool pull;
00440     bool data_requested;
00442     bool data_delivered;
00444     bool drop_count;
00445 };
00446 
00447 
00448 
00449 
00450 #endif

Last updated 12 September 2005 21:38:45