mq_send() was not setting the errno value on certain failures to allocate a message

This commit is contained in:
Gregory Nutt 2016-09-15 12:42:24 -06:00
parent 368f241637
commit e3bbfa2d85
3 changed files with 32 additions and 11 deletions

View File

@ -133,6 +133,15 @@ int mq_send(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio)
leave_critical_section(flags); leave_critical_section(flags);
mqmsg = mq_msgalloc(); mqmsg = mq_msgalloc();
/* Check if the message was sucessfully allocated */
if (mqmsg == NULL)
{
/* No... mq_msgalloc() does not set the errno value */
set_errno(ENOMEM);
}
} }
else else
{ {
@ -141,6 +150,8 @@ int mq_send(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio)
* - We are not in an interrupt handler AND * - We are not in an interrupt handler AND
* - The message queue is full AND * - The message queue is full AND
* - When we tried waiting, the wait was unsuccessful. * - When we tried waiting, the wait was unsuccessful.
*
* In this case mq_waitsend() has already set the errno value.
*/ */
leave_critical_section(flags); leave_critical_section(flags);
@ -151,9 +162,10 @@ int mq_send(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio)
* to allocate it) or because the allocation failed. * to allocate it) or because the allocation failed.
*/ */
if (mqmsg) if (mqmsg != NULL)
{ {
/* Yes, perform the message send. /* The allocation was successful (implying that we can also send the
* message). Perform the message send.
* *
* NOTE: There is a race condition here: What if a message is added by * NOTE: There is a race condition here: What if a message is added by
* interrupt related logic so that queue again becomes non-empty. * interrupt related logic so that queue again becomes non-empty.

View File

@ -158,7 +158,7 @@ FAR struct mqueue_msg_s *mq_msgalloc(void)
/* Try the general free list */ /* Try the general free list */
mqmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&g_msgfree); mqmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&g_msgfree);
if (!mqmsg) if (mqmsg == NULL)
{ {
/* Try the free list reserved for interrupt handlers */ /* Try the free list reserved for interrupt handlers */
@ -178,18 +178,25 @@ FAR struct mqueue_msg_s *mq_msgalloc(void)
mqmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&g_msgfree); mqmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&g_msgfree);
leave_critical_section(flags); leave_critical_section(flags);
/* If we cannot a message from the free list, then we will have to allocate one. */ /* If we cannot a message from the free list, then we will have to
* allocate one.
*/
if (!mqmsg) if (mqmsg == NULL)
{ {
mqmsg = (FAR struct mqueue_msg_s *)kmm_malloc((sizeof (struct mqueue_msg_s))); mqmsg = (FAR struct mqueue_msg_s *)
kmm_malloc((sizeof (struct mqueue_msg_s)));
/* Check if we got an allocated message */ /* Check if we allocated the message */
if (mqmsg != NULL)
{
/* Yes... remember that this message was dynamically allocated */
ASSERT(mqmsg);
mqmsg->type = MQ_ALLOC_DYN; mqmsg->type = MQ_ALLOC_DYN;
} }
} }
}
return mqmsg; return mqmsg;
} }

View File

@ -192,9 +192,11 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
/* Pre-allocate a message structure */ /* Pre-allocate a message structure */
mqmsg = mq_msgalloc(); mqmsg = mq_msgalloc();
if (!mqmsg) if (mqmsg == NULL)
{ {
/* Failed to allocate the message */ /* Failed to allocate the message. mq_msgalloc() will have set the
* errno to ENOMEM.
*/
set_errno(ENOMEM); set_errno(ENOMEM);
return ERROR; return ERROR;