This is Unofficial EPICS BASE Doxygen Site
osdMessageQueue.cpp File Reference
#include <stdexcept>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "epicsMessageQueue.h"
#include <ellLib.h>
#include <epicsAssert.h>
#include <epicsEvent.h>
#include <epicsMutex.h>
+ Include dependency graph for osdMessageQueue.cpp:

Go to the source code of this file.

Classes

struct  eventNode
 
struct  threadNode
 
struct  epicsMessageQueueOSD
 

Functions

LIBCOM_API epicsMessageQueueId epicsStdCall epicsMessageQueueCreate (unsigned int capacity, unsigned int maxMessageSize)
 Create a message queue. More...
 
LIBCOM_API void epicsStdCall epicsMessageQueueDestroy (epicsMessageQueueId pmsg)
 Destroy a message queue, release all its memory. More...
 
LIBCOM_API int epicsStdCall epicsMessageQueueTrySend (epicsMessageQueueId pmsg, void *message, unsigned int size)
 Try to send a message. More...
 
LIBCOM_API int epicsStdCall epicsMessageQueueSend (epicsMessageQueueId pmsg, void *message, unsigned int size)
 Send a message. More...
 
LIBCOM_API int epicsStdCall epicsMessageQueueSendWithTimeout (epicsMessageQueueId pmsg, void *message, unsigned int size, double timeout)
 Send a message or timeout. More...
 
LIBCOM_API int epicsStdCall epicsMessageQueueTryReceive (epicsMessageQueueId pmsg, void *message, unsigned int size)
 Try to receive a message. More...
 
LIBCOM_API int epicsStdCall epicsMessageQueueReceive (epicsMessageQueueId pmsg, void *message, unsigned int size)
 Fetch the next message on the queue. More...
 
LIBCOM_API int epicsStdCall epicsMessageQueueReceiveWithTimeout (epicsMessageQueueId pmsg, void *message, unsigned int size, double timeout)
 Wait for a message to be queued. More...
 
LIBCOM_API int epicsStdCall epicsMessageQueuePending (epicsMessageQueueId pmsg)
 How many messages are queued. More...
 
LIBCOM_API void epicsStdCall epicsMessageQueueShow (epicsMessageQueueId pmsg, int level)
 Displays some information about the message queue. More...
 

Function Documentation

LIBCOM_API epicsMessageQueueId epicsStdCall epicsMessageQueueCreate ( unsigned int  capacity,
unsigned int  maximumMessageSize 
)

Create a message queue.

Parameters
capacityMaximum number of messages to queue
maximumMessageSizeNumber of bytes of the largest message that may be queued
Returns
An identifier for the new queue, or 0.

Definition at line 69 of file osdMessageQueue.cpp.

72 {
74  unsigned int slotBytes, slotLongs;
75 
76  if(capacity == 0)
77  return NULL;
78 
79  pmsg = (epicsMessageQueueId)calloc(1, sizeof(*pmsg));
80  if(!pmsg)
81  return NULL;
82 
83  pmsg->capacity = capacity;
84  pmsg->maxMessageSize = maxMessageSize;
85  slotLongs = 1 + ((maxMessageSize + sizeof(unsigned long) - 1) / sizeof(unsigned long));
86  slotBytes = slotLongs * sizeof(unsigned long);
87 
88  pmsg->mutex = epicsMutexCreate();
89  pmsg->buf = (unsigned long*)calloc(pmsg->capacity, slotBytes);
90  if(!pmsg->buf || !pmsg->mutex) {
91  if(pmsg->mutex)
92  epicsMutexDestroy(pmsg->mutex);
93  free(pmsg->buf);
94  free(pmsg);
95  return NULL;
96  }
97 
98  pmsg->inPtr = pmsg->outPtr = pmsg->firstMessageSlot = (char *)&pmsg->buf[0];
99  pmsg->lastMessageSlot = (char *)&pmsg->buf[(capacity - 1) * slotLongs];
100  pmsg->full = false;
101  pmsg->slotSize = slotBytes;
102 
103  ellInit(&pmsg->sendQueue);
104  ellInit(&pmsg->receiveQueue);
105  ellInit(&pmsg->eventFreeList);
106  return pmsg;
107 }
volatile char * inPtr
void epicsStdCall epicsMutexDestroy(epicsMutexId pmutexNode)
Destroy an epicsMutex semaphore.
Definition: epicsMutex.cpp:127
volatile char * outPtr
struct epicsMessageQueueOSD * epicsMessageQueueId
#define NULL
Definition: catime.c:38
unsigned long maxMessageSize
#define ellInit(PLIST)
Initialize a list type.
Definition: ellLib.h:76
#define epicsMutexCreate()
Create an epicsMutex semaphore for use from C code.
Definition: epicsMutex.h:168
LIBCOM_API void epicsStdCall epicsMessageQueueDestroy ( epicsMessageQueueId  pmsg)

Destroy a message queue, release all its memory.

Definition at line 117 of file osdMessageQueue.cpp.

118 {
119  struct eventNode *evp;
120 
121  while ((evp = reinterpret_cast < struct eventNode * >
122  ( ellGet(&pmsg->eventFreeList) ) ) != NULL) {
123  destroyEventNode(evp);
124  }
125  epicsMutexDestroy(pmsg->mutex);
126  free(pmsg->buf);
127  free(pmsg);
128 }
void epicsStdCall epicsMutexDestroy(epicsMutexId pmutexNode)
Destroy an epicsMutex semaphore.
Definition: epicsMutex.cpp:127
ELLNODE * ellGet(ELLLIST *pList)
Deletes and returns the first node from a list.
Definition: ellLib.c:147
#define NULL
Definition: catime.c:38
LIBCOM_API int epicsStdCall epicsMessageQueuePending ( epicsMessageQueueId  id)

How many messages are queued.

Parameters
idMessage queue identifier.
Returns
The number of messages presently in the queue.

Definition at line 398 of file osdMessageQueue.cpp.

399 {
400  char *myInPtr, *myOutPtr;
401  int nmsg;
402 
403  epicsMutexMustLock(pmsg->mutex);
404  myInPtr = (char *)pmsg->inPtr;
405  myOutPtr = (char *)pmsg->outPtr;
406  if (pmsg->full)
407  nmsg = pmsg->capacity;
408  else if (myInPtr >= myOutPtr)
409  nmsg = (myInPtr - myOutPtr) / pmsg->slotSize;
410  else
411  nmsg = pmsg->capacity - (myOutPtr - myInPtr) / pmsg->slotSize;
412  epicsMutexUnlock(pmsg->mutex);
413  return nmsg;
414 }
volatile char * inPtr
volatile char * outPtr
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
Definition: epicsMutex.h:214
LIBCOM_API int epicsStdCall epicsMessageQueueReceive ( epicsMessageQueueId  id,
void *  message,
unsigned int  size 
)

Fetch the next message on the queue.

Wait for a message to be sent if the queue is empty, then move the first message queued to the specified location.

If the received message is larger than the specified message size the implementation may either return -1, or truncate the message. It is most efficient if the messageBufferSize is equal to the maximumMessageSize with which the message queue was created.

Returns
Number of bytes in the message.
-1 if the buffer is too small for the message.

Definition at line 384 of file osdMessageQueue.cpp.

386 {
387  return myReceive(pmsg, message, size, -1);
388 }
LIBCOM_API int epicsStdCall epicsMessageQueueReceiveWithTimeout ( epicsMessageQueueId  id,
void *  message,
unsigned int  size,
double  timeout 
)

Wait for a message to be queued.

Wait up to timeout seconds for a message to be sent if the queue is empty, then move the first message to the specified location.

If the received message is larger than the specified message buffer size the implementation may either return -1, or truncate the message. It is most efficient if the messageBufferSize is equal to the maximumMessageSize with which the message queue was created.

Returns
Number of bytes in the message.
-1 if a message is not received within the timeout interval.

Definition at line 391 of file osdMessageQueue.cpp.

393 {
394  return myReceive(pmsg, message, size, timeout);
395 }
double timeout
Definition: pvutils.cpp:25
LIBCOM_API int epicsStdCall epicsMessageQueueSend ( epicsMessageQueueId  id,
void *  message,
unsigned int  messageSize 
)

Send a message.

Returns
0 if the message was sent to a receiver or queued for future delivery.
-1 if the message is larger than the queue's maximum message size.

Definition at line 263 of file osdMessageQueue.cpp.

265 {
266  return mySend(pmsg, message, size, -1);
267 }
LIBCOM_API int epicsStdCall epicsMessageQueueSendWithTimeout ( epicsMessageQueueId  id,
void *  message,
unsigned int  messageSize,
double  timeout 
)

Send a message or timeout.

Returns
0 if the message was sent to a receiver or queued for future delivery.
-1 if the timeout was reached before the message could be sent or queued, or if the message is larger than the queue's maximum message size.

Definition at line 270 of file osdMessageQueue.cpp.

272 {
273  return mySend(pmsg, message, size, timeout);
274 }
double timeout
Definition: pvutils.cpp:25
LIBCOM_API void epicsStdCall epicsMessageQueueShow ( epicsMessageQueueId  id,
int  level 
)

Displays some information about the message queue.

Parameters
idMessage queue identifier.
levelControls the amount of information displayed.

Definition at line 417 of file osdMessageQueue.cpp.

418 {
419  printf("Message Queue Used:%d Slots:%lu",
420  epicsMessageQueuePending(pmsg), pmsg->capacity);
421  if (level >= 1)
422  printf(" Maximum size:%lu", pmsg->maxMessageSize);
423  printf("\n");
424 }
#define printf
Definition: epicsStdio.h:41
unsigned long maxMessageSize
LIBCOM_API int epicsStdCall epicsMessageQueuePending(epicsMessageQueueId pmsg)
How many messages are queued.
LIBCOM_API int epicsStdCall epicsMessageQueueTryReceive ( epicsMessageQueueId  id,
void *  message,
unsigned int  size 
)

Try to receive a message.

If the queue holds at least one message, the first message on the queue is moved to the specified location and the length of that message is returned.

If the received message is larger than the specified message size the implementation may either return -1, or truncate the message. It is most efficient if the messageBufferSize is equal to the maximumMessageSize with which the message queue was created.

Returns
Number of bytes in the message.
-1 if the message queue is empty, or the buffer too small.

Definition at line 377 of file osdMessageQueue.cpp.

379 {
380  return myReceive(pmsg, message, size, 0);
381 }
LIBCOM_API int epicsStdCall epicsMessageQueueTrySend ( epicsMessageQueueId  id,
void *  message,
unsigned int  messageSize 
)

Try to send a message.

Note
On VxWorks and RTEMS this routine may be called from an interrupt handler.
Returns
0 if the message was sent to a receiver or queued for future delivery.
-1 if no more messages can be queued or if the message is larger than the queue's maximum message size.

Definition at line 256 of file osdMessageQueue.cpp.

258 {
259  return mySend(pmsg, message, size, 0);
260 }