From e3bbfa2d8515a9cf83e4f9daef30c522f25835bd Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 15 Sep 2016 12:42:24 -0600 Subject: [PATCH] mq_send() was not setting the errno value on certain failures to allocate a message --- sched/mqueue/mq_send.c | 16 ++++++++++++++-- sched/mqueue/mq_sndinternal.c | 21 ++++++++++++++------- sched/mqueue/mq_timedsend.c | 6 ++++-- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/sched/mqueue/mq_send.c b/sched/mqueue/mq_send.c index df1500e035..12ce2b85c1 100644 --- a/sched/mqueue/mq_send.c +++ b/sched/mqueue/mq_send.c @@ -133,6 +133,15 @@ int mq_send(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio) leave_critical_section(flags); 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 { @@ -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 * - The message queue is full AND * - When we tried waiting, the wait was unsuccessful. + * + * In this case mq_waitsend() has already set the errno value. */ 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. */ - 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 * interrupt related logic so that queue again becomes non-empty. diff --git a/sched/mqueue/mq_sndinternal.c b/sched/mqueue/mq_sndinternal.c index 050d71269a..087e1f15dc 100644 --- a/sched/mqueue/mq_sndinternal.c +++ b/sched/mqueue/mq_sndinternal.c @@ -158,7 +158,7 @@ FAR struct mqueue_msg_s *mq_msgalloc(void) /* Try the general free list */ mqmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&g_msgfree); - if (!mqmsg) + if (mqmsg == NULL) { /* Try the free list reserved for interrupt handlers */ @@ -178,16 +178,23 @@ FAR struct mqueue_msg_s *mq_msgalloc(void) mqmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&g_msgfree); 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 */ - ASSERT(mqmsg); - mqmsg->type = MQ_ALLOC_DYN; + if (mqmsg != NULL) + { + /* Yes... remember that this message was dynamically allocated */ + + mqmsg->type = MQ_ALLOC_DYN; + } } } diff --git a/sched/mqueue/mq_timedsend.c b/sched/mqueue/mq_timedsend.c index 860e6223db..ffece37b8c 100644 --- a/sched/mqueue/mq_timedsend.c +++ b/sched/mqueue/mq_timedsend.c @@ -192,9 +192,11 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio, /* Pre-allocate a message structure */ 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); return ERROR;