sched/mqueue/mq_desclose.c: Add a test to verify that message queue is closed by the same task group that opened it. If not, then list corruption would result. This test is only performed if CONFIG_DEBUG_FEATURES is enabled since it should not normally be an issue: It would be a strange programming practice to open a message queue in open task group, then close it in another.
This commit is contained in:
parent
721994846c
commit
a12f80fb90
@ -77,6 +77,7 @@ 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);
|
||||
|
||||
@ -93,8 +94,9 @@ int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
|
||||
|
||||
/* Close/free the message descriptor */
|
||||
|
||||
nxmq_desclose_group(mqdes, group);
|
||||
|
||||
ret = nxmq_desclose_group(mqdes, group);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* Get the inode from the message queue structure */
|
||||
|
||||
inode = msgq->inode;
|
||||
@ -103,10 +105,12 @@ int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
|
||||
/* Decrement the reference count on the inode, possibly freeing it */
|
||||
|
||||
mq_inode_release(inode);
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
}
|
||||
|
||||
return OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -390,14 +390,15 @@ int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group);
|
||||
* group - Group that has the open descriptor.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* and failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* - Called only from mq_close() with the scheduler locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group);
|
||||
int nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
@ -83,20 +83,50 @@
|
||||
* group - Group that has the open descriptor.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* and failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* - Called only from mq_close() with the scheduler locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group)
|
||||
int nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group)
|
||||
{
|
||||
FAR struct mqueue_inode_s *msgq;
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
mqd_t mq_ptr;
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(mqdes != NULL && group != NULL);
|
||||
|
||||
/* Remove the message descriptor from the current task's list of message
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
/* Check that msgq is valid for closing. It must be owned by the current
|
||||
* group. NOTE the call to sq_rem() below would corrupt the descriptor
|
||||
* list if mqdes did not lie in the list.
|
||||
*/
|
||||
|
||||
mq_ptr = (mqd_t)sq_peek(&group->tg_msgdesq);
|
||||
while (mq_ptr)
|
||||
{
|
||||
if (mq_ptr == mqdes)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
mq_ptr = (mqd_t)sq_next(mq_ptr);
|
||||
}
|
||||
|
||||
DEBUGASSERT(mq_ptr != NULL);
|
||||
if (mq_ptr == NULL)
|
||||
{
|
||||
/* 'mqdes' does not lie in the group's list of message descriptors. */
|
||||
|
||||
return -EPERM;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Remove the message descriptor from the current group's list of message
|
||||
* descriptors.
|
||||
*/
|
||||
|
||||
@ -121,4 +151,5 @@ void nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group)
|
||||
/* Deallocate the message descriptor */
|
||||
|
||||
mq_desfree(mqdes);
|
||||
return OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user