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:
Gregory Nutt 2017-10-10 08:43:10 -06:00
parent c5a5a5a1b6
commit fca07be1df
22 changed files with 497 additions and 306 deletions

View file

@ -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);
}
}

View file

@ -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 */

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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

View file

@ -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:

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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,

View file

@ -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;
}

View file

@ -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

View file

@ -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)

View file

@ -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;
}