MQ_SEND(2)

๐Ÿ“ฆ version 15.1, in freebsd 14.5, freebsd 15.1

๐Ÿ’Œ MQ_SEND(2) โ€” the system calls manual page, bestie edition ๐Ÿ’Œ

okay so welcome to mq_send(2), a page from section 2 of the System Calls Manual (that's the big book of syscalls), and honestly? she's giving realtime realness and I'm obsessed. sit down, grab a strawberry drink, we're learning how to yeet a message into a queue. ๐Ÿ“โœจ


โœจ NAME โœจ

mq_send, mq_timedsend โ€” send a message to message queue (REALTIME)

like. that's it. that's the job. you have a queue, you have a message, and these two besties make the introduction. ๐Ÿ’…


๐Ÿ“š LIBRARY ๐Ÿ“š

POSIX Real-time Library (librt, -lrt)

so when you're linking, that's -lrt, no cap. don't forget it or the linker will absolutely humble you.


๐Ÿซถ SYNOPSIS ๐Ÿซถ

#include <mqueue.h>

int
mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
    unsigned msg_prio);

int
mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
    unsigned msg_prio, const struct timespec *abs_timeout);

two functions, one glow-up: the plain one and the one with a deadline. ๐ŸŽ€


๐ŸŒธ DESCRIPTION ๐ŸŒธ

okay so mq_send() โ€” here's the vibe. it takes the message that msg_ptr is pointing at and adds it to the message queue identified by mqdes. the msg_len argument is the length of that message, in bytes, the one msg_ptr points to.

โš ๏ธ and the value of msg_len should be less than or equal to the mq_msgsize attribute of the message queue โ€” otherwise mq_send() will fail. respect the limit or get humbled, fr fr. ๐Ÿ˜ญ

if the queue is not full: mq_send() behaves like the message got inserted into the queue at the position indicated by the msg_prio argument. a message with a larger numeric value of msg_prio gets inserted before messages with lower values of msg_prio. a message gets inserted after other messages already in the queue (if any) that have equal msg_prio. and the value of msg_prio should be less than {MQ_PRIO_MAX}. priorities are literally the main character here, iykyk. ๐Ÿ‘‘

if the specified message queue is full and O_NONBLOCK is not set in the message queue description associated with mqdes, then mq_send() will block until space becomes available to enqueue the message, or until mq_send() is interrupted by a signal. it's giving "waiting in line at the club."

and if more than one thread is waiting to send when space becomes available in the message queue, and the Priority Scheduling option is supported, then the thread of the highest priority that has been waiting the longest will be unblocked to send its message. otherwise? it is unspecified which waiting thread is unblocked. so like... it's a mystery, we don't know, don't ask. ๐Ÿ’€

if the specified message queue is full and O_NONBLOCK is set in the message queue description associated with mqdes, the message will not be queued and mq_send() will return an error. no queue for you, bestie. ๐Ÿ™ˆ


now the glow-up: mq_timedsend(). it will add a message to the message queue specified by mqdes in the manner defined for the mq_send() system call. same energy. โœจ

however โ€” if the specified message queue is full and O_NONBLOCK is not set in the message queue description associated with mqdes, the wait for sufficient room in the queue will be terminated when the specified timeout expires. so you're not waiting forever, you have a deadline, growth. ๐Ÿฆ‹

and if O_NONBLOCK is set in the message queue description, this system call is equivalent to mq_send(). literally the same thing, just with a timeout argument it doesn't even use for waiting. iconic honestly.

when does the timeout expire? when the absolute time specified by abs_timeout passes, as measured by the clock on which timeouts are based โ€” that is, when the value of that clock equals or exceeds abs_timeout โ€” or if the absolute time specified by abs_timeout has already been passed at the time of the call. (yes, you can be late to your own party. ๐Ÿ˜ญ)

and the clock? the timeout is based on the CLOCK_REALTIME clock. periodt. โฐ


๐ŸŒˆ RETURN VALUES ๐ŸŒˆ

upon successful completion, mq_send() and mq_timedsend() return a value of zero. slay. โœ…

otherwise: no message will be enqueued, the system calls return -1, and the global variable errno is set to indicate the error. it's giving failure with full documentation. ๐Ÿ’…


๐Ÿ”ฅ ERRORS ๐Ÿ”ฅ

the mq_send() and mq_timedsend() system calls will fail if:

  • [EAGAIN] โ€” the O_NONBLOCK flag is set in the message queue description associated with mqdes, and the specified message queue is full. (queue's packed, go home.)
  • [EBADF] โ€” the mqdes argument is not a valid message queue descriptor open for writing. (that's not even a real door, bestie, and it's not one you can write through.)
  • [EINTR] โ€” a signal interrupted the call to mq_send() or mq_timedsend(). (rude, honestly.)
  • [EINVAL] โ€” the value of msg_prio was outside the valid range.
  • [EINVAL] โ€” the process or thread would have blocked, and the abs_timeout parameter specified a nanoseconds field value less than zero or greater than or equal to 1000 million. (nsec goes 0 to under a billion, that's the rule, don't fight it. ๐Ÿ’€)
  • [EMSGSIZE] โ€” the specified message length, msg_len, exceeds the message size attribute of the message queue. (too big. she doesn't fit. ๐ŸŽ€)
  • [ETIMEDOUT] โ€” the O_NONBLOCK flag was not set when the message queue was opened, but the timeout expired before the message could be added to the queue. (you waited, time ran out, tragic. ๐Ÿ˜ญ)
note that [EINVAL] shows up twice up there โ€” two completely different reasons, same error code. not a typo, that's just how she lives.

๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

the whole friend group, go read them next:


โญ STANDARDS โญ

the mq_send() and mq_timedsend() system calls conform to IEEE Std 1003.1-2004 (โ€œPOSIX.1โ€). certified, validated, official. ๐Ÿ‘‘


๐Ÿงš HISTORY ๐Ÿงš

support for POSIX message queues first appeared in FreeBSD 7.0. a little lore for you. ๐Ÿฆ‹


okay, legal corner, putting on my serious glasses for exactly one paragraph:

portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group. in the event of any discrepancy between this version and the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. the original Standard can be obtained online at http://www.opengroup.org/unix/online.html.


๐Ÿ’– and that's the whole page!! a whole Debian release from November 29, 2005, no cap โ€” she's been serving realtime correctness for two decades and she's still iconic. go send some messages, bestie, you've got this. ๐ŸŽ€โœจ๐ŸŒธ๐Ÿซถ
๐Ÿ“ฆ where this page comes from