Message Queues are one of the better and comfortable ways to send/receive messages/data between threads within a process(or a separate process).You can see other ways at Inter-Process Data Transfer and Inter-Thread Communication.
A queue is generally created to handle messages of a given type of defined(fixed) length. The size of a queue, ie, maximum number of messages, or slots, it can contain is defined and fixed when the queue is created. The size of message for which a queue is created, and the size of the queue is arbitrary, being limited only by system resources.
A Message Queue can be :
- A global queue, which is visible to all processes
- A local queue, which is local to the current process and not visible to any other process
Usage of Message Queue
The member functions defined in RMsgQueue are: CreateGlobal(), CreateLocal(), Receive(), ReceiveBlocking(), Send(), SendBlocking()
Following are the neccessary steps to make use of a message queue:
- Create a queue
- Send data to the queue
- Receive message from the queue
- Other queue properites
Creating a Queue
RMsgQueue is the handle to a message queue.
class RMsgQueue : public RMsgQueueBase;
Here, RMsgQueueBase provides implementation for managing an asynchronous message queue, and is a base class for the RMsgQueue templated class.
The following code shows how to create a global message queue with message length of the above class(Here it is 8) and with 10 such number of messages.
const TInt KNumberOfMsgs = 10;
TInt ret = msgq.CreateGlobal(KGlobalQName, KNumberOfMsgs, EOwnerProcess);
Creating a local message queue is also similar, as shown below:
const TInt KNumberOfMsgs = 2;
TInt ret = msgq.CreateLocal(KNumberOfMsgs, EOwnerProcess);
Sending data to the Queue
Using the message queue handle, a message is sent to a queue by calling Send() or SendBlocking().
Here, if the queue is full, Send() returns the error code KErrOverflow and SendBlocking() waits until there is space available in the queue.
The following code creates a global queue and sends 2 integer to values to it. To demonstrate the usage of both Send() and SendBlocking(); the first call to Send() returns an error if the queue is full, the call to SendBlocking() waits until there is space in the queue.
//Create a global Queue
TInt ret = msgqueue.CreateGlobal(KGlobalQName,1);
if (ret == KErrNone) //If creation is success
TInt value = 100;
//KErrNone, if Send() successful; KErrOverflow, if queue is full
ret = msgqueue.Send(&value);
value = 200;
Receiving Messages from the Queue
Using the message queue handle, a message is received from a message queue by calling Receive() or ReceiveBlocking(). Receive() returns the error code KErrUnderflow if the queue is empty, ReceiveBlocking() waits until there is data in the queue.
TInt ret = msgqueue.OpenGlobal(KGlobalQName);
if (ret == KErrNone)
//Using Receive(), returns "KErrUnderflow" if queue is empty
ret = msgqueue.Receive(&msgfrmq);
Other Queue Properties
Other member functions inherited from RHandleBase are as follows:
- CancelDataAvailable() - Cancels an outstanding data available notification request.
- CancelSpaceAvailable() - Cancels an outstanding space available notification request.
- KMaxLength - Gets the size of message slots in the queue.
- MessageSize() - Gets the size of message slots in the queue.
- NotifyDataAvailable() - Requests notification when there is at least one message in the queue. A thread can have only one data available notification request outstanding on this message queue. If a second request is made before the first request completes, then the calling thread is panicked.
- NotifySpaceAvailable() - Requests notification when space becomes available in the queue. This is an asynchronous request that completes when there is at least one 'slot'available in the queue.
- Open() - Opens a global message queue using a handle passed in a server message.
- OpenGlobal() - Opens a global message queue using the name of the message queue.