mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 10:58:49 +08:00
mqueue: Add nxmq_open/nxmq_close/nxmq_unlink function
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
parent
de2a9d8a77
commit
929292f57b
4 changed files with 273 additions and 74 deletions
|
@ -88,7 +88,7 @@ int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
|
|||
inode = msgq->inode;
|
||||
DEBUGASSERT(inode->u.i_mqueue == msgq);
|
||||
|
||||
/* Decrement the reference count on the inode, possibly freeing it */
|
||||
/* Decrement the reference count on the inode, possibly free it */
|
||||
|
||||
mq_inode_release(inode);
|
||||
}
|
||||
|
@ -99,6 +99,51 @@ int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxmq_close
|
||||
*
|
||||
* Description:
|
||||
* This is an internal OS interface. It is functionally equivalent to
|
||||
* mq_close() except that:
|
||||
*
|
||||
* - It is not a cancellation point, and
|
||||
* - It does not modify the errno value.
|
||||
*
|
||||
* See comments with mq_close() for a more complete description of the
|
||||
* behavior of this function
|
||||
*
|
||||
* Input Parameters:
|
||||
* mqdes - Message queue descriptor.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxmq_close(mqd_t mqdes)
|
||||
{
|
||||
FAR struct tcb_s *rtcb = (FAR struct tcb_s *)sched_self();
|
||||
int ret;
|
||||
|
||||
/* Lock the scheduler to prevent any asynchronous task delete operation
|
||||
* (unlikely).
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
rtcb = (FAR struct tcb_s *)sched_self();
|
||||
DEBUGASSERT(mqdes != NULL && rtcb != NULL && rtcb->group != NULL);
|
||||
|
||||
/* Then perform the close operation */
|
||||
|
||||
ret = nxmq_close_group(mqdes, rtcb->group);
|
||||
|
||||
sched_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_close
|
||||
*
|
||||
|
@ -129,30 +174,15 @@ int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
|
|||
|
||||
int mq_close(mqd_t mqdes)
|
||||
{
|
||||
FAR struct tcb_s *rtcb = (FAR struct tcb_s *)sched_self();
|
||||
int ret;
|
||||
|
||||
/* Lock the scheduler to prevent any asynchronous task delete operation
|
||||
* (unlikely).
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
rtcb = (FAR struct tcb_s *)sched_self();
|
||||
DEBUGASSERT(mqdes != NULL && rtcb != NULL && rtcb->group != NULL);
|
||||
|
||||
/* Then perform the close operation */
|
||||
|
||||
ret = nxmq_close_group(mqdes, rtcb->group);
|
||||
#if 0
|
||||
if (ret < 0) /* Currently, nxmq_close_group() only returns OK */
|
||||
ret = nxmq_close(mqdes);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
ret = ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
sched_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,14 +43,18 @@
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_open
|
||||
* Name: nxmq_open
|
||||
*
|
||||
* Description:
|
||||
* This function establish a connection between a named message queue and
|
||||
* the calling task. After a successful call of mq_open(), the task can
|
||||
* reference the message queue using the address returned by the call. The
|
||||
* message queue remains usable until it is closed by a successful call to
|
||||
* mq_close().
|
||||
* the calling task. This is an internal OS interface. It is functionally
|
||||
* equivalent to mq_open() except that:
|
||||
*
|
||||
* - It is not a cancellation point, and
|
||||
* - It does not modify the errno value.
|
||||
*
|
||||
* See comments with mq_open() for a more complete description of the
|
||||
* behavior of this function
|
||||
*
|
||||
* Input Parameters:
|
||||
* mq_name - Name of the queue to open
|
||||
|
@ -65,30 +69,27 @@
|
|||
* messages that may be placed in the message queue.
|
||||
*
|
||||
* Returned Value:
|
||||
* A message queue descriptor or (mqd_t)-1 (ERROR)
|
||||
*
|
||||
* Assumptions:
|
||||
* 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, mqdes point to the new message queue descriptor.
|
||||
* A negated errno value is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
|
||||
int nxmq_open(FAR const char *mq_name, int oflags, mode_t mode,
|
||||
FAR struct mq_attr *attr, FAR mqd_t *mqdes)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct mqueue_inode_s *msgq;
|
||||
struct inode_search_s desc;
|
||||
char fullpath[MAX_MQUEUE_PATH];
|
||||
va_list ap;
|
||||
struct mq_attr *attr;
|
||||
mqd_t mqdes;
|
||||
mode_t mode;
|
||||
int errcode;
|
||||
int ret;
|
||||
|
||||
/* Make sure that a non-NULL name is supplied */
|
||||
|
||||
if (mq_name == NULL || *mq_name == '\0')
|
||||
{
|
||||
errcode = EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
|
@ -132,7 +133,7 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
|
|||
|
||||
if (!INODE_IS_MQUEUE(inode))
|
||||
{
|
||||
errcode = ENXIO;
|
||||
ret = -ENXIO;
|
||||
goto errout_with_inode;
|
||||
}
|
||||
|
||||
|
@ -142,17 +143,17 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
|
|||
|
||||
if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
||||
{
|
||||
errcode = EEXIST;
|
||||
ret = -EEXIST;
|
||||
goto errout_with_inode;
|
||||
}
|
||||
|
||||
/* Create a message queue descriptor for the current thread */
|
||||
|
||||
msgq = inode->u.i_mqueue;
|
||||
mqdes = nxmq_create_des(NULL, msgq, oflags);
|
||||
if (!mqdes)
|
||||
*mqdes = nxmq_create_des(NULL, msgq, oflags);
|
||||
if (!*mqdes)
|
||||
{
|
||||
errcode = ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_inode;
|
||||
}
|
||||
}
|
||||
|
@ -164,25 +165,15 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
|
|||
{
|
||||
/* The mqueue does not exist and O_CREAT is not set */
|
||||
|
||||
errcode = ENOENT;
|
||||
ret = -ENOENT;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* Create the mqueue. First we have to extract the additional
|
||||
* parameters from the variable argument list.
|
||||
*/
|
||||
|
||||
va_start(ap, oflags);
|
||||
mode = va_arg(ap, mode_t);
|
||||
attr = va_arg(ap, FAR struct mq_attr *);
|
||||
va_end(ap);
|
||||
|
||||
/* Create an inode in the pseudo-filesystem at this path */
|
||||
|
||||
ret = inode_semtake();
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = -ret;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
|
@ -191,7 +182,6 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
|
|||
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = -ret;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
|
@ -202,16 +192,16 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
|
|||
msgq = (FAR struct mqueue_inode_s *)nxmq_alloc_msgq(mode, attr);
|
||||
if (!msgq)
|
||||
{
|
||||
errcode = ENOSPC;
|
||||
ret = -ENOSPC;
|
||||
goto errout_with_inode;
|
||||
}
|
||||
|
||||
/* Create a message queue descriptor for the TCB */
|
||||
|
||||
mqdes = nxmq_create_des(NULL, msgq, oflags);
|
||||
if (!mqdes)
|
||||
*mqdes = nxmq_create_des(NULL, msgq, oflags);
|
||||
if (!*mqdes)
|
||||
{
|
||||
errcode = ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_msgq;
|
||||
}
|
||||
|
||||
|
@ -228,7 +218,7 @@ mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
|
|||
|
||||
RELEASE_SEARCH(&desc);
|
||||
sched_unlock();
|
||||
return mqdes;
|
||||
return OK;
|
||||
|
||||
errout_with_msgq:
|
||||
nxmq_free_msgq(msgq);
|
||||
|
@ -242,6 +232,66 @@ errout_with_lock:
|
|||
sched_unlock();
|
||||
|
||||
errout:
|
||||
set_errno(errcode);
|
||||
return (mqd_t)ERROR;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_open
|
||||
*
|
||||
* Description:
|
||||
* This function establish a connection between a named message queue and
|
||||
* the calling task. After a successful call of mq_open(), the task can
|
||||
* reference the message queue using the address returned by the call. The
|
||||
* message queue remains usable until it is closed by a successful call to
|
||||
* mq_close().
|
||||
*
|
||||
* Input Parameters:
|
||||
* mq_name - Name of the queue to open
|
||||
* oflags - open flags
|
||||
* Optional parameters. When the O_CREAT flag is specified, two optional
|
||||
* parameters are expected:
|
||||
*
|
||||
* 1. mode_t mode (ignored), and
|
||||
* 2. struct mq_attr *attr. The mq_maxmsg attribute
|
||||
* is used at the time that the message queue is
|
||||
* created to determine the maximum number of
|
||||
* messages that may be placed in the message queue.
|
||||
*
|
||||
* Returned Value:
|
||||
* A message queue descriptor or (mqd_t)-1 (ERROR)
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
mqd_t mq_open(FAR const char *mq_name, int oflags, ...)
|
||||
{
|
||||
FAR struct mq_attr *attr = NULL;
|
||||
mode_t mode = 0;
|
||||
mqd_t mqdes;
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
/* Were we asked to create it? */
|
||||
|
||||
if ((oflags & O_CREAT) != 0)
|
||||
{
|
||||
/* We have to extract the additional
|
||||
* parameters from the variable argument list.
|
||||
*/
|
||||
|
||||
va_start(ap, oflags);
|
||||
mode = va_arg(ap, mode_t);
|
||||
attr = va_arg(ap, FAR struct mq_attr *);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
ret = nxmq_open(mq_name, oflags, mode, attr, &mqdes);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(ret);
|
||||
mqdes = (mqd_t)ERROR;
|
||||
}
|
||||
|
||||
return mqdes;
|
||||
}
|
||||
|
|
|
@ -40,30 +40,33 @@
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_unlink
|
||||
* Name: nxmq_unlink
|
||||
*
|
||||
* Description:
|
||||
* This function removes the message queue named by "mq_name." If one
|
||||
* or more tasks have the message queue open when mq_unlink() is called,
|
||||
* removal of the message queue is postponed until all references to the
|
||||
* message queue have been closed.
|
||||
* This is an internal OS interface. It is functionally equivalent to
|
||||
* mq_unlink() except that:
|
||||
*
|
||||
* - It is not a cancellation point, and
|
||||
* - It does not modify the errno value.
|
||||
*
|
||||
* See comments with mq_unlink() for a more complete description of the
|
||||
* behavior of this function
|
||||
*
|
||||
* Input Parameters:
|
||||
* mq_name - Name of the message queue
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mq_unlink(FAR const char *mq_name)
|
||||
int nxmq_unlink(FAR const char *mq_name)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
struct inode_search_s desc;
|
||||
char fullpath[MAX_MQUEUE_PATH];
|
||||
int errcode;
|
||||
int ret;
|
||||
|
||||
/* Get the full path to the message queue */
|
||||
|
@ -80,7 +83,6 @@ int mq_unlink(FAR const char *mq_name)
|
|||
{
|
||||
/* There is no inode that includes in this path */
|
||||
|
||||
errcode = -ret;
|
||||
goto errout_with_search;
|
||||
}
|
||||
|
||||
|
@ -93,7 +95,7 @@ int mq_unlink(FAR const char *mq_name)
|
|||
|
||||
if (!INODE_IS_MQUEUE(inode))
|
||||
{
|
||||
errcode = ENXIO;
|
||||
ret = -ENXIO;
|
||||
goto errout_with_inode;
|
||||
}
|
||||
|
||||
|
@ -104,13 +106,12 @@ int mq_unlink(FAR const char *mq_name)
|
|||
ret = inode_semtake();
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = -ret;
|
||||
goto errout_with_inode;
|
||||
}
|
||||
|
||||
if (inode->i_child != NULL)
|
||||
{
|
||||
errcode = ENOTEMPTY;
|
||||
ret = -ENOTEMPTY;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
|
@ -127,7 +128,6 @@ int mq_unlink(FAR const char *mq_name)
|
|||
*/
|
||||
|
||||
DEBUGASSERT(ret >= 0 || ret == -EBUSY);
|
||||
UNUSED(ret);
|
||||
|
||||
/* Now we do not release the reference count in the normal way (by calling
|
||||
* inode release. Rather, we call mq_inode_release(). mq_inode_release
|
||||
|
@ -151,7 +151,39 @@ errout_with_inode:
|
|||
|
||||
errout_with_search:
|
||||
RELEASE_SEARCH(&desc);
|
||||
set_errno(errcode);
|
||||
sched_unlock();
|
||||
return ERROR;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_unlink
|
||||
*
|
||||
* Description:
|
||||
* This function removes the message queue named by "mq_name." If one
|
||||
* or more tasks have the message queue open when mq_unlink() is called,
|
||||
* removal of the message queue is postponed until all references to the
|
||||
* message queue have been closed.
|
||||
*
|
||||
* Input Parameters:
|
||||
* mq_name - Name of the message queue
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mq_unlink(FAR const char *mq_name)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = nxmq_unlink(mq_name);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -151,6 +151,93 @@ struct mq_attr; /* Forward reference */
|
|||
struct timespec; /* Forward reference */
|
||||
struct task_group_s; /* Forward reference */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxmq_open
|
||||
*
|
||||
* Description:
|
||||
* This function establish a connection between a named message queue and
|
||||
* the calling task. This is an internal OS interface. It is functionally
|
||||
* equivalent to mq_open() except that:
|
||||
*
|
||||
* - It is not a cancellation point, and
|
||||
* - It does not modify the errno value.
|
||||
*
|
||||
* See comments with mq_open() for a more complete description of the
|
||||
* behavior of this function
|
||||
*
|
||||
* Input Parameters:
|
||||
* mq_name - Name of the queue to open
|
||||
* oflags - open flags
|
||||
* Optional parameters. When the O_CREAT flag is specified, two optional
|
||||
* parameters are expected:
|
||||
*
|
||||
* 1. mode_t mode (ignored), and
|
||||
* 2. struct mq_attr *attr. The mq_maxmsg attribute
|
||||
* is used at the time that the message queue is
|
||||
* created to determine the maximum number of
|
||||
* messages that may be placed in the message queue.
|
||||
*
|
||||
* 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, mqdes point to the new message queue descriptor.
|
||||
* A negated errno value is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxmq_open(FAR const char *mq_name, int oflags, mode_t mode,
|
||||
FAR struct mq_attr *attr, FAR mqd_t *mqdes);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxmq_close
|
||||
*
|
||||
* Description:
|
||||
* This is an internal OS interface. It is functionally equivalent to
|
||||
* mq_close() except that:
|
||||
*
|
||||
* - It is not a cancellation point, and
|
||||
* - It does not modify the errno value.
|
||||
*
|
||||
* See comments with mq_close() for a more complete description of the
|
||||
* behavior of this function
|
||||
*
|
||||
* Input Parameters:
|
||||
* mqdes - Message queue descriptor.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxmq_close(mqd_t mqdes);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxmq_unlink
|
||||
*
|
||||
* Description:
|
||||
* This is an internal OS interface. It is functionally equivalent to
|
||||
* mq_unlink() except that:
|
||||
*
|
||||
* - It is not a cancellation point, and
|
||||
* - It does not modify the errno value.
|
||||
*
|
||||
* See comments with mq_unlink() for a more complete description of the
|
||||
* behavior of this function
|
||||
*
|
||||
* Input Parameters:
|
||||
* mq_name - Name of the message queue
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxmq_unlink(FAR const char *mq_name);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxmq_send
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue