Reputation: 584
What is the best way to handle signals for a Linux Message Queue (POSIX or SysV) with signals that have different sizes?
Suppose I have a process which could receive two or more different signals with different sizes. For example:
struct sig1 {
long mType;
char data[10];
};
struct sig2 {
long mType;
char data[20000];
};
Now, as I understand the message queue API, in order to receive these signals I need to make sure that I can provide a buffer for the data which is at least equal to the size of the largest message passed in the message queue.
int msgrcv(int msqid, void *msgp, size_t msgsz,
long msgtyp, int msgflg);
To me it seems impractical that I need to allocte a new buffer for every signal that I receive that is as large as the largest message passed in the queue. Or is there any way to poll the queue to know how large the message is before taking it out from the queue? Now in the extreme case I provided above I would need to allocate 20000 bytes for every signal received even though when the sig1 is received, only 10 bytes would suffice.
Suppose I have an application with high signaling load and signals with large different in sizes. Is there a good way to handle this case? Also, in a performance perspective, will I lose performance since I need to allocate larger buffers for every receive?
Upvotes: 0
Views: 769
Reputation: 129314
Sorry, complete rewrite, I confused the msgrcv
with reading from pipes and sockets, where each packet can be read in part or as a whole.
You need to have a receiving buffer that is large enough for the largest message of all that you may receive.
The actual size is returned as the return value from msgrcv
, so something like this:
struct sig2 msg;
size_t n = msgrcv(queue_id, &msg, sizeof(msg.data), -1, 0);
if (n == -1)
{
... error - inspect errno to understand what went wrong ...
}
Note also that the default size is 16384 bytes, so a 20000 byte array may not work unless you reconfigure the default message size.
Upvotes: 1