message.h
/*
* Player - One Hell of a Robot Server
* Copyright (C) 2000
* Brian Gerkey, Kasper Stoy, Richard Vaughan, & Andrew Howard
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/********************************************************************
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
********************************************************************/
/*
* Desc: Message class and message queues
* CVS: $Id: message.h 8004 2009-07-13 14:03:44Z thjc $
* Author: Toby Collett - Jan 2005
*/
#ifndef MESSAGE_H
#define MESSAGE_H
#if defined (WIN32)
#if defined (PLAYER_STATIC)
#define PLAYERCORE_EXPORT
#elif defined (playercore_EXPORTS)
#define PLAYERCORE_EXPORT __declspec (dllexport)
#else
#define PLAYERCORE_EXPORT __declspec (dllimport)
#endif
#else
#define PLAYERCORE_EXPORT
#endif
#include <pthread.h>
#include <libplayerinterface/player.h>
class MessageQueue;
class PLAYERCORE_EXPORT QueuePointer
{
public:
QueuePointer();
QueuePointer(bool _Replace, size_t _Maxlen);
~QueuePointer();
QueuePointer(const QueuePointer & CopyFrom);
QueuePointer & operator = (const QueuePointer & rhs);
MessageQueue * operator -> ();
MessageQueue * get() const;
MessageQueue & operator * ();
bool operator == (const QueuePointer & rhs);
bool operator == (void * pointer);
bool operator != (const QueuePointer & rhs);
bool operator != (void * pointer);
private:
void DecRef();
MessageQueue * Queue;
unsigned int * RefCount;
pthread_mutex_t * Lock;
};
class PLAYERCORE_EXPORT Message
{
public:
Message(const struct player_msghdr & Header,
void* data,
bool copy = true);
Message(const struct player_msghdr & Header,
void* data,
QueuePointer &_queue,
bool copy = true);
Message(const Message & rhs);
~Message();
static bool MatchMessage(player_msghdr_t* hdr,
int type,
int subtype,
player_devaddr_t addr)
{
return(((type < 0) || (hdr->type == (uint8_t)type)) &&
((subtype < 0) || (hdr->subtype == (uint8_t)subtype)) &&
(hdr->addr.host == addr.host) &&
(hdr->addr.robot == addr.robot) &&
(hdr->addr.interf == addr.interf) &&
(hdr->addr.index == addr.index));
}
static bool MatchMessage(player_msghdr_t* hdr,
int type,
int subtype)
{
return(((type < 0) || (hdr->type == (uint8_t)type)) &&
((subtype < 0) || (hdr->subtype == (uint8_t)subtype)));
}
player_msghdr_t * GetHeader() {return &Header;};
void* GetPayload() {return (void*)Data;};
unsigned int GetDataSize() {return Header.size;};
bool Compare(Message &other);
void DecRef();
QueuePointer Queue;
unsigned int * RefCount;
private:
void CreateMessage(const struct player_msghdr & Header,
void* data,
bool copy = true);
player_msghdr_t Header;
uint8_t * Data;
pthread_mutex_t * Lock;
};
class PLAYERCORE_EXPORT MessageQueueElement
{
public:
MessageQueueElement();
~MessageQueueElement();
Message* msg;
private:
MessageQueueElement * prev;
MessageQueueElement * next;
friend class MessageQueue;
};
class PLAYERCORE_EXPORT MessageReplaceRule
{
private:
// The address to match (not using a player_devaddr_t so that we can
// use -1 to indicate don't care)
int host, robot, interf, index;
// The type and subtype to match (-1 is don't care)
int type, subtype;
public:
MessageReplaceRule(int _host, int _robot, int _interf, int _index,
int _type, int _subtype, int _replace) :
host(_host), robot(_robot), interf(_interf), index(_index),
type(_type), subtype(_subtype), replace(_replace), next(NULL) {}
bool Match(player_msghdr_t* hdr)
{
return(((this->host < 0) ||
((uint32_t)this->host == hdr->addr.host)) &&
((this->robot < 0) ||
((uint32_t)this->robot == hdr->addr.robot)) &&
((this->interf < 0) ||
((uint16_t)this->interf == hdr->addr.interf)) &&
((this->index < 0) ||
((uint16_t)this->index == hdr->addr.index)) &&
((this->type < 0) ||
((uint8_t)this->type == hdr->type)) &&
((this->subtype < 0) ||
((uint8_t)this->subtype == hdr->subtype)));
}
bool Equivalent (int _host, int _robot, int _interf, int _index, int _type, int _subtype)
{
return (host == _host && robot == _robot && interf ==_interf && index == _index &&
type == _type && subtype == _subtype);
}
// To replace, or not to replace
// That is the question
int replace;
// Next rule in the list
MessageReplaceRule* next;
};
class PLAYERCORE_EXPORT MessageQueue
{
public:
MessageQueue(bool _Replace, size_t _Maxlen);
~MessageQueue();
bool Empty() { return(this->head == NULL); }
bool Push(Message& msg);
void PushFront(Message & msg, bool haveLock);
void PushBack(Message & msg, bool haveLock);
Message* Pop();
void SetReplace(bool _Replace) { this->Replace = _Replace; };
void AddReplaceRule(int _host, int _robot, int _interf, int _index,
int _type, int _subtype, int _replace);
void AddReplaceRule(const player_devaddr_t &device,
int _type, int _subtype, int _replace);
int CheckReplace(player_msghdr_t* hdr);
bool Wait(double TimeOut=0.0);
void DataAvailable(void);
bool Filter(Message& msg);
void ClearFilter(void);
void SetFilter(int host, int robot, int interf, int index,
int type, int subtype);
void SetPull (bool _pull) { this->pull = _pull; }
size_t GetLength(void);
void SetDataRequested(bool d, bool haveLock);
private:
void Lock() {pthread_mutex_lock(&lock);};
void Unlock() {pthread_mutex_unlock(&lock);};
void Remove(MessageQueueElement* el);
MessageQueueElement* head;
MessageQueueElement* tail;
pthread_mutex_t lock;
size_t Maxlen;
MessageReplaceRule* replaceRules;
bool Replace;
size_t Length;
pthread_cond_t cond;
pthread_mutex_t condMutex;
bool filter_on;
int filter_host, filter_robot, filter_interf,
filter_index, filter_type, filter_subtype;
bool pull;
bool data_requested;
bool data_delivered;
bool drop_count;
};
#endif
MessageQueue
A doubly-linked queue of messages.
Definition: message.h:337
Message::RefCount
unsigned int * RefCount
Reference count.
Definition: message.h:200
MessageQueue::pull
bool pull
Flag for if in pull mode.
Definition: message.h:449
player_devaddr::interf
uint16_t interf
The interface provided by the device; must be one of PLAYER_*_CODE.
Definition: player.h:149
player_msghdr
Generic message header.
Definition: player.h:157
MessageQueue::SetPull
void SetPull(bool _pull)
Set the pull flag.
Definition: message.h:406
Message::Lock
pthread_mutex_t * Lock
Used to lock access to Data.
Definition: message.h:212
Message
Reference-counted message objects.
Definition: message.h:132
MessageQueue::SetReplace
void SetReplace(bool _Replace)
Set the Replace flag, which governs whether data and command messages of the same subtype from the sa...
Definition: message.h:369
Message::Data
uint8_t * Data
Pointer to the message data.
Definition: message.h:210
player_msghdr::addr
player_devaddr_t addr
Device to which this message pertains.
Definition: player.h:160
MessageQueue::data_delivered
bool data_delivered
Flag that data was sent (in PULL mode)
Definition: message.h:454
MessageQueue::lock
pthread_mutex_t lock
Mutex to control access to the queue, via Lock() and Unlock().
Definition: message.h:427
player_devaddr
A device address.
Definition: player.h:141
MessageQueue::tail
MessageQueueElement * tail
Tail of the queue.
Definition: message.h:425
Message::GetPayload
void * GetPayload()
Get pointer to payload.
Definition: message.h:188
player_devaddr::host
uint32_t host
The "host" on which the device resides.
Definition: player.h:144
QueuePointer::Queue
MessageQueue * Queue
The queue we are pointing to.
Definition: message.h:107
MessageQueueElement::msg
Message * msg
The message stored in this queue element.
Definition: message.h:227
MessageQueue::cond
pthread_cond_t cond
A condition variable that can be used to signal, via DataAvailable(), other threads that are Wait()in...
Definition: message.h:440
QueuePointer
An autopointer for the message queue.
Definition: message.h:73
MessageQueue::condMutex
pthread_mutex_t condMutex
Mutex to go with condition variable cond.
Definition: message.h:442
MessageQueue::Maxlen
size_t Maxlen
Maximum length of queue in elements.
Definition: message.h:429
Message::GetHeader
player_msghdr_t * GetHeader()
Get pointer to header.
Definition: message.h:186
player_msghdr::size
uint32_t size
Size in bytes of the payload to follow.
Definition: player.h:170
MessageQueue::Replace
bool Replace
When a (data or command) message doesn't match a rule in replaceRules, should we replace it...
Definition: message.h:434
player_devaddr::robot
uint32_t robot
The "robot" or device collection in which the device resides.
Definition: player.h:147
player_msghdr::type
uint8_t type
Message type; must be one of PLAYER_MSGTYPE_*.
Definition: player.h:162
MessageQueue::Empty
bool Empty()
Check whether a queue is empty.
Definition: message.h:345
MessageQueue::Lock
void Lock()
Lock the mutex associated with this queue.
Definition: message.h:416
MessageQueue::drop_count
bool drop_count
Count of the number of messages discarded due to queue overflow.
Definition: message.h:456
MessageReplaceRule
We keep a singly-linked list of (addr,type,subtype,replace) tuples.
Definition: message.h:243
QueuePointer::RefCount
unsigned int * RefCount
Reference count.
Definition: message.h:110
QueuePointer::Lock
pthread_mutex_t * Lock
Used to lock access to refcount.
Definition: message.h:113
Message::Header
player_msghdr_t Header
message header
Definition: message.h:208
MessageQueueElement
This class is a helper for maintaining doubly-linked queues of Messages.
Definition: message.h:218
MessageQueue::filter_on
bool filter_on
Current filter values.
Definition: message.h:444
Message::Queue
QueuePointer Queue
queue to which any response to this message should be directed
Definition: message.h:197
MessageQueue::Length
size_t Length
Current length of queue, in elements.
Definition: message.h:436
MessageQueueElement::next
MessageQueueElement * next
Pointer to next queue element.
Definition: message.h:232
Message::GetDataSize
unsigned int GetDataSize()
Size of message data.
Definition: message.h:190
MessageQueueElement::prev
MessageQueueElement * prev
Pointer to previous queue element.
Definition: message.h:230
player_msghdr::subtype
uint8_t subtype
Message subtype; interface specific.
Definition: player.h:164
MessageQueue::data_requested
bool data_requested
Flag for data was requested (in PULL mode), but none has yet been delivered.
Definition: message.h:452
MessageQueue::Unlock
void Unlock()
Unlock the mutex associated with this queue.
Definition: message.h:418
Message::MatchMessage
static bool MatchMessage(player_msghdr_t *hdr, int type, int subtype)
Helper for message processing.
Definition: message.h:177
Message::MatchMessage
static bool MatchMessage(player_msghdr_t *hdr, int type, int subtype, player_devaddr_t addr)
Helper for message processing.
Definition: message.h:159
MessageQueue::replaceRules
MessageReplaceRule * replaceRules
Singly-linked list of replacement rules.
Definition: message.h:431
MessageQueue::head
MessageQueueElement * head
Head of the queue.
Definition: message.h:423
player_devaddr::index
uint16_t index
Which device of that interface.
Definition: player.h:151

Last updated 12 September 2005 21:38:45