mirror of
https://github.com/apache/nuttx.git
synced 2026-06-07 17:33:08 +08:00
mqueue: simplify the mqueue reailize
1. remove descript management in mqueue, save code size 2. use i_ops instead of i_mqueue to remove the dup logic Change-Id: Ie88960e50ddcae9c87977c9ad65a45297c663291 Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
+2
-152
@@ -40,65 +40,6 @@
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* 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 nxmq_close_group()
|
||||
* deallocates any system resources allocated by the system for use by
|
||||
* this task for its message queue.
|
||||
*
|
||||
* Input Parameters:
|
||||
* mqdes - Message queue descriptor.
|
||||
* group - Group that has the open descriptor.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) if the message queue is closed successfully. Otherwise, a
|
||||
* negated errno value is returned.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
|
||||
{
|
||||
FAR struct mqueue_inode_s *msgq;
|
||||
FAR struct inode *inode;
|
||||
int ret = OK;
|
||||
|
||||
DEBUGASSERT(mqdes != NULL && group != NULL);
|
||||
|
||||
/* Verify the inputs */
|
||||
|
||||
if (mqdes)
|
||||
{
|
||||
sched_lock();
|
||||
|
||||
/* Find the message queue associated with the message descriptor */
|
||||
|
||||
msgq = mqdes->msgq;
|
||||
DEBUGASSERT(msgq && msgq->inode);
|
||||
|
||||
/* Close/free the message descriptor */
|
||||
|
||||
ret = nxmq_desclose_group(mqdes, group);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* Get the inode from the message queue structure */
|
||||
|
||||
inode = msgq->inode;
|
||||
DEBUGASSERT(inode->u.i_mqueue == msgq);
|
||||
|
||||
/* Decrement the reference count on the inode, possibly free it */
|
||||
|
||||
mq_inode_release(inode);
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxmq_close
|
||||
*
|
||||
@@ -124,23 +65,7 @@ int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
|
||||
|
||||
int nxmq_close(mqd_t mqdes)
|
||||
{
|
||||
FAR struct tcb_s *rtcb = (FAR struct tcb_s *)nxsched_self();
|
||||
int ret;
|
||||
|
||||
/* Lock the scheduler to prevent any asynchronous task delete operation
|
||||
* (unlikely).
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
DEBUGASSERT(mqdes != NULL && rtcb != NULL && rtcb->group != NULL);
|
||||
|
||||
/* Then perform the close operation */
|
||||
|
||||
ret = nxmq_close_group(mqdes, rtcb->group);
|
||||
|
||||
sched_unlock();
|
||||
return ret;
|
||||
return nx_close(mqdes);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -173,80 +98,5 @@ int nxmq_close(mqd_t mqdes)
|
||||
|
||||
int mq_close(mqd_t mqdes)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = nxmq_close(mqdes);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_inode_release
|
||||
*
|
||||
* Description:
|
||||
* Release a reference count on a message queue inode.
|
||||
*
|
||||
* Input Parameters:
|
||||
* inode - The message queue inode
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mq_inode_release(FAR struct inode *inode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Decrement the reference count on the inode */
|
||||
|
||||
do
|
||||
{
|
||||
ret = inode_semtake();
|
||||
|
||||
/* The only error that is expected is due to thread cancellation.
|
||||
* At this point, we must continue to free the mqueue anyway.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(ret == OK || ret == -ECANCELED);
|
||||
}
|
||||
while (ret < 0);
|
||||
|
||||
if (inode->i_crefs > 0)
|
||||
{
|
||||
inode->i_crefs--;
|
||||
}
|
||||
|
||||
/* If the message queue was previously unlinked and the reference count
|
||||
* has decremented to zero, then release the message queue and delete
|
||||
* the inode now.
|
||||
*/
|
||||
|
||||
if (inode->i_crefs <= 0 && (inode->i_flags & FSNODEFLAG_DELETED) != 0)
|
||||
{
|
||||
FAR struct mqueue_inode_s *msgq = inode->u.i_mqueue;
|
||||
DEBUGASSERT(msgq);
|
||||
|
||||
/* Free the message queue (and any messages left in it) */
|
||||
|
||||
nxmq_free_msgq(msgq);
|
||||
inode->u.i_mqueue = NULL;
|
||||
|
||||
/* Release and free the inode container. If it has been properly
|
||||
* unlinked, then the peer pointer should be NULL.
|
||||
*/
|
||||
|
||||
inode_semgive();
|
||||
|
||||
DEBUGASSERT(inode->i_peer == NULL);
|
||||
inode_free(inode);
|
||||
return;
|
||||
}
|
||||
|
||||
inode_semgive();
|
||||
return close(mqdes);
|
||||
}
|
||||
|
||||
+57
-14
@@ -38,6 +38,52 @@
|
||||
#include "inode/inode.h"
|
||||
#include "mqueue/mqueue.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int nxmq_file_close(FAR struct file *filep);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct file_operations g_nxmq_fileops =
|
||||
{
|
||||
NULL, /* open */
|
||||
nxmq_file_close, /* close */
|
||||
NULL, /* read */
|
||||
NULL, /* write */
|
||||
NULL, /* seek */
|
||||
NULL, /* ioctl */
|
||||
NULL, /* poll */
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
NULL, /* unlink */
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static int nxmq_file_close(FAR struct file *filep)
|
||||
{
|
||||
FAR struct inode *inode = filep->f_inode;
|
||||
|
||||
if (inode->i_crefs <= 1 && (inode->i_flags & FSNODEFLAG_DELETED))
|
||||
{
|
||||
FAR struct mqueue_inode_s *msgq = inode->i_private;
|
||||
|
||||
if (msgq)
|
||||
{
|
||||
nxmq_free_msgq(msgq);
|
||||
inode->i_private = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -147,14 +193,13 @@ int nxmq_open(FAR const char *mq_name, int oflags, mode_t mode,
|
||||
goto errout_with_inode;
|
||||
}
|
||||
|
||||
/* Create a message queue descriptor for the current thread */
|
||||
/* Associate the inode with a file structure */
|
||||
|
||||
msgq = inode->u.i_mqueue;
|
||||
*mqdes = nxmq_create_des(NULL, msgq, oflags);
|
||||
if (!*mqdes)
|
||||
*mqdes = files_allocate(inode, oflags, 0, 0);
|
||||
if (*mqdes < 0)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_inode;
|
||||
ret = *mqdes;
|
||||
goto errout_with_msgq;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -196,19 +241,18 @@ int nxmq_open(FAR const char *mq_name, int oflags, mode_t mode,
|
||||
goto errout_with_inode;
|
||||
}
|
||||
|
||||
/* Create a message queue descriptor for the TCB */
|
||||
/* Associate the inode with a file structure */
|
||||
|
||||
*mqdes = nxmq_create_des(NULL, msgq, oflags);
|
||||
if (!*mqdes)
|
||||
*mqdes = files_allocate(inode, oflags, 0, 0);
|
||||
if (*mqdes < 0)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
ret = *mqdes;
|
||||
goto errout_with_msgq;
|
||||
}
|
||||
|
||||
/* Bind the message queue and the inode structure */
|
||||
|
||||
INODE_SET_MQUEUE(inode);
|
||||
inode->u.i_mqueue = msgq;
|
||||
inode->u.i_ops = &g_nxmq_fileops;
|
||||
inode->i_private = msgq;
|
||||
msgq->inode = inode;
|
||||
|
||||
/* Set the initial reference count on this inode to one */
|
||||
@@ -222,7 +266,6 @@ int nxmq_open(FAR const char *mq_name, int oflags, mode_t mode,
|
||||
|
||||
errout_with_msgq:
|
||||
nxmq_free_msgq(msgq);
|
||||
inode->u.i_mqueue = NULL;
|
||||
|
||||
errout_with_inode:
|
||||
inode_release(inode);
|
||||
|
||||
+34
-2
@@ -35,6 +35,38 @@
|
||||
#include "inode/inode.h"
|
||||
#include "mqueue/mqueue.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_inode_release
|
||||
*
|
||||
* Description:
|
||||
* Release a reference count on a message queue inode.
|
||||
*
|
||||
* Input Parameters:
|
||||
* inode - The message queue inode
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void mq_inode_release(FAR struct inode *inode)
|
||||
{
|
||||
if (inode->i_crefs <= 1)
|
||||
{
|
||||
FAR struct mqueue_inode_s *msgq = inode->i_private;
|
||||
|
||||
if (msgq)
|
||||
{
|
||||
nxmq_free_msgq(msgq);
|
||||
inode->i_private = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -182,8 +214,8 @@ int mq_unlink(FAR const char *mq_name)
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
ret = ERROR;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return OK;
|
||||
}
|
||||
|
||||
+1
-37
@@ -45,6 +45,7 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#ifndef CONFIG_FS_MQUEUE_MPATH
|
||||
@@ -55,41 +56,4 @@
|
||||
|
||||
#define MAX_MQUEUE_PATH 64
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mq_inode_release
|
||||
*
|
||||
* Description:
|
||||
* Release a reference count on a message queue inode.
|
||||
*
|
||||
* Input Parameters:
|
||||
* inode - The message queue inode
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mq_inode_release(FAR struct inode *inode);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __FS_MQUEUE_MQUEUE_H */
|
||||
|
||||
Reference in New Issue
Block a user