mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 01:21:26 +08:00
Squashed commit of the following:
Change all calls to mq_send() and mq_timedsend() in the OS to calls to nxmq_send() and nxmq_timedsend(), making appropriate changes for differences in return values.
sched/mqueue: Add internal function nxmq_send() and nxmq_timedsend() that are equivalent to mq_send() and mq_timedsend() except that they do not create cancellation points and do to not modify the errno variable.
This commit is contained in:
+6
-5
@@ -53,8 +53,9 @@
|
|||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/mqueue.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/fs/fs.h>
|
||||||
#include <nuttx/audio/audio.h>
|
#include <nuttx/audio/audio.h>
|
||||||
#include <mqueue.h>
|
#include <mqueue.h>
|
||||||
|
|
||||||
@@ -716,8 +717,8 @@ static inline void audio_dequeuebuffer(FAR struct audio_upperhalf_s *upper,
|
|||||||
msg.session = session;
|
msg.session = session;
|
||||||
#endif
|
#endif
|
||||||
apb->flags |= AUDIO_APB_DEQUEUED;
|
apb->flags |= AUDIO_APB_DEQUEUED;
|
||||||
mq_send(upper->usermq, (FAR const char *)&msg, sizeof(msg),
|
(void)nxmq_send(upper->usermq, (FAR const char *)&msg, sizeof(msg),
|
||||||
CONFIG_AUDIO_BUFFER_DEQUEUE_PRIO);
|
CONFIG_AUDIO_BUFFER_DEQUEUE_PRIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -754,8 +755,8 @@ static inline void audio_complete(FAR struct audio_upperhalf_s *upper,
|
|||||||
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
||||||
msg.session = session;
|
msg.session = session;
|
||||||
#endif
|
#endif
|
||||||
mq_send(upper->usermq, (FAR const char *)&msg, sizeof(msg),
|
(void)nxmq_send(upper->usermq, (FAR const char *)&msg, sizeof(msg),
|
||||||
CONFIG_AUDIO_BUFFER_DEQUEUE_PRIO);
|
CONFIG_AUDIO_BUFFER_DEQUEUE_PRIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* A do-nothinig audio device driver to simplify testing of audio decoders.
|
* A do-nothinig audio device driver to simplify testing of audio decoders.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2014, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -53,6 +53,7 @@
|
|||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
|
#include <nuttx/mqueue.h>
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
#include <nuttx/fs/ioctl.h>
|
#include <nuttx/fs/ioctl.h>
|
||||||
#include <nuttx/audio/audio.h>
|
#include <nuttx/audio/audio.h>
|
||||||
@@ -589,8 +590,8 @@ static int null_stop(FAR struct audio_lowerhalf_s *dev)
|
|||||||
|
|
||||||
term_msg.msgId = AUDIO_MSG_STOP;
|
term_msg.msgId = AUDIO_MSG_STOP;
|
||||||
term_msg.u.data = 0;
|
term_msg.u.data = 0;
|
||||||
mq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
(void)nxmq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
||||||
CONFIG_AUDIO_NULL_MSG_PRIO);
|
CONFIG_AUDIO_NULL_MSG_PRIO);
|
||||||
|
|
||||||
/* Join the worker thread */
|
/* Join the worker thread */
|
||||||
|
|
||||||
|
|||||||
+9
-12
@@ -53,6 +53,7 @@
|
|||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
|
#include <nuttx/mqueue.h>
|
||||||
#include <nuttx/clock.h>
|
#include <nuttx/clock.h>
|
||||||
#include <nuttx/wqueue.h>
|
#include <nuttx/wqueue.h>
|
||||||
#include <nuttx/i2c/i2c_master.h>
|
#include <nuttx/i2c/i2c_master.h>
|
||||||
@@ -963,11 +964,11 @@ cs43l22_senddone(FAR struct i2s_dev_s *i2s,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
msg.msgId = AUDIO_MSG_COMPLETE;
|
msg.msgId = AUDIO_MSG_COMPLETE;
|
||||||
ret = mq_send(priv->mq, (FAR const char *)&msg, sizeof(msg),
|
ret = nxmq_send(priv->mq, (FAR const char *)&msg, sizeof(msg),
|
||||||
CONFIG_CS43L22_MSG_PRIO);
|
CONFIG_CS43L22_MSG_PRIO);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
auderr("ERROR: mq_send failed: %d\n", errno);
|
auderr("ERROR: nxmq_send failed: %d\n", ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1225,8 +1226,8 @@ static int cs43l22_stop(FAR struct audio_lowerhalf_s *dev)
|
|||||||
|
|
||||||
term_msg.msgId = AUDIO_MSG_STOP;
|
term_msg.msgId = AUDIO_MSG_STOP;
|
||||||
term_msg.u.data = 0;
|
term_msg.u.data = 0;
|
||||||
mq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
(void)nxmq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
||||||
CONFIG_CS43L22_MSG_PRIO);
|
CONFIG_CS43L22_MSG_PRIO);
|
||||||
|
|
||||||
/* Join the worker thread */
|
/* Join the worker thread */
|
||||||
|
|
||||||
@@ -1341,15 +1342,11 @@ static int cs43l22_enqueuebuffer(FAR struct audio_lowerhalf_s *dev,
|
|||||||
term_msg.msgId = AUDIO_MSG_ENQUEUE;
|
term_msg.msgId = AUDIO_MSG_ENQUEUE;
|
||||||
term_msg.u.data = 0;
|
term_msg.u.data = 0;
|
||||||
|
|
||||||
ret = mq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
ret = nxmq_send(priv->mq, (FAR const char *)&term_msg,
|
||||||
CONFIG_CS43L22_MSG_PRIO);
|
sizeof(term_msg), CONFIG_CS43L22_MSG_PRIO);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
int errcode = errno;
|
auderr("ERROR: nxmq_send failed: %d\n", ret);
|
||||||
DEBUGASSERT(errcode > 0);
|
|
||||||
|
|
||||||
auderr("ERROR: mq_send failed: %d\n", errcode);
|
|
||||||
UNUSED(errcode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
|
|
||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
#include <nuttx/signal.h>
|
#include <nuttx/signal.h>
|
||||||
|
#include <nuttx/mqueue.h>
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
#include <nuttx/fs/ioctl.h>
|
#include <nuttx/fs/ioctl.h>
|
||||||
#include <nuttx/audio/audio.h>
|
#include <nuttx/audio/audio.h>
|
||||||
@@ -1222,8 +1223,8 @@ static int vs1053_dreq_isr(int irq, FAR void *context, FAR void *arg)
|
|||||||
if (dev->running)
|
if (dev->running)
|
||||||
{
|
{
|
||||||
msg.msgId = AUDIO_MSG_DATA_REQUEST;
|
msg.msgId = AUDIO_MSG_DATA_REQUEST;
|
||||||
mq_send(dev->mq, (FAR const char *)&msg, sizeof(msg),
|
(void)nxmq_send(dev->mq, (FAR const char *)&msg, sizeof(msg),
|
||||||
CONFIG_VS1053_MSG_PRIO);
|
CONFIG_VS1053_MSG_PRIO);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1513,8 +1514,8 @@ static int vs1053_stop(FAR struct audio_lowerhalf_s *lower)
|
|||||||
|
|
||||||
term_msg.msgId = AUDIO_MSG_STOP;
|
term_msg.msgId = AUDIO_MSG_STOP;
|
||||||
term_msg.u.data = 0;
|
term_msg.u.data = 0;
|
||||||
mq_send(dev->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
(void)nxmq_send(dev->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
||||||
CONFIG_VS1053_MSG_PRIO);
|
CONFIG_VS1053_MSG_PRIO);
|
||||||
|
|
||||||
/* Join the worker thread */
|
/* Join the worker thread */
|
||||||
|
|
||||||
@@ -1627,8 +1628,8 @@ static int vs1053_enqueuebuffer(FAR struct audio_lowerhalf_s *lower,
|
|||||||
{
|
{
|
||||||
term_msg.msgId = AUDIO_MSG_ENQUEUE;
|
term_msg.msgId = AUDIO_MSG_ENQUEUE;
|
||||||
term_msg.u.data = 0;
|
term_msg.u.data = 0;
|
||||||
mq_send(dev->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
(void)nxmq_send(dev->mq, (FAR const char *)&term_msg,
|
||||||
CONFIG_VS1053_MSG_PRIO);
|
sizeof(term_msg), CONFIG_VS1053_MSG_PRIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-12
@@ -1360,11 +1360,11 @@ static void wm8904_senddone(FAR struct i2s_dev_s *i2s,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
msg.msgId = AUDIO_MSG_COMPLETE;
|
msg.msgId = AUDIO_MSG_COMPLETE;
|
||||||
ret = mq_send(priv->mq, (FAR const char *)&msg, sizeof(msg),
|
ret = nxmq_send(priv->mq, (FAR const char *)&msg, sizeof(msg),
|
||||||
CONFIG_WM8904_MSG_PRIO);
|
CONFIG_WM8904_MSG_PRIO);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
auderr("ERROR: mq_send failed: %d\n", errno);
|
auderr("ERROR: nxmq_send failed: %d\n", ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1622,8 +1622,8 @@ static int wm8904_stop(FAR struct audio_lowerhalf_s *dev)
|
|||||||
|
|
||||||
term_msg.msgId = AUDIO_MSG_STOP;
|
term_msg.msgId = AUDIO_MSG_STOP;
|
||||||
term_msg.u.data = 0;
|
term_msg.u.data = 0;
|
||||||
mq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
(void)nxmq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
||||||
CONFIG_WM8904_MSG_PRIO);
|
CONFIG_WM8904_MSG_PRIO);
|
||||||
|
|
||||||
/* Join the worker thread */
|
/* Join the worker thread */
|
||||||
|
|
||||||
@@ -1738,15 +1738,11 @@ static int wm8904_enqueuebuffer(FAR struct audio_lowerhalf_s *dev,
|
|||||||
term_msg.msgId = AUDIO_MSG_ENQUEUE;
|
term_msg.msgId = AUDIO_MSG_ENQUEUE;
|
||||||
term_msg.u.data = 0;
|
term_msg.u.data = 0;
|
||||||
|
|
||||||
ret = mq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
ret = nxmq_send(priv->mq, (FAR const char *)&term_msg,
|
||||||
CONFIG_WM8904_MSG_PRIO);
|
sizeof(term_msg), CONFIG_WM8904_MSG_PRIO);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
int errcode = errno;
|
auderr("ERROR: nxmq_send failed: %d\n", ret);
|
||||||
DEBUGASSERT(errcode > 0);
|
|
||||||
|
|
||||||
auderr("ERROR: mq_send failed: %d\n", errcode);
|
|
||||||
UNUSED(errcode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,7 @@
|
|||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
#include <nuttx/signal.h>
|
#include <nuttx/signal.h>
|
||||||
#include <nuttx/semaphore.h>
|
#include <nuttx/semaphore.h>
|
||||||
|
#include <nuttx/mqueue.h>
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
#include <nuttx/spi/spi.h>
|
#include <nuttx/spi/spi.h>
|
||||||
|
|
||||||
@@ -702,8 +703,9 @@ static void *cc3000_worker(FAR void *arg)
|
|||||||
priv->state = eSPI_STATE_READ_READY;
|
priv->state = eSPI_STATE_READ_READY;
|
||||||
priv->rx_buffer.len = data_to_recv;
|
priv->rx_buffer.len = data_to_recv;
|
||||||
|
|
||||||
ret = mq_send(priv->queue, (FAR const char *)&priv->rx_buffer,
|
ret = nxmq_send(priv->queue,
|
||||||
sizeof(priv->rx_buffer), 1);
|
(FAR const char *)&priv->rx_buffer,
|
||||||
|
sizeof(priv->rx_buffer), 1);
|
||||||
DEBUGASSERT(ret >= 0);
|
DEBUGASSERT(ret >= 0);
|
||||||
UNUSED(ret);
|
UNUSED(ret);
|
||||||
|
|
||||||
|
|||||||
+20
-10
@@ -55,11 +55,11 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mq_close_group
|
* Name: nxmq_close_group
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function is used to indicate that all threads in the group are
|
* This function is used to indicate that all threads in the group are
|
||||||
* finished with the specified message queue mqdes. The mq_close_group()
|
* finished with the specified message queue mqdes. The nxmq_close_group()
|
||||||
* deallocates any system resources allocated by the system for use by
|
* deallocates any system resources allocated by the system for use by
|
||||||
* this task for its message queue.
|
* this task for its message queue.
|
||||||
*
|
*
|
||||||
@@ -68,12 +68,12 @@
|
|||||||
* group - Group that has the open descriptor.
|
* group - Group that has the open descriptor.
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* 0 (OK) if the message queue is closed successfully,
|
* Zero (OK) if the message queue is closed successfully. Otherwise, a
|
||||||
* otherwise, -1 (ERROR).
|
* negated errno value is returned.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int mq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
|
int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
|
||||||
{
|
{
|
||||||
FAR struct mqueue_inode_s *msgq;
|
FAR struct mqueue_inode_s *msgq;
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
@@ -93,7 +93,7 @@ int mq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
|
|||||||
|
|
||||||
/* Close/free the message descriptor */
|
/* Close/free the message descriptor */
|
||||||
|
|
||||||
mq_desclose_group(mqdes, group);
|
nxmq_desclose_group(mqdes, group);
|
||||||
|
|
||||||
/* Get the inode from the message queue structure */
|
/* Get the inode from the message queue structure */
|
||||||
|
|
||||||
@@ -130,8 +130,8 @@ int mq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
|
|||||||
* otherwise, -1 (ERROR).
|
* otherwise, -1 (ERROR).
|
||||||
*
|
*
|
||||||
* Assumptions:
|
* Assumptions:
|
||||||
* - The behavior of a task that is blocked on either a mq_send() or
|
* - The behavior of a task that is blocked on either a [nx]mq_send() or
|
||||||
* mq_receive() is undefined when mq_close() is called.
|
* [nx]mq_receive() is undefined when mq_close() is called.
|
||||||
* - The results of using this message queue descriptor after a successful
|
* - The results of using this message queue descriptor after a successful
|
||||||
* return from mq_close() is undefined.
|
* return from mq_close() is undefined.
|
||||||
*
|
*
|
||||||
@@ -151,7 +151,17 @@ int mq_close(mqd_t mqdes)
|
|||||||
rtcb = (FAR struct tcb_s *)sched_self();
|
rtcb = (FAR struct tcb_s *)sched_self();
|
||||||
DEBUGASSERT(mqdes != NULL && rtcb != NULL && rtcb->group != NULL);
|
DEBUGASSERT(mqdes != NULL && rtcb != NULL && rtcb->group != NULL);
|
||||||
|
|
||||||
ret = mq_close_group(mqdes, rtcb->group);
|
/* Then perform the close operation */
|
||||||
|
|
||||||
|
ret = nxmq_close_group(mqdes, rtcb->group);
|
||||||
|
#if 0
|
||||||
|
if (ret < 0) /* Currently, nxmq_close_group() only returns OK */
|
||||||
|
{
|
||||||
|
set_errno(-ret);
|
||||||
|
ret = ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -193,7 +203,7 @@ void mq_inode_release(FAR struct inode *inode)
|
|||||||
|
|
||||||
/* Free the message queue (and any messages left in it) */
|
/* Free the message queue (and any messages left in it) */
|
||||||
|
|
||||||
mq_msgqfree(msgq);
|
nxmq_free_msgq(msgq);
|
||||||
inode->u.i_mqueue = NULL;
|
inode->u.i_mqueue = NULL;
|
||||||
|
|
||||||
/* Release and free the inode container. If it has been properly
|
/* Release and free the inode container. If it has been properly
|
||||||
|
|||||||
+4
-4
@@ -164,7 +164,7 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
|
|||||||
/* Create a message queue descriptor for the current thread */
|
/* Create a message queue descriptor for the current thread */
|
||||||
|
|
||||||
msgq = inode->u.i_mqueue;
|
msgq = inode->u.i_mqueue;
|
||||||
mqdes = mq_descreate(NULL, msgq, oflags);
|
mqdes = nxmq_create_des(NULL, msgq, oflags);
|
||||||
if (!mqdes)
|
if (!mqdes)
|
||||||
{
|
{
|
||||||
errcode = ENOMEM;
|
errcode = ENOMEM;
|
||||||
@@ -208,7 +208,7 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
|
|||||||
* be created with a reference count of zero.
|
* be created with a reference count of zero.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
msgq = (FAR struct mqueue_inode_s *)mq_msgqalloc(mode, attr);
|
msgq = (FAR struct mqueue_inode_s *)nxmq_alloc_msgq(mode, attr);
|
||||||
if (!msgq)
|
if (!msgq)
|
||||||
{
|
{
|
||||||
errcode = ENOSPC;
|
errcode = ENOSPC;
|
||||||
@@ -217,7 +217,7 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
|
|||||||
|
|
||||||
/* Create a message queue descriptor for the TCB */
|
/* Create a message queue descriptor for the TCB */
|
||||||
|
|
||||||
mqdes = mq_descreate(NULL, msgq, oflags);
|
mqdes = nxmq_create_des(NULL, msgq, oflags);
|
||||||
if (!mqdes)
|
if (!mqdes)
|
||||||
{
|
{
|
||||||
errcode = ENOMEM;
|
errcode = ENOMEM;
|
||||||
@@ -240,7 +240,7 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
|
|||||||
return mqdes;
|
return mqdes;
|
||||||
|
|
||||||
errout_with_msgq:
|
errout_with_msgq:
|
||||||
mq_msgqfree(msgq);
|
nxmq_free_msgq(msgq);
|
||||||
inode->u.i_mqueue = NULL;
|
inode->u.i_mqueue = NULL;
|
||||||
|
|
||||||
errout_with_inode:
|
errout_with_inode:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* graphics/nxmu/nxmu_sendclient.c
|
* graphics/nxmu/nxmu_sendclient.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2012, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -43,28 +43,10 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/mqueue.h>
|
||||||
|
|
||||||
#include "nxfe.h"
|
#include "nxfe.h"
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Types
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -102,10 +84,10 @@ int nxmu_sendclient(FAR struct nxfe_conn_s *conn, FAR const void *msg,
|
|||||||
|
|
||||||
/* Send the message to the client */
|
/* Send the message to the client */
|
||||||
|
|
||||||
ret = mq_send(conn->swrmq, msg, msglen, NX_CLIMSG_PRIO);
|
ret = nxmq_send(conn->swrmq, msg, msglen, NX_CLIMSG_PRIO);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
gerr("ERROR: mq_send failed: %d\n", errno);
|
gerr("ERROR: nxmq_send failed: %d\n", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
+125
-17
@@ -1,7 +1,8 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* include/nuttx/mqueue.h
|
* include/nuttx/mqueue.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009, 2011, 2014-2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009, 2011, 2014-2017 Gregory Nutt. All rights
|
||||||
|
* reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -56,6 +57,37 @@
|
|||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Most internal nxsig_* interfaces are not available in the user space in
|
||||||
|
* PROTECTED and KERNEL builds. In that context, the application signal
|
||||||
|
* interfaces must be used. The differences between the two sets of
|
||||||
|
* interfaces are: (1) the nxsig_* interfaces do not cause cancellation
|
||||||
|
* points and (2) they do not modify the errno variable.
|
||||||
|
*
|
||||||
|
* This is only important when compiling libraries (libc or libnx) that are
|
||||||
|
* used both by the OS (libkc.a and libknx.a) or by the applications
|
||||||
|
* (libuc.a and libunx.a). The that case, the correct interface must be
|
||||||
|
* used for the build context.
|
||||||
|
*
|
||||||
|
* The interfaces sigtimedwait(), sigwait(), sigwaitinfo(), sleep(),
|
||||||
|
* nanosleep(), and usleep() are cancellation points.
|
||||||
|
*
|
||||||
|
* REVISIT: The fact that these interfaces are cancellation points is an
|
||||||
|
* issue and may cause violations: It use of these internally will cause
|
||||||
|
* the calling function to become a cancellation points!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
|
||||||
|
# define _MQ_SEND(d,m,l,p) nxmq_send(d,m,l,p)
|
||||||
|
# define _MQ_TIMEDSEND(d,m,l,p,t) nxmq_send(d,m,l,p,t)
|
||||||
|
# define _MQ_ERRNO(r) (-(r))
|
||||||
|
# define _MQ_ERRVAL(r) (r)
|
||||||
|
#else
|
||||||
|
# define _MQ_SEND(d,m,l,p) mq_send(d,m,l,p)
|
||||||
|
# define _MQ_TIMEDSEND(d,m,l,p,t) mq_send(d,m,l,p,t)
|
||||||
|
# define _MQ_ERRNO(r) errno
|
||||||
|
# define _MQ_ERRVAL(r) (-errno)
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Type Declarations
|
* Public Type Declarations
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -111,12 +143,88 @@ extern "C"
|
|||||||
#define EXTERN extern
|
#define EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct mq_attr; /* Forward reference */
|
|
||||||
struct tcb_s; /* Forward reference */
|
struct tcb_s; /* Forward reference */
|
||||||
|
struct mq_attr; /* Forward reference */
|
||||||
|
struct timespec; /* Forward reference */
|
||||||
struct task_group_s; /* Forward reference */
|
struct task_group_s; /* Forward reference */
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mq_msgqfree
|
* Name: nxmq_send
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function adds the specified message (msg) to the message queue
|
||||||
|
* (mqdes). This is an internal OS interface. It is functionally
|
||||||
|
* equivalent to mq_send() except that:
|
||||||
|
*
|
||||||
|
* - It is not a cancellaction point, and
|
||||||
|
* - It does not modify the errno value.
|
||||||
|
*
|
||||||
|
* See comments with mq_send() for a more complete description of the
|
||||||
|
* behavior of this function
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mqdes - Message queue descriptor
|
||||||
|
* msg - Message to send
|
||||||
|
* msglen - The length of the message in bytes
|
||||||
|
* prio - The priority of the message
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* This is an internal OS interface and should not be used by applications.
|
||||||
|
* It follows the NuttX internal error return policy: Zero (OK) is
|
||||||
|
* returned on success. A negated errno value is returned on failure.
|
||||||
|
* (see mq_send() for the list list valid return values).
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int nxmq_send(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nxmq_timedsend
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function adds the specified message (msg) to the message queue
|
||||||
|
* (mqdes). nxmq_timedsend() behaves just like mq_send(), except that if
|
||||||
|
* the queue is full and the O_NONBLOCK flag is not enabled for the
|
||||||
|
* message queue description, then abstime points to a structure which
|
||||||
|
* specifies a ceiling on the time for which the call will block.
|
||||||
|
*
|
||||||
|
* nxmq_timedsend() is functionally equivalent to mq_timedsend() except
|
||||||
|
* that:
|
||||||
|
*
|
||||||
|
* - It is not a cancellaction point, and
|
||||||
|
* - It does not modify the errno value.
|
||||||
|
*
|
||||||
|
* See comments with mq_timedsend() for a more complete description of the
|
||||||
|
* behavior of this function
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mqdes - Message queue descriptor
|
||||||
|
* msg - Message to send
|
||||||
|
* msglen - The length of the message in bytes
|
||||||
|
* prio - The priority of the message
|
||||||
|
* abstime - the absolute time to wait until a timeout is decleared
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* This is an internal OS interface and should not be used by applications.
|
||||||
|
* It follows the NuttX internal error return policy: Zero (OK) is
|
||||||
|
* returned on success. A negated errno value is returned on failure.
|
||||||
|
* (see mq_timedsend() for the list list valid return values).
|
||||||
|
*
|
||||||
|
* EAGAIN The queue was empty, and the O_NONBLOCK flag was set for the
|
||||||
|
* message queue description referred to by mqdes.
|
||||||
|
* EINVAL Either msg or mqdes is NULL or the value of prio is invalid.
|
||||||
|
* EPERM Message queue opened not opened for writing.
|
||||||
|
* EMSGSIZE 'msglen' was greater than the maxmsgsize attribute of the
|
||||||
|
* message queue.
|
||||||
|
* EINTR The call was interrupted by a signal handler.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int nxmq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
||||||
|
FAR const struct timespec *abstime);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nxmq_free_msgq
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function deallocates an initialized message queue structure.
|
* This function deallocates an initialized message queue structure.
|
||||||
@@ -133,10 +241,10 @@ struct task_group_s; /* Forward reference */
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void mq_msgqfree(FAR struct mqueue_inode_s *msgq);
|
void nxmq_free_msgq(FAR struct mqueue_inode_s *msgq);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mq_msgqalloc
|
* Name: nxmq_alloc_msgq
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function implements a part of the POSIX message queue open logic.
|
* This function implements a part of the POSIX message queue open logic.
|
||||||
@@ -154,11 +262,11 @@ void mq_msgqfree(FAR struct mqueue_inode_s *msgq);
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
FAR struct mqueue_inode_s *mq_msgqalloc(mode_t mode,
|
FAR struct mqueue_inode_s *nxmq_alloc_msgq(mode_t mode,
|
||||||
FAR struct mq_attr *attr);
|
FAR struct mq_attr *attr);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mq_descreate
|
* Name: nxmq_create_des
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Create a message queue descriptor for the specified TCB
|
* Create a message queue descriptor for the specified TCB
|
||||||
@@ -174,15 +282,15 @@ FAR struct mqueue_inode_s *mq_msgqalloc(mode_t mode,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
mqd_t mq_descreate(FAR struct tcb_s *mtcb, FAR struct mqueue_inode_s *msgq,
|
mqd_t nxmq_create_des(FAR struct tcb_s *mtcb,
|
||||||
int oflags);
|
FAR struct mqueue_inode_s *msgq, int oflags);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mq_close_group
|
* Name: nxmq_close_group
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function is used to indicate that all threads in the group are
|
* This function is used to indicate that all threads in the group are
|
||||||
* finished with the specified message queue mqdes. The mq_close_group()
|
* finished with the specified message queue mqdes. nxmq_close_group()
|
||||||
* deallocates any system resources allocated by the system for use by
|
* deallocates any system resources allocated by the system for use by
|
||||||
* this task for its message queue.
|
* this task for its message queue.
|
||||||
*
|
*
|
||||||
@@ -191,15 +299,15 @@ mqd_t mq_descreate(FAR struct tcb_s *mtcb, FAR struct mqueue_inode_s *msgq,
|
|||||||
* group - Group that has the open descriptor.
|
* group - Group that has the open descriptor.
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* 0 (OK) if the message queue is closed successfully,
|
* Zero (OK) if the message queue is closed successfully. Otherwise, a
|
||||||
* otherwise, -1 (ERROR).
|
* negated errno value is returned.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int mq_close_group(mqd_t mqdes, FAR struct task_group_s *group);
|
int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mq_desclose_group
|
* Name: nxmq_desclose_group
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function performs the portion of the mq_close operation related
|
* This function performs the portion of the mq_close operation related
|
||||||
@@ -217,7 +325,7 @@ int mq_close_group(mqd_t mqdes, FAR struct task_group_s *group);
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void mq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group);
|
void nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group);
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* libnx/nxmu/nxmu_sendserver.c
|
* libnx/nxmu/nxmu_sendserver.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2012-2013, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/mqueue.h>
|
||||||
#include <nuttx/nx/nxmu.h>
|
#include <nuttx/nx/nxmu.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -82,10 +83,10 @@ int nxmu_sendserver(FAR struct nxfe_conn_s *conn, FAR const void *msg,
|
|||||||
|
|
||||||
/* Send the message to the server */
|
/* Send the message to the server */
|
||||||
|
|
||||||
ret = mq_send(conn->cwrmq, msg, msglen, NX_SVRMSG_PRIO);
|
ret = _MQ_SEND(conn->cwrmq, msg, msglen, NX_SVRMSG_PRIO);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
gerr("ERROR: mq_send failed: %d\n", errno);
|
gerr("ERROR: _MQ_SEND failed: %d\n", _MQ_ERRNO(rer));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/mqueue/mq_desclose.c
|
* sched/mqueue/mq_desclose.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009, 2013-2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009, 2013-2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mq_desclose_group
|
* Name: nxmq_desclose_group
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function performs the portion of the mq_close operation related
|
* This function performs the portion of the mq_close operation related
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void mq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group)
|
void nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group)
|
||||||
{
|
{
|
||||||
FAR struct mqueue_inode_s *msgq;
|
FAR struct mqueue_inode_s *msgq;
|
||||||
|
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ static mqd_t nxmq_alloc_des(void)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mq_descreate
|
* Name: nxmq_create_des
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Create a message queue descriptor for the specified TCB
|
* Create a message queue descriptor for the specified TCB
|
||||||
@@ -120,8 +120,8 @@ static mqd_t nxmq_alloc_des(void)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
mqd_t mq_descreate(FAR struct tcb_s *mtcb, FAR struct mqueue_inode_s *msgq,
|
mqd_t nxmq_create_des(FAR struct tcb_s *mtcb,
|
||||||
int oflags)
|
FAR struct mqueue_inode_s *msgq, int oflags)
|
||||||
{
|
{
|
||||||
FAR struct task_group_s *group;
|
FAR struct task_group_s *group;
|
||||||
mqd_t mqdes;
|
mqd_t mqdes;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/mqueue/mq_msgqalloc.c
|
* sched/mqueue/mq_msgqalloc.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2014, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mq_msgqalloc
|
* Name: nxmq_alloc_msgq
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function implements a part of the POSIX message queue open logic.
|
* This function implements a part of the POSIX message queue open logic.
|
||||||
@@ -72,8 +72,8 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
FAR struct mqueue_inode_s *mq_msgqalloc(mode_t mode,
|
FAR struct mqueue_inode_s *nxmq_alloc_msgq(mode_t mode,
|
||||||
FAR struct mq_attr *attr)
|
FAR struct mq_attr *attr)
|
||||||
{
|
{
|
||||||
FAR struct mqueue_inode_s *msgq;
|
FAR struct mqueue_inode_s *msgq;
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mq_msgqfree
|
* Name: nxmq_free_msgq
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function deallocates an initialized message queue structure.
|
* This function deallocates an initialized message queue structure.
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void mq_msgqfree(FAR struct mqueue_inode_s *msgq)
|
void nxmq_free_msgq(FAR struct mqueue_inode_s *msgq)
|
||||||
{
|
{
|
||||||
FAR struct mqueue_msg_s *curr;
|
FAR struct mqueue_msg_s *curr;
|
||||||
FAR struct mqueue_msg_s *next;
|
FAR struct mqueue_msg_s *next;
|
||||||
|
|||||||
@@ -67,6 +67,6 @@ void nxmq_release(FAR struct task_group_s *group)
|
|||||||
{
|
{
|
||||||
while (group->tg_msgdesq.head)
|
while (group->tg_msgdesq.head)
|
||||||
{
|
{
|
||||||
mq_close_group((mqd_t)group->tg_msgdesq.head, group);
|
(void)nxmq_close_group((mqd_t)group->tg_msgdesq.head, group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+107
-66
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/mqueue/mq_send.c
|
* sched/mqueue/mq_send.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009, 2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009, 2016-2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -55,67 +55,48 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mq_send
|
* Name: nxmq_send
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function adds the specified message (msg) to the message queue
|
* This function adds the specified message (msg) to the message queue
|
||||||
* (mqdes). The "msglen" parameter specifies the length of the message
|
* (mqdes). This is an internal OS interface. It is functionally
|
||||||
* in bytes pointed to by "msg." This length must not exceed the maximum
|
* equivalent to mq_send() except that:
|
||||||
* message length from the mq_getattr().
|
|
||||||
*
|
*
|
||||||
* If the message queue is not full, mq_send() place the message in the
|
* - It is not a cancellaction point, and
|
||||||
* message queue at the position indicated by the "prio" argument.
|
* - It does not modify the errno value.
|
||||||
* Messages with higher priority will be inserted before lower priority
|
|
||||||
* messages. The value of "prio" must not exceed MQ_PRIO_MAX.
|
|
||||||
*
|
*
|
||||||
* If the specified message queue is full and O_NONBLOCK is not set in the
|
* See comments with mq_send() for a more complete description of the
|
||||||
* message queue, then mq_send() will block until space becomes available
|
* behavior of this function
|
||||||
* to the queue the message.
|
|
||||||
*
|
*
|
||||||
* If the message queue is full and O_NONBLOCK is set, the message is not
|
* Input Parameters:
|
||||||
* queued and ERROR is returned.
|
* mqdes - Message queue descriptor
|
||||||
*
|
* msg - Message to send
|
||||||
* Parameters:
|
|
||||||
* mqdes - Message queue descriptor
|
|
||||||
* msg - Message to send
|
|
||||||
* msglen - The length of the message in bytes
|
* msglen - The length of the message in bytes
|
||||||
* prio - The priority of the message
|
* prio - The priority of the message
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Returned Value:
|
||||||
* On success, mq_send() returns 0 (OK); on error, -1 (ERROR)
|
* This is an internal OS interface and should not be used by applications.
|
||||||
* is returned, with errno set to indicate the error:
|
* It follows the NuttX internal error return policy: Zero (OK) is
|
||||||
*
|
* returned on success. A negated errno value is returned on failure.
|
||||||
* EAGAIN The queue was full and the O_NONBLOCK flag was set for the
|
* (see mq_send() for the list list valid return values).
|
||||||
* message queue description referred to by mqdes.
|
|
||||||
* EINVAL Either msg or mqdes is NULL or the value of prio is invalid.
|
|
||||||
* EPERM Message queue opened not opened for writing.
|
|
||||||
* EMSGSIZE 'msglen' was greater than the maxmsgsize attribute of the
|
|
||||||
* message queue.
|
|
||||||
* EINTR The call was interrupted by a signal handler.
|
|
||||||
*
|
|
||||||
* Assumptions/restrictions:
|
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int mq_send(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio)
|
int nxmq_send(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio)
|
||||||
{
|
{
|
||||||
FAR struct mqueue_inode_s *msgq;
|
FAR struct mqueue_inode_s *msgq;
|
||||||
FAR struct mqueue_msg_s *mqmsg = NULL;
|
FAR struct mqueue_msg_s *mqmsg = NULL;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
int ret = ERROR;
|
int ret;
|
||||||
|
|
||||||
/* mq_send() is a cancellation point */
|
|
||||||
|
|
||||||
(void)enter_cancellation_point();
|
|
||||||
|
|
||||||
/* Verify the input parameters -- setting errno appropriately
|
/* Verify the input parameters -- setting errno appropriately
|
||||||
* on any failures to verify.
|
* on any failures to verify.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (nxmq_verify_send(mqdes, msg, msglen, prio) != OK)
|
ret = nxmq_verify_send(mqdes, msg, msglen, prio);
|
||||||
|
if (ret < 0);
|
||||||
{
|
{
|
||||||
leave_cancellation_point();
|
return ret;
|
||||||
return ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a pointer to the message queue */
|
/* Get a pointer to the message queue */
|
||||||
@@ -130,37 +111,36 @@ int mq_send(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio)
|
|||||||
* non-FULL. This would fail with EAGAIN, EINTR, or ETIMEOUT.
|
* non-FULL. This would fail with EAGAIN, EINTR, or ETIMEOUT.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
mqmsg = NULL;
|
||||||
flags = enter_critical_section();
|
flags = enter_critical_section();
|
||||||
if (up_interrupt_context() || /* In an interrupt handler */
|
ret = OK;
|
||||||
msgq->nmsgs < msgq->maxmsgs || /* OR Message queue not full */
|
|
||||||
nxmq_wait_send(mqdes) == OK) /* OR Successfully waited for mq not full */
|
if (!up_interrupt_context()) /* In an interrupt handler? */
|
||||||
{
|
{
|
||||||
/* Allocate the message */
|
/* No.. Not in an interrupt handler. Is the message queue FULL? */
|
||||||
|
|
||||||
|
if (msgq->nmsgs >= msgq->maxmsgs) /* Message queue not-FULL? */
|
||||||
|
{
|
||||||
|
/* Yes.. the message queue is full. Wait for space to become
|
||||||
|
* available in the message queue.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = nxmq_wait_send(mqdes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ret can only be negative if nxmq_wait_send failed */
|
||||||
|
|
||||||
|
leave_critical_section(flags);
|
||||||
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
/* Now allocate the message. */
|
||||||
|
|
||||||
leave_critical_section(flags);
|
|
||||||
mqmsg = nxmq_alloc_msg();
|
mqmsg = nxmq_alloc_msg();
|
||||||
|
|
||||||
/* Check if the message was sucessfully allocated */
|
/* Check if the message was sucessfully allocated */
|
||||||
|
|
||||||
if (mqmsg == NULL)
|
ret = (mqmsg == NULL) ? -ENOMEM : OK;
|
||||||
{
|
|
||||||
/* No... nxmq_alloc_msg() does not set the errno value */
|
|
||||||
|
|
||||||
set_errno(ENOMEM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* We cannot send the message (and didn't even try to allocate it)
|
|
||||||
* because:
|
|
||||||
* - 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 nxmq_wait_send() has already set the errno value.
|
|
||||||
*/
|
|
||||||
|
|
||||||
leave_critical_section(flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we were able to get a message structure -- this can fail
|
/* Check if we were able to get a message structure -- this can fail
|
||||||
@@ -183,6 +163,67 @@ int mq_send(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mq_send
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function adds the specified message (msg) to the message queue
|
||||||
|
* (mqdes). The "msglen" parameter specifies the length of the message
|
||||||
|
* in bytes pointed to by "msg." This length must not exceed the maximum
|
||||||
|
* message length from the mq_getattr().
|
||||||
|
*
|
||||||
|
* If the message queue is not full, mq_send() place the message in the
|
||||||
|
* message queue at the position indicated by the "prio" argument.
|
||||||
|
* Messages with higher priority will be inserted before lower priority
|
||||||
|
* messages. The value of "prio" must not exceed MQ_PRIO_MAX.
|
||||||
|
*
|
||||||
|
* If the specified message queue is full and O_NONBLOCK is not set in the
|
||||||
|
* message queue, then mq_send() will block until space becomes available
|
||||||
|
* to the queue the message.
|
||||||
|
*
|
||||||
|
* If the message queue is full and O_NONBLOCK is set, the message is not
|
||||||
|
* queued and ERROR is returned.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mqdes - Message queue descriptor
|
||||||
|
* msg - Message to send
|
||||||
|
* msglen - The length of the message in bytes
|
||||||
|
* prio - The priority of the message
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* On success, mq_send() returns 0 (OK); on error, -1 (ERROR)
|
||||||
|
* is returned, with errno set to indicate the error:
|
||||||
|
*
|
||||||
|
* EAGAIN The queue was full and the O_NONBLOCK flag was set for the
|
||||||
|
* message queue description referred to by mqdes.
|
||||||
|
* EINVAL Either msg or mqdes is NULL or the value of prio is invalid.
|
||||||
|
* EPERM Message queue opened not opened for writing.
|
||||||
|
* EMSGSIZE 'msglen' was greater than the maxmsgsize attribute of the
|
||||||
|
* message queue.
|
||||||
|
* EINTR The call was interrupted by a signal handler.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mq_send(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* mq_send() is a cancellation point */
|
||||||
|
|
||||||
|
(void)enter_cancellation_point();
|
||||||
|
|
||||||
|
/* Let nxmq_send() do all of the work */
|
||||||
|
|
||||||
|
ret = nxmq_send(mqdes, msg, msglen, prio);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
set_errno(-ret);
|
||||||
|
ret = ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
leave_cancellation_point();
|
leave_cancellation_point();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,26 +69,24 @@
|
|||||||
* Name: nxmq_verify_send
|
* Name: nxmq_verify_send
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This is internal, common logic shared by both mq_send and mq_timesend.
|
* This is internal, common logic shared by both [nx]mq_send and
|
||||||
* This function verifies the input parameters that are common to both
|
* [nx]mq_timesend. This function verifies the input parameters that are
|
||||||
* functions.
|
* common to both functions.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Input Parameters:
|
||||||
* mqdes - Message queue descriptor
|
* mqdes - Message queue descriptor
|
||||||
* msg - Message to send
|
* msg - Message to send
|
||||||
* msglen - The length of the message in bytes
|
* msglen - The length of the message in bytes
|
||||||
* prio - The priority of the message
|
* prio - The priority of the message
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Returned Value:
|
||||||
* One success, 0 (OK) is returned. On failure, -1 (ERROR) is returned and
|
* One success, 0 (OK) is returned. On failure, a negated errno value is
|
||||||
* the errno is set appropriately:
|
* returned.
|
||||||
*
|
*
|
||||||
* EINVAL Either msg or mqdes is NULL or the value of prio is invalid.
|
* EINVAL Either msg or mqdes is NULL or the value of prio is invalid.
|
||||||
* EPERM Message queue opened not opened for writing.
|
* EPERM Message queue opened not opened for writing.
|
||||||
* EMSGSIZE 'msglen' was greater than the maxmsgsize attribute of the
|
* EMSGSIZE 'msglen' was greater than the maxmsgsize attribute of the
|
||||||
* message queue.
|
* message queue.
|
||||||
*
|
|
||||||
* Assumptions:
|
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
@@ -99,20 +97,17 @@ int nxmq_verify_send(mqd_t mqdes, FAR const char *msg, size_t msglen,
|
|||||||
|
|
||||||
if (!msg || !mqdes || prio < 0 || prio > MQ_PRIO_MAX)
|
if (!msg || !mqdes || prio < 0 || prio > MQ_PRIO_MAX)
|
||||||
{
|
{
|
||||||
set_errno(EINVAL);
|
return -EINVAL;
|
||||||
return ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mqdes->oflags & O_WROK) == 0)
|
if ((mqdes->oflags & O_WROK) == 0)
|
||||||
{
|
{
|
||||||
set_errno(EPERM);
|
return -EPERM;
|
||||||
return ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msglen > (size_t)mqdes->msgq->maxmsgsize)
|
if (msglen > (size_t)mqdes->msgq->maxmsgsize)
|
||||||
{
|
{
|
||||||
set_errno(EMSGSIZE);
|
return -EMSGSIZE;
|
||||||
return ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
@@ -139,7 +134,7 @@ int nxmq_verify_send(mqd_t mqdes, FAR const char *msg, size_t msglen,
|
|||||||
* Inputs:
|
* Inputs:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Returned Value:
|
||||||
* A reference to the allocated msg structure. On a failure to allocate,
|
* A reference to the allocated msg structure. On a failure to allocate,
|
||||||
* this function PANICs.
|
* this function PANICs.
|
||||||
*
|
*
|
||||||
@@ -207,15 +202,16 @@ FAR struct mqueue_msg_s *nxmq_alloc_msg(void)
|
|||||||
* Name: nxmq_wait_send
|
* Name: nxmq_wait_send
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This is internal, common logic shared by both mq_send and mq_timesend.
|
* This is internal, common logic shared by both [nx]mq_send and
|
||||||
* This function waits until the message queue is not full.
|
* [nx]mq_timesend. This function waits until the message queue is not
|
||||||
|
* full.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Input Parameters:
|
||||||
* mqdes - Message queue descriptor
|
* mqdes - Message queue descriptor
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Returned Value:
|
||||||
* On success, mq_send() returns 0 (OK); on error, -1 (ERROR) is
|
* On success, nxmq_wait_send() returns 0 (OK); a negated errno value is
|
||||||
* returned, with errno set to indicate the error:
|
* returned on any failure:
|
||||||
*
|
*
|
||||||
* EAGAIN The queue was full and the O_NONBLOCK flag was set for the
|
* EAGAIN The queue was full and the O_NONBLOCK flag was set for the
|
||||||
* message queue description referred to by mqdes.
|
* message queue description referred to by mqdes.
|
||||||
@@ -233,23 +229,22 @@ int nxmq_wait_send(mqd_t mqdes)
|
|||||||
{
|
{
|
||||||
FAR struct tcb_s *rtcb;
|
FAR struct tcb_s *rtcb;
|
||||||
FAR struct mqueue_inode_s *msgq;
|
FAR struct mqueue_inode_s *msgq;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* nxmq_wait_send() is not a cancellation point, but it is always called from
|
#ifdef CONFIG_CANCELLATION_POINTS
|
||||||
* a cancellation point.
|
/* nxmq_wait_send() is not a cancellation point, but may be called via
|
||||||
|
* mq_send() or mq_timedsend() which are cancellation points.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (enter_cancellation_point())
|
if (check_cancellation_point())
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_CANCELLATION_POINTS
|
|
||||||
/* If there is a pending cancellation, then do not perform
|
/* If there is a pending cancellation, then do not perform
|
||||||
* the wait. Exit now with ECANCELED.
|
* the wait. Exit now with ECANCELED.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
set_errno(ECANCELED);
|
return -ECANCELED;
|
||||||
leave_cancellation_point();
|
|
||||||
return ERROR;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Get a pointer to the message queue */
|
/* Get a pointer to the message queue */
|
||||||
|
|
||||||
@@ -267,9 +262,7 @@ int nxmq_wait_send(mqd_t mqdes)
|
|||||||
{
|
{
|
||||||
/* No... We will return an error to the caller. */
|
/* No... We will return an error to the caller. */
|
||||||
|
|
||||||
set_errno(EAGAIN);
|
return -EAGAIN;
|
||||||
leave_cancellation_point();
|
|
||||||
return ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Yes... We will not return control until the message queue is
|
/* Yes... We will not return control until the message queue is
|
||||||
@@ -284,33 +277,42 @@ int nxmq_wait_send(mqd_t mqdes)
|
|||||||
|
|
||||||
while (msgq->nmsgs >= msgq->maxmsgs)
|
while (msgq->nmsgs >= msgq->maxmsgs)
|
||||||
{
|
{
|
||||||
|
int saved_errno;
|
||||||
|
|
||||||
/* Block until the message queue is no longer full.
|
/* Block until the message queue is no longer full.
|
||||||
* When we are unblocked, we will try again
|
* When we are unblocked, we will try again
|
||||||
*/
|
*/
|
||||||
|
|
||||||
rtcb = this_task();
|
rtcb = this_task();
|
||||||
rtcb->msgwaitq = msgq;
|
rtcb->msgwaitq = msgq;
|
||||||
msgq->nwaitnotfull++;
|
msgq->nwaitnotfull++;
|
||||||
|
|
||||||
set_errno(OK);
|
/* "Borrow" the per-task errno to communication wake-up error
|
||||||
|
* conditions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
saved_errno = rtcb->pterrno;
|
||||||
|
rtcb->pterrno = OK;
|
||||||
|
|
||||||
up_block_task(rtcb, TSTATE_WAIT_MQNOTFULL);
|
up_block_task(rtcb, TSTATE_WAIT_MQNOTFULL);
|
||||||
|
|
||||||
/* When we resume at this point, either (1) the message queue
|
/* When we resume at this point, either (1) the message queue
|
||||||
* is no longer empty, or (2) the wait has been interrupted by
|
* is no longer empty, or (2) the wait has been interrupted by
|
||||||
* a signal. We can detect the latter case be examining the
|
* a signal. We can detect the latter case be examining the
|
||||||
* errno value (should be EINTR or ETIMEOUT).
|
* per-task errno value (should be EINTR or ETIMEOUT).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (get_errno() != OK)
|
ret = rtcb->pterrno;
|
||||||
|
rtcb->pterrno = saved_errno;
|
||||||
|
|
||||||
|
if (ret != OK)
|
||||||
{
|
{
|
||||||
leave_cancellation_point();
|
return -ret;
|
||||||
return ERROR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_cancellation_point();
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,23 +320,21 @@ int nxmq_wait_send(mqd_t mqdes)
|
|||||||
* Name: nxmq_do_send
|
* Name: nxmq_do_send
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This is internal, common logic shared by both mq_send and mq_timesend.
|
* This is internal, common logic shared by both [nx]mq_send and
|
||||||
* This function adds the specified message (msg) to the message queue
|
* [nx]mq_timesend. This function adds the specified message (msg) to the
|
||||||
* (mqdes). Then it notifies any tasks that were waiting for message
|
* message queue (mqdes). Then it notifies any tasks that were waiting
|
||||||
* queue notifications setup by mq_notify. And, finally, it awakens any
|
* for message queue notifications setup by mq_notify. And, finally, it
|
||||||
* tasks that were waiting for the message not empty event.
|
* awakens any tasks that were waiting for the message not empty event.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Input Parameters:
|
||||||
* mqdes - Message queue descriptor
|
* mqdes - Message queue descriptor
|
||||||
* msg - Message to send
|
* msg - Message to send
|
||||||
* msglen - The length of the message in bytes
|
* msglen - The length of the message in bytes
|
||||||
* prio - The priority of the message
|
* prio - The priority of the message
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Returned Value:
|
||||||
* This function always returns OK.
|
* This function always returns OK.
|
||||||
*
|
*
|
||||||
* Assumptions/restrictions:
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int nxmq_do_send(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg,
|
int nxmq_do_send(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg,
|
||||||
|
|||||||
+114
-65
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/mqueue/mq_timedsend.c
|
* sched/mqueue/mq_timedsend.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2011, 2013-2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2011, 2013-2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -67,11 +67,11 @@
|
|||||||
* This function is called if the timeout elapses before the message queue
|
* This function is called if the timeout elapses before the message queue
|
||||||
* becomes non-full.
|
* becomes non-full.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Input Parameters:
|
||||||
* argc - the number of arguments (should be 1)
|
* argc - the number of arguments (should be 1)
|
||||||
* pid - the task ID of the task to wakeup
|
* pid - the task ID of the task to wakeup
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Assumptions:
|
* Assumptions:
|
||||||
@@ -99,7 +99,7 @@ static void nxmq_sndtimeout(int argc, wdparm_t pid)
|
|||||||
* punch and already changed the task's state.
|
* punch and already changed the task's state.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (wtcb && wtcb->task_state == TSTATE_WAIT_MQNOTFULL)
|
if (wtcb != NULL && wtcb->task_state == TSTATE_WAIT_MQNOTFULL)
|
||||||
{
|
{
|
||||||
/* Restart with task with a timeout error */
|
/* Restart with task with a timeout error */
|
||||||
|
|
||||||
@@ -116,43 +116,36 @@ static void nxmq_sndtimeout(int argc, wdparm_t pid)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mq_send
|
* Name: nxmq_timedsend
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function adds the specificied message (msg) to the message queue
|
* This function adds the specified message (msg) to the message queue
|
||||||
* (mqdes). The "msglen" parameter specifies the length of the message
|
* (mqdes). nxmq_timedsend() behaves just like mq_send(), except
|
||||||
* in bytes pointed to by "msg." This length must not exceed the maximum
|
* that if the queue is full and the O_NONBLOCK flag is not enabled for
|
||||||
* message length from the mq_getattr().
|
* the message queue description, then abstime points to a structure which
|
||||||
|
* specifies a ceiling on the time for which the call will block.
|
||||||
*
|
*
|
||||||
* If the message queue is not full, mq_timedsend() place the message in the
|
* nxmq_timedsend() is functionally equivalent to mq_timedsend() except
|
||||||
* message queue at the position indicated by the "prio" argrument.
|
* that:
|
||||||
* Messages with higher priority will be inserted before lower priority
|
|
||||||
* messages. The value of "prio" must not exceed MQ_PRIO_MAX.
|
|
||||||
*
|
*
|
||||||
* If the specified message queue is full and O_NONBLOCK is not set in the
|
* - It is not a cancellaction point, and
|
||||||
* message queue, then mq_timedsend() will block until space becomes available
|
* - It does not modify the errno value.
|
||||||
* to the queue the message or a timeout occurs.
|
|
||||||
*
|
*
|
||||||
* mq_timedsend() behaves just like mq_send(), except that if the queue
|
* See comments with mq_timedsend() for a more complete description of the
|
||||||
* is full and the O_NONBLOCK flag is not enabled for the message queue
|
* behavior of this function
|
||||||
* description, then abstime points to a structure which specifies a
|
|
||||||
* ceiling on the time for which the call will block. This ceiling is an
|
|
||||||
* absolute timeout in seconds and nanoseconds since the Epoch (midnight
|
|
||||||
* on the morning of 1 January 1970).
|
|
||||||
*
|
*
|
||||||
* If the message queue is full, and the timeout has already expired by
|
* Input Parameters:
|
||||||
* the time of the call, mq_timedsend() returns immediately.
|
* mqdes - Message queue descriptor
|
||||||
*
|
* msg - Message to send
|
||||||
* Parameters:
|
* msglen - The length of the message in bytes
|
||||||
* mqdes - Message queue descriptor
|
* prio - The priority of the message
|
||||||
* msg - Message to send
|
|
||||||
* msglen - The length of the message in bytes
|
|
||||||
* prio - The priority of the message
|
|
||||||
* abstime - the absolute time to wait until a timeout is decleared
|
* abstime - the absolute time to wait until a timeout is decleared
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Returned Value:
|
||||||
* On success, mq_send() returns 0 (OK); on error, -1 (ERROR)
|
* This is an internal OS interface and should not be used by applications.
|
||||||
* is returned, with errno set to indicate the error:
|
* It follows the NuttX internal error return policy: Zero (OK) is
|
||||||
|
* returned on success. A negated errno value is returned on failure.
|
||||||
|
* (see mq_timedsend() for the list list valid return values).
|
||||||
*
|
*
|
||||||
* EAGAIN The queue was empty, and the O_NONBLOCK flag was set for the
|
* EAGAIN The queue was empty, and the O_NONBLOCK flag was set for the
|
||||||
* message queue description referred to by mqdes.
|
* message queue description referred to by mqdes.
|
||||||
@@ -162,12 +155,10 @@ static void nxmq_sndtimeout(int argc, wdparm_t pid)
|
|||||||
* message queue.
|
* message queue.
|
||||||
* EINTR The call was interrupted by a signal handler.
|
* EINTR The call was interrupted by a signal handler.
|
||||||
*
|
*
|
||||||
* Assumptions/restrictions:
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
int nxmq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
||||||
FAR const struct timespec *abstime)
|
FAR const struct timespec *abstime)
|
||||||
{
|
{
|
||||||
FAR struct tcb_s *rtcb = this_task();
|
FAR struct tcb_s *rtcb = this_task();
|
||||||
FAR struct mqueue_inode_s *msgq;
|
FAR struct mqueue_inode_s *msgq;
|
||||||
@@ -175,24 +166,16 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
|||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
ssystime_t ticks;
|
ssystime_t ticks;
|
||||||
int result;
|
int result;
|
||||||
int ret = ERROR;
|
int ret;
|
||||||
|
|
||||||
DEBUGASSERT(up_interrupt_context() == false && rtcb->waitdog == NULL);
|
DEBUGASSERT(up_interrupt_context() == false && rtcb->waitdog == NULL);
|
||||||
|
|
||||||
/* mq_timedsend() is a cancellation point */
|
/* Verify the input parameters on any failures to verify. */
|
||||||
|
|
||||||
(void)enter_cancellation_point();
|
ret = nxmq_verify_send(mqdes, msg, msglen, prio);
|
||||||
|
if (ret < 0)
|
||||||
/* Verify the input parameters -- setting errno appropriately
|
|
||||||
* on any failures to verify.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (nxmq_verify_send(mqdes, msg, msglen, prio) != OK)
|
|
||||||
{
|
{
|
||||||
/* nxmq_verify_send() will set the errno appropriately */
|
return ret;
|
||||||
|
|
||||||
leave_cancellation_point();
|
|
||||||
return ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pre-allocate a message structure */
|
/* Pre-allocate a message structure */
|
||||||
@@ -204,9 +187,7 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
|||||||
* errno value.
|
* errno value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
set_errno(ENOMEM);
|
return -ENOMEM;
|
||||||
leave_cancellation_point();
|
|
||||||
return ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a pointer to the message queue */
|
/* Get a pointer to the message queue */
|
||||||
@@ -236,7 +217,6 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
|||||||
|
|
||||||
ret = nxmq_do_send(mqdes, mqmsg, msg, msglen, prio);
|
ret = nxmq_do_send(mqdes, mqmsg, msg, msglen, prio);
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
leave_cancellation_point();
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,7 +226,7 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
|||||||
|
|
||||||
if (!abstime || abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
|
if (!abstime || abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
|
||||||
{
|
{
|
||||||
result = EINVAL;
|
ret = -EINVAL;
|
||||||
goto errout_with_mqmsg;
|
goto errout_with_mqmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,7 +238,7 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
|||||||
rtcb->waitdog = wd_create();
|
rtcb->waitdog = wd_create();
|
||||||
if (!rtcb->waitdog)
|
if (!rtcb->waitdog)
|
||||||
{
|
{
|
||||||
result = EINVAL;
|
ret = -EINVAL;
|
||||||
goto errout_with_mqmsg;
|
goto errout_with_mqmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,7 +249,7 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
|||||||
* disabled here so that this time stays valid until the wait begins.
|
* disabled here so that this time stays valid until the wait begins.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = enter_critical_section();
|
||||||
result = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
|
result = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
|
||||||
|
|
||||||
/* If the time has already expired and the message queue is empty,
|
/* If the time has already expired and the message queue is empty,
|
||||||
@@ -285,6 +265,7 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
|||||||
|
|
||||||
if (result != OK)
|
if (result != OK)
|
||||||
{
|
{
|
||||||
|
ret = -result;
|
||||||
goto errout_in_critical_section;
|
goto errout_in_critical_section;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,9 +287,8 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
|||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
/* nxmq_wait_send() will set the errno, but the error exit will reset it */
|
/* nxmq_wait_send() failed. */
|
||||||
|
|
||||||
result = get_errno();
|
|
||||||
goto errout_in_critical_section;
|
goto errout_in_critical_section;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,8 +312,7 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Exit here with (1) the scheduler locked, (2) a message allocated, (3) a
|
/* Exit here with (1) the scheduler locked, (2) a message allocated, (3) a
|
||||||
* wdog allocated, and (4) interrupts disabled. The error code is in
|
* wdog allocated, and (4) interrupts disabled.
|
||||||
* 'result'
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
errout_in_critical_section:
|
errout_in_critical_section:
|
||||||
@@ -348,8 +327,78 @@ errout_in_critical_section:
|
|||||||
errout_with_mqmsg:
|
errout_with_mqmsg:
|
||||||
nxmq_free_msg(mqmsg);
|
nxmq_free_msg(mqmsg);
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
|
return ret;
|
||||||
set_errno(result);
|
}
|
||||||
leave_cancellation_point();
|
|
||||||
return ERROR;
|
/****************************************************************************
|
||||||
|
* Name: mq_timedsend
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function adds the specified message (msg) to the message queue
|
||||||
|
* (mqdes). The "msglen" parameter specifies the length of the message
|
||||||
|
* in bytes pointed to by "msg." This length must not exceed the maximum
|
||||||
|
* message length from the mq_getattr().
|
||||||
|
*
|
||||||
|
* If the message queue is not full, mq_timedsend() place the message in the
|
||||||
|
* message queue at the position indicated by the "prio" argrument.
|
||||||
|
* Messages with higher priority will be inserted before lower priority
|
||||||
|
* messages. The value of "prio" must not exceed MQ_PRIO_MAX.
|
||||||
|
*
|
||||||
|
* If the specified message queue is full and O_NONBLOCK is not set in the
|
||||||
|
* message queue, then mq_timedsend() will block until space becomes available
|
||||||
|
* to the queue the message or a timeout occurs.
|
||||||
|
*
|
||||||
|
* mq_timedsend() behaves just like mq_send(), except that if the queue
|
||||||
|
* is full and the O_NONBLOCK flag is not enabled for the message queue
|
||||||
|
* description, then abstime points to a structure which specifies a
|
||||||
|
* ceiling on the time for which the call will block. This ceiling is an
|
||||||
|
* absolute timeout in seconds and nanoseconds since the Epoch (midnight
|
||||||
|
* on the morning of 1 January 1970).
|
||||||
|
*
|
||||||
|
* If the message queue is full, and the timeout has already expired by
|
||||||
|
* the time of the call, mq_timedsend() returns immediately.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mqdes - Message queue descriptor
|
||||||
|
* msg - Message to send
|
||||||
|
* msglen - The length of the message in bytes
|
||||||
|
* prio - The priority of the message
|
||||||
|
* abstime - the absolute time to wait until a timeout is decleared
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* On success, mq_send() returns 0 (OK); on error, -1 (ERROR)
|
||||||
|
* is returned, with errno set to indicate the error:
|
||||||
|
*
|
||||||
|
* EAGAIN The queue was empty, and the O_NONBLOCK flag was set for the
|
||||||
|
* message queue description referred to by mqdes.
|
||||||
|
* EINVAL Either msg or mqdes is NULL or the value of prio is invalid.
|
||||||
|
* EPERM Message queue opened not opened for writing.
|
||||||
|
* EMSGSIZE 'msglen' was greater than the maxmsgsize attribute of the
|
||||||
|
* message queue.
|
||||||
|
* EINTR The call was interrupted by a signal handler.
|
||||||
|
*
|
||||||
|
* Assumptions/restrictions:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
||||||
|
FAR const struct timespec *abstime)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* mq_timedsend() is a cancellation point */
|
||||||
|
|
||||||
|
(void)enter_cancellation_point();
|
||||||
|
|
||||||
|
/* Let nxmq_send() do all of the work */
|
||||||
|
|
||||||
|
ret = nxmq_timedsend(mqdes, msg, msglen, prio, abstime);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
set_errno(-ret);
|
||||||
|
ret = ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex,
|
|||||||
|
|
||||||
if (status == -EINTR)
|
if (status == -EINTR)
|
||||||
{
|
{
|
||||||
serr("ERROR: Timedout!\n");
|
swarn("WARNING: Timedout!\n");
|
||||||
ret = ETIMEDOUT;
|
ret = ETIMEDOUT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -112,14 +112,16 @@ int pthread_sem_take(sem_t *sem, bool intr)
|
|||||||
ret = nxsem_wait(sem);
|
ret = nxsem_wait(sem);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
/* The only case that an error should occur here is if the wait
|
/* The only cases that an error should occur here is if the wait
|
||||||
* was awakened by a signal.
|
* was awakened by a signal or if the thread was canceled during
|
||||||
|
* the wait.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DEBUGASSERT(ret == -EINTR);
|
DEBUGASSERT(ret == -EINTR || ret == -ECANCELED);
|
||||||
|
|
||||||
/* When the signal is received, should we errout? Or should we
|
/* When the error occurs in this case, should we errout? Or
|
||||||
* just continue waiting until we have the semaphore?
|
* should we just continue waiting until we have the
|
||||||
|
* semaphore?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (intr)
|
if (intr)
|
||||||
|
|||||||
@@ -124,17 +124,17 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
pjoin = pthread_findjoininfo(group, (pid_t)thread);
|
pjoin = pthread_findjoininfo(group, (pid_t)thread);
|
||||||
if (!pjoin)
|
if (pjoin == NULL)
|
||||||
{
|
{
|
||||||
/* Determine what kind of error to return */
|
/* Determine what kind of error to return */
|
||||||
|
|
||||||
FAR struct tcb_s *tcb = sched_gettcb((pthread_t)thread);
|
FAR struct tcb_s *tcb = sched_gettcb((pthread_t)thread);
|
||||||
|
|
||||||
serr("ERROR: Could not find thread data\n");
|
swarn("WARNING: Could not find thread data\n");
|
||||||
|
|
||||||
/* Case (1) or (3) -- we can't tell which. Assume (3) */
|
/* Case (1) or (3) -- we can't tell which. Assume (3) */
|
||||||
|
|
||||||
if (!tcb)
|
if (tcb == NULL)
|
||||||
{
|
{
|
||||||
ret = ESRCH;
|
ret = ESRCH;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user