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 mqueue_inode_s *msgq;
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
DEBUGASSERT(mqdes != NULL && group != NULL);
|
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 */
|
/* 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 */
|
/* Get the inode from the message queue structure */
|
||||||
|
|
||||||
inode = msgq->inode;
|
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 */
|
/* Decrement the reference count on the inode, possibly freeing it */
|
||||||
|
|
||||||
mq_inode_release(inode);
|
mq_inode_release(inode);
|
||||||
|
}
|
||||||
|
|
||||||
sched_unlock();
|
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.
|
* group - Group that has the open descriptor.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None.
|
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||||
|
* and failure.
|
||||||
*
|
*
|
||||||
* Assumptions:
|
* Assumptions:
|
||||||
* - Called only from mq_close() with the scheduler locked.
|
* - 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
|
#undef EXTERN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -83,20 +83,50 @@
|
|||||||
* group - Group that has the open descriptor.
|
* group - Group that has the open descriptor.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None.
|
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||||
|
* and failure.
|
||||||
*
|
*
|
||||||
* Assumptions:
|
* Assumptions:
|
||||||
* - Called only from mq_close() with the scheduler locked.
|
* - 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;
|
FAR struct mqueue_inode_s *msgq;
|
||||||
|
#ifdef CONFIG_DEBUG_FEATURES
|
||||||
|
mqd_t mq_ptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
DEBUGASSERT(mqdes != NULL && group != NULL);
|
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.
|
* descriptors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -121,4 +151,5 @@ void nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group)
|
|||||||
/* Deallocate the message descriptor */
|
/* Deallocate the message descriptor */
|
||||||
|
|
||||||
mq_desfree(mqdes);
|
mq_desfree(mqdes);
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user