mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 07:28:38 +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:
parent
c5a5a5a1b6
commit
fca07be1df
22 changed files with 497 additions and 306 deletions
|
@ -53,8 +53,9 @@
|
|||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/mqueue.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/audio/audio.h>
|
||||
#include <mqueue.h>
|
||||
|
||||
|
@ -716,8 +717,8 @@ static inline void audio_dequeuebuffer(FAR struct audio_upperhalf_s *upper,
|
|||
msg.session = session;
|
||||
#endif
|
||||
apb->flags |= AUDIO_APB_DEQUEUED;
|
||||
mq_send(upper->usermq, (FAR const char *)&msg, sizeof(msg),
|
||||
CONFIG_AUDIO_BUFFER_DEQUEUE_PRIO);
|
||||
(void)nxmq_send(upper->usermq, (FAR const char *)&msg, sizeof(msg),
|
||||
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
|
||||
msg.session = session;
|
||||
#endif
|
||||
mq_send(upper->usermq, (FAR const char *)&msg, sizeof(msg),
|
||||
CONFIG_AUDIO_BUFFER_DEQUEUE_PRIO);
|
||||
(void)nxmq_send(upper->usermq, (FAR const char *)&msg, sizeof(msg),
|
||||
CONFIG_AUDIO_BUFFER_DEQUEUE_PRIO);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* 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>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -53,6 +53,7 @@
|
|||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/mqueue.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/ioctl.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.u.data = 0;
|
||||
mq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
||||
CONFIG_AUDIO_NULL_MSG_PRIO);
|
||||
(void)nxmq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
||||
CONFIG_AUDIO_NULL_MSG_PRIO);
|
||||
|
||||
/* Join the worker thread */
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/mqueue.h>
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
|
@ -963,11 +964,11 @@ cs43l22_senddone(FAR struct i2s_dev_s *i2s,
|
|||
*/
|
||||
|
||||
msg.msgId = AUDIO_MSG_COMPLETE;
|
||||
ret = mq_send(priv->mq, (FAR const char *)&msg, sizeof(msg),
|
||||
CONFIG_CS43L22_MSG_PRIO);
|
||||
ret = nxmq_send(priv->mq, (FAR const char *)&msg, sizeof(msg),
|
||||
CONFIG_CS43L22_MSG_PRIO);
|
||||
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.u.data = 0;
|
||||
mq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
||||
CONFIG_CS43L22_MSG_PRIO);
|
||||
(void)nxmq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
||||
CONFIG_CS43L22_MSG_PRIO);
|
||||
|
||||
/* 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.u.data = 0;
|
||||
|
||||
ret = mq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
||||
CONFIG_CS43L22_MSG_PRIO);
|
||||
ret = nxmq_send(priv->mq, (FAR const char *)&term_msg,
|
||||
sizeof(term_msg), CONFIG_CS43L22_MSG_PRIO);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
DEBUGASSERT(errcode > 0);
|
||||
|
||||
auderr("ERROR: mq_send failed: %d\n", errcode);
|
||||
UNUSED(errcode);
|
||||
auderr("ERROR: nxmq_send failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/signal.h>
|
||||
#include <nuttx/mqueue.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/ioctl.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)
|
||||
{
|
||||
msg.msgId = AUDIO_MSG_DATA_REQUEST;
|
||||
mq_send(dev->mq, (FAR const char *)&msg, sizeof(msg),
|
||||
CONFIG_VS1053_MSG_PRIO);
|
||||
(void)nxmq_send(dev->mq, (FAR const char *)&msg, sizeof(msg),
|
||||
CONFIG_VS1053_MSG_PRIO);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1513,8 +1514,8 @@ static int vs1053_stop(FAR struct audio_lowerhalf_s *lower)
|
|||
|
||||
term_msg.msgId = AUDIO_MSG_STOP;
|
||||
term_msg.u.data = 0;
|
||||
mq_send(dev->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
||||
CONFIG_VS1053_MSG_PRIO);
|
||||
(void)nxmq_send(dev->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
||||
CONFIG_VS1053_MSG_PRIO);
|
||||
|
||||
/* 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.u.data = 0;
|
||||
mq_send(dev->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
||||
CONFIG_VS1053_MSG_PRIO);
|
||||
(void)nxmq_send(dev->mq, (FAR const char *)&term_msg,
|
||||
sizeof(term_msg), CONFIG_VS1053_MSG_PRIO);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1360,11 +1360,11 @@ static void wm8904_senddone(FAR struct i2s_dev_s *i2s,
|
|||
*/
|
||||
|
||||
msg.msgId = AUDIO_MSG_COMPLETE;
|
||||
ret = mq_send(priv->mq, (FAR const char *)&msg, sizeof(msg),
|
||||
CONFIG_WM8904_MSG_PRIO);
|
||||
ret = nxmq_send(priv->mq, (FAR const char *)&msg, sizeof(msg),
|
||||
CONFIG_WM8904_MSG_PRIO);
|
||||
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.u.data = 0;
|
||||
mq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
||||
CONFIG_WM8904_MSG_PRIO);
|
||||
(void)nxmq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
||||
CONFIG_WM8904_MSG_PRIO);
|
||||
|
||||
/* 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.u.data = 0;
|
||||
|
||||
ret = mq_send(priv->mq, (FAR const char *)&term_msg, sizeof(term_msg),
|
||||
CONFIG_WM8904_MSG_PRIO);
|
||||
ret = nxmq_send(priv->mq, (FAR const char *)&term_msg,
|
||||
sizeof(term_msg), CONFIG_WM8904_MSG_PRIO);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
DEBUGASSERT(errcode > 0);
|
||||
|
||||
auderr("ERROR: mq_send failed: %d\n", errcode);
|
||||
UNUSED(errcode);
|
||||
auderr("ERROR: nxmq_send failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
#include <nuttx/arch.h>
|
||||
#include <nuttx/signal.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/mqueue.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/spi/spi.h>
|
||||
|
||||
|
@ -702,8 +703,9 @@ static void *cc3000_worker(FAR void *arg)
|
|||
priv->state = eSPI_STATE_READ_READY;
|
||||
priv->rx_buffer.len = data_to_recv;
|
||||
|
||||
ret = mq_send(priv->queue, (FAR const char *)&priv->rx_buffer,
|
||||
sizeof(priv->rx_buffer), 1);
|
||||
ret = nxmq_send(priv->queue,
|
||||
(FAR const char *)&priv->rx_buffer,
|
||||
sizeof(priv->rx_buffer), 1);
|
||||
DEBUGASSERT(ret >= 0);
|
||||
UNUSED(ret);
|
||||
|
||||
|
|
|
@ -55,11 +55,11 @@
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_close_group
|
||||
* Name: nxmq_close_group
|
||||
*
|
||||
* Description:
|
||||
* 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
|
||||
* this task for its message queue.
|
||||
*
|
||||
|
@ -68,12 +68,12 @@
|
|||
* group - Group that has the open descriptor.
|
||||
*
|
||||
* Return Value:
|
||||
* 0 (OK) if the message queue is closed successfully,
|
||||
* otherwise, -1 (ERROR).
|
||||
* Zero (OK) if the message queue is closed successfully. Otherwise, a
|
||||
* 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 inode *inode;
|
||||
|
@ -93,7 +93,7 @@ int mq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
|
|||
|
||||
/* Close/free the message descriptor */
|
||||
|
||||
mq_desclose_group(mqdes, group);
|
||||
nxmq_desclose_group(mqdes, group);
|
||||
|
||||
/* 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).
|
||||
*
|
||||
* Assumptions:
|
||||
* - The behavior of a task that is blocked on either a mq_send() or
|
||||
* mq_receive() is undefined when mq_close() is called.
|
||||
* - The behavior of a task that is blocked on either a [nx]mq_send() or
|
||||
* [nx]mq_receive() is undefined when mq_close() is called.
|
||||
* - The results of using this message queue descriptor after a successful
|
||||
* return from mq_close() is undefined.
|
||||
*
|
||||
|
@ -151,7 +151,17 @@ int mq_close(mqd_t mqdes)
|
|||
rtcb = (FAR struct tcb_s *)sched_self();
|
||||
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();
|
||||
return ret;
|
||||
}
|
||||
|
@ -193,7 +203,7 @@ void mq_inode_release(FAR struct inode *inode)
|
|||
|
||||
/* Free the message queue (and any messages left in it) */
|
||||
|
||||
mq_msgqfree(msgq);
|
||||
nxmq_free_msgq(msgq);
|
||||
inode->u.i_mqueue = NULL;
|
||||
|
||||
/* Release and free the inode container. If it has been properly
|
||||
|
|
|
@ -164,7 +164,7 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
|
|||
/* Create a message queue descriptor for the current thread */
|
||||
|
||||
msgq = inode->u.i_mqueue;
|
||||
mqdes = mq_descreate(NULL, msgq, oflags);
|
||||
mqdes = nxmq_create_des(NULL, msgq, oflags);
|
||||
if (!mqdes)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
|
||||
msgq = (FAR struct mqueue_inode_s *)mq_msgqalloc(mode, attr);
|
||||
msgq = (FAR struct mqueue_inode_s *)nxmq_alloc_msgq(mode, attr);
|
||||
if (!msgq)
|
||||
{
|
||||
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 */
|
||||
|
||||
mqdes = mq_descreate(NULL, msgq, oflags);
|
||||
mqdes = nxmq_create_des(NULL, msgq, oflags);
|
||||
if (!mqdes)
|
||||
{
|
||||
errcode = ENOMEM;
|
||||
|
@ -240,7 +240,7 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
|
|||
return mqdes;
|
||||
|
||||
errout_with_msgq:
|
||||
mq_msgqfree(msgq);
|
||||
nxmq_free_msgq(msgq);
|
||||
inode->u.i_mqueue = NULL;
|
||||
|
||||
errout_with_inode:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -43,28 +43,10 @@
|
|||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/mqueue.h>
|
||||
|
||||
#include "nxfe.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private 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 */
|
||||
|
||||
ret = mq_send(conn->swrmq, msg, msglen, NX_CLIMSG_PRIO);
|
||||
ret = nxmq_send(conn->swrmq, msg, msglen, NX_CLIMSG_PRIO);
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("ERROR: mq_send failed: %d\n", errno);
|
||||
gerr("ERROR: nxmq_send failed: %d\n", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -56,6 +57,37 @@
|
|||
* 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
|
||||
****************************************************************************/
|
||||
|
@ -111,12 +143,88 @@ extern "C"
|
|||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
struct mq_attr; /* Forward reference */
|
||||
struct tcb_s; /* Forward reference */
|
||||
struct mq_attr; /* Forward reference */
|
||||
struct timespec; /* 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:
|
||||
* 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:
|
||||
* 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 mq_attr *attr);
|
||||
FAR struct mqueue_inode_s *nxmq_alloc_msgq(mode_t mode,
|
||||
FAR struct mq_attr *attr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_descreate
|
||||
* Name: nxmq_create_des
|
||||
*
|
||||
* Description:
|
||||
* 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,
|
||||
int oflags);
|
||||
mqd_t nxmq_create_des(FAR struct tcb_s *mtcb,
|
||||
FAR struct mqueue_inode_s *msgq, int oflags);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_close_group
|
||||
* Name: nxmq_close_group
|
||||
*
|
||||
* Description:
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* Return Value:
|
||||
* 0 (OK) if the message queue is closed successfully,
|
||||
* otherwise, -1 (ERROR).
|
||||
* Zero (OK) if the message queue is closed successfully. Otherwise, a
|
||||
* 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:
|
||||
* 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
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -43,6 +43,7 @@
|
|||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/mqueue.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 */
|
||||
|
||||
ret = mq_send(conn->cwrmq, msg, msglen, NX_SVRMSG_PRIO);
|
||||
ret = _MQ_SEND(conn->cwrmq, msg, msglen, NX_SVRMSG_PRIO);
|
||||
if (ret < 0)
|
||||
{
|
||||
gerr("ERROR: mq_send failed: %d\n", errno);
|
||||
gerr("ERROR: _MQ_SEND failed: %d\n", _MQ_ERRNO(rer));
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -72,7 +72,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_desclose_group
|
||||
* Name: nxmq_desclose_group
|
||||
*
|
||||
* Description:
|
||||
* 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;
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ static mqd_t nxmq_alloc_des(void)
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_descreate
|
||||
* Name: nxmq_create_des
|
||||
*
|
||||
* Description:
|
||||
* 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,
|
||||
int oflags)
|
||||
mqd_t nxmq_create_des(FAR struct tcb_s *mtcb,
|
||||
FAR struct mqueue_inode_s *msgq, int oflags)
|
||||
{
|
||||
FAR struct task_group_s *group;
|
||||
mqd_t mqdes;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -54,7 +54,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_msgqalloc
|
||||
* Name: nxmq_alloc_msgq
|
||||
*
|
||||
* Description:
|
||||
* 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 mq_attr *attr)
|
||||
FAR struct mqueue_inode_s *nxmq_alloc_msgq(mode_t mode,
|
||||
FAR struct mq_attr *attr)
|
||||
{
|
||||
FAR struct mqueue_inode_s *msgq;
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_msgqfree
|
||||
* Name: nxmq_free_msgq
|
||||
*
|
||||
* Description:
|
||||
* 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 *next;
|
||||
|
|
|
@ -67,6 +67,6 @@ void nxmq_release(FAR struct task_group_s *group)
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -55,67 +55,48 @@
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_send
|
||||
* Name: nxmq_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().
|
||||
* (mqdes). This is an internal OS interface. It is functionally
|
||||
* equivalent to mq_send() except that:
|
||||
*
|
||||
* 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.
|
||||
* - It is not a cancellaction point, and
|
||||
* - It does not modify the errno value.
|
||||
*
|
||||
* 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.
|
||||
* See comments with mq_send() for a more complete description of the
|
||||
* behavior of this function
|
||||
*
|
||||
* If the message queue is full and O_NONBLOCK is set, the message is not
|
||||
* queued and ERROR is returned.
|
||||
*
|
||||
* Parameters:
|
||||
* mqdes - Message queue descriptor
|
||||
* msg - Message to send
|
||||
* Input Parameters:
|
||||
* mqdes - Message queue descriptor
|
||||
* msg - Message to send
|
||||
* msglen - The length of the message in bytes
|
||||
* prio - The priority of the message
|
||||
* prio - The priority of the message
|
||||
*
|
||||
* Return 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.
|
||||
*
|
||||
* Assumptions/restrictions:
|
||||
* 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 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_msg_s *mqmsg = NULL;
|
||||
irqstate_t flags;
|
||||
int ret = ERROR;
|
||||
|
||||
/* mq_send() is a cancellation point */
|
||||
|
||||
(void)enter_cancellation_point();
|
||||
int ret;
|
||||
|
||||
/* Verify the input parameters -- setting errno appropriately
|
||||
* 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 ERROR;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
mqmsg = NULL;
|
||||
flags = enter_critical_section();
|
||||
if (up_interrupt_context() || /* In an interrupt handler */
|
||||
msgq->nmsgs < msgq->maxmsgs || /* OR Message queue not full */
|
||||
nxmq_wait_send(mqdes) == OK) /* OR Successfully waited for mq not full */
|
||||
{
|
||||
/* Allocate the message */
|
||||
ret = OK;
|
||||
|
||||
if (!up_interrupt_context()) /* In an interrupt handler? */
|
||||
{
|
||||
/* 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();
|
||||
|
||||
/* Check if the message was sucessfully allocated */
|
||||
|
||||
if (mqmsg == NULL)
|
||||
{
|
||||
/* 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);
|
||||
ret = (mqmsg == NULL) ? -ENOMEM : OK;
|
||||
}
|
||||
|
||||
/* 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();
|
||||
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();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -69,26 +69,24 @@
|
|||
* Name: nxmq_verify_send
|
||||
*
|
||||
* Description:
|
||||
* This is internal, common logic shared by both mq_send and mq_timesend.
|
||||
* This function verifies the input parameters that are common to both
|
||||
* functions.
|
||||
* This is internal, common logic shared by both [nx]mq_send and
|
||||
* [nx]mq_timesend. This function verifies the input parameters that are
|
||||
* common to both functions.
|
||||
*
|
||||
* Parameters:
|
||||
* Input Parameters:
|
||||
* mqdes - Message queue descriptor
|
||||
* msg - Message to send
|
||||
* msglen - The length of the message in bytes
|
||||
* prio - The priority of the message
|
||||
*
|
||||
* Return Value:
|
||||
* One success, 0 (OK) is returned. On failure, -1 (ERROR) is returned and
|
||||
* the errno is set appropriately:
|
||||
* Returned Value:
|
||||
* One success, 0 (OK) is returned. On failure, a negated errno value is
|
||||
* returned.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Assumptions:
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((mqdes->oflags & O_WROK) == 0)
|
||||
{
|
||||
set_errno(EPERM);
|
||||
return ERROR;
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (msglen > (size_t)mqdes->msgq->maxmsgsize)
|
||||
{
|
||||
set_errno(EMSGSIZE);
|
||||
return ERROR;
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
@ -139,7 +134,7 @@ int nxmq_verify_send(mqd_t mqdes, FAR const char *msg, size_t msglen,
|
|||
* Inputs:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* Returned Value:
|
||||
* A reference to the allocated msg structure. On a failure to allocate,
|
||||
* this function PANICs.
|
||||
*
|
||||
|
@ -207,15 +202,16 @@ FAR struct mqueue_msg_s *nxmq_alloc_msg(void)
|
|||
* Name: nxmq_wait_send
|
||||
*
|
||||
* Description:
|
||||
* This is internal, common logic shared by both mq_send and mq_timesend.
|
||||
* This function waits until the message queue is not full.
|
||||
* This is internal, common logic shared by both [nx]mq_send and
|
||||
* [nx]mq_timesend. This function waits until the message queue is not
|
||||
* full.
|
||||
*
|
||||
* Parameters:
|
||||
* Input Parameters:
|
||||
* mqdes - Message queue descriptor
|
||||
*
|
||||
* Return Value:
|
||||
* On success, mq_send() returns 0 (OK); on error, -1 (ERROR) is
|
||||
* returned, with errno set to indicate the error:
|
||||
* Returned Value:
|
||||
* On success, nxmq_wait_send() returns 0 (OK); a negated errno value is
|
||||
* returned on any failure:
|
||||
*
|
||||
* EAGAIN The queue was full and the O_NONBLOCK flag was set for the
|
||||
* 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 mqueue_inode_s *msgq;
|
||||
int ret;
|
||||
|
||||
/* nxmq_wait_send() is not a cancellation point, but it is always called from
|
||||
* a cancellation point.
|
||||
#ifdef CONFIG_CANCELLATION_POINTS
|
||||
/* 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
|
||||
* the wait. Exit now with ECANCELED.
|
||||
*/
|
||||
|
||||
set_errno(ECANCELED);
|
||||
leave_cancellation_point();
|
||||
return ERROR;
|
||||
#endif
|
||||
return -ECANCELED;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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. */
|
||||
|
||||
set_errno(EAGAIN);
|
||||
leave_cancellation_point();
|
||||
return ERROR;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
int saved_errno;
|
||||
|
||||
/* Block until the message queue is no longer full.
|
||||
* When we are unblocked, we will try again
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
rtcb = this_task();
|
||||
rtcb->msgwaitq = msgq;
|
||||
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);
|
||||
|
||||
/* When we resume at this point, either (1) the message queue
|
||||
* is no longer empty, or (2) the wait has been interrupted by
|
||||
* 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 ERROR;
|
||||
return -ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
leave_cancellation_point();
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -318,23 +320,21 @@ int nxmq_wait_send(mqd_t mqdes)
|
|||
* Name: nxmq_do_send
|
||||
*
|
||||
* Description:
|
||||
* This is internal, common logic shared by both mq_send and mq_timesend.
|
||||
* This function adds the specified message (msg) to the message queue
|
||||
* (mqdes). Then it notifies any tasks that were waiting for message
|
||||
* queue notifications setup by mq_notify. And, finally, it awakens any
|
||||
* tasks that were waiting for the message not empty event.
|
||||
* This is internal, common logic shared by both [nx]mq_send and
|
||||
* [nx]mq_timesend. This function adds the specified message (msg) to the
|
||||
* message queue (mqdes). Then it notifies any tasks that were waiting
|
||||
* for message queue notifications setup by mq_notify. And, finally, it
|
||||
* awakens any tasks that were waiting for the message not empty event.
|
||||
*
|
||||
* Parameters:
|
||||
* mqdes - Message queue descriptor
|
||||
* msg - Message to send
|
||||
* Input Parameters:
|
||||
* mqdes - Message queue descriptor
|
||||
* msg - Message to send
|
||||
* 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.
|
||||
*
|
||||
* Assumptions/restrictions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxmq_do_send(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* 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>
|
||||
*
|
||||
* 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
|
||||
* becomes non-full.
|
||||
*
|
||||
* Parameters:
|
||||
* Input Parameters:
|
||||
* argc - the number of arguments (should be 1)
|
||||
* pid - the task ID of the task to wakeup
|
||||
*
|
||||
* Return Value:
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
|
@ -99,7 +99,7 @@ static void nxmq_sndtimeout(int argc, wdparm_t pid)
|
|||
* 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 */
|
||||
|
||||
|
@ -116,43 +116,36 @@ static void nxmq_sndtimeout(int argc, wdparm_t pid)
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_send
|
||||
* Name: nxmq_timedsend
|
||||
*
|
||||
* Description:
|
||||
* This function adds the specificied 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().
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
* nxmq_timedsend() is functionally equivalent to mq_timedsend() except
|
||||
* that:
|
||||
*
|
||||
* 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.
|
||||
* - It is not a cancellaction point, and
|
||||
* - It does not modify the errno value.
|
||||
*
|
||||
* 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).
|
||||
* See comments with mq_timedsend() for a more complete description of the
|
||||
* behavior of this function
|
||||
*
|
||||
* If the message queue is full, and the timeout has already expired by
|
||||
* the time of the call, mq_timedsend() returns immediately.
|
||||
*
|
||||
* Parameters:
|
||||
* mqdes - Message queue descriptor
|
||||
* msg - Message to send
|
||||
* msglen - The length of the message in bytes
|
||||
* prio - The priority of the message
|
||||
* 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
|
||||
*
|
||||
* Return Value:
|
||||
* On success, mq_send() returns 0 (OK); on error, -1 (ERROR)
|
||||
* is returned, with errno set to indicate the error:
|
||||
* 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.
|
||||
|
@ -162,12 +155,10 @@ static void nxmq_sndtimeout(int argc, wdparm_t pid)
|
|||
* 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 nxmq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
||||
FAR const struct timespec *abstime)
|
||||
{
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
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;
|
||||
ssystime_t ticks;
|
||||
int result;
|
||||
int ret = ERROR;
|
||||
int ret;
|
||||
|
||||
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();
|
||||
|
||||
/* Verify the input parameters -- setting errno appropriately
|
||||
* 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)
|
||||
{
|
||||
/* nxmq_verify_send() will set the errno appropriately */
|
||||
|
||||
leave_cancellation_point();
|
||||
return ERROR;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
set_errno(ENOMEM);
|
||||
leave_cancellation_point();
|
||||
return ERROR;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
sched_unlock();
|
||||
leave_cancellation_point();
|
||||
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)
|
||||
{
|
||||
result = EINVAL;
|
||||
ret = -EINVAL;
|
||||
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();
|
||||
if (!rtcb->waitdog)
|
||||
{
|
||||
result = EINVAL;
|
||||
ret = -EINVAL;
|
||||
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.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = enter_critical_section();
|
||||
result = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
|
||||
|
||||
/* 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)
|
||||
{
|
||||
ret = -result;
|
||||
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)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
@ -332,8 +312,7 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
|||
return ret;
|
||||
|
||||
/* Exit here with (1) the scheduler locked, (2) a message allocated, (3) a
|
||||
* wdog allocated, and (4) interrupts disabled. The error code is in
|
||||
* 'result'
|
||||
* wdog allocated, and (4) interrupts disabled.
|
||||
*/
|
||||
|
||||
errout_in_critical_section:
|
||||
|
@ -348,8 +327,78 @@ errout_in_critical_section:
|
|||
errout_with_mqmsg:
|
||||
nxmq_free_msg(mqmsg);
|
||||
sched_unlock();
|
||||
|
||||
set_errno(result);
|
||||
leave_cancellation_point();
|
||||
return ERROR;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 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)
|
||||
{
|
||||
serr("ERROR: Timedout!\n");
|
||||
swarn("WARNING: Timedout!\n");
|
||||
ret = ETIMEDOUT;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -112,14 +112,16 @@ int pthread_sem_take(sem_t *sem, bool intr)
|
|||
ret = nxsem_wait(sem);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* The only case that an error should occur here is if the wait
|
||||
* was awakened by a signal.
|
||||
/* The only cases that an error should occur here is if the wait
|
||||
* 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
|
||||
* just continue waiting until we have the semaphore?
|
||||
/* When the error occurs in this case, should we errout? Or
|
||||
* should we just continue waiting until we have the
|
||||
* semaphore?
|
||||
*/
|
||||
|
||||
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);
|
||||
if (!pjoin)
|
||||
if (pjoin == NULL)
|
||||
{
|
||||
/* Determine what kind of error to return */
|
||||
|
||||
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) */
|
||||
|
||||
if (!tcb)
|
||||
if (tcb == NULL)
|
||||
{
|
||||
ret = ESRCH;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue