int mq_close_group(mqd_t mqdes, FAR struct task_group_s *group) { FAR struct mqueue_inode_s *msgq; FAR struct inode *inode; 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 */ mq_desclose_group(mqdes, group); /* 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 freeing it */ mq_inode_release(inode); sched_unlock(); } return OK; }
int mq_unlink(FAR const char *mq_name) { FAR struct inode *inode; FAR const char *relpath = NULL; char fullpath[MAX_MQUEUE_PATH]; int errcode; int ret; /* Get the full path to the message queue */ snprintf(fullpath, MAX_MQUEUE_PATH, CONFIG_FS_MQUEUE_MPATH "/%s", mq_name); /* Get the inode for this message queue. */ sched_lock(); inode = inode_find(fullpath, &relpath); if (!inode) { /* There is no inode that includes in this path */ errcode = ENOENT; goto errout; } /* Verify that what we found is, indeed, a message queue */ if (!INODE_IS_MQUEUE(inode)) { errcode = ENXIO; goto errout_with_inode; } /* Refuse to unlink the inode if it has children. I.e., if it is * functioning as a directory and the directory is not empty. */ inode_semtake(); if (inode->i_child != NULL) { errcode = ENOTEMPTY; goto errout_with_semaphore; } /* Remove the old inode from the tree. Because we hold a reference count * on the inode, it will not be deleted now. This will set the * FSNODEFLAG_DELETED bit in the inode flags. */ ret = inode_remove(fullpath); /* inode_remove() should always fail with -EBUSY because we hae a reference * on the inode. -EBUSY means taht the inode was, indeed, unlinked but * thatis could not be freed because there are refrences. */ 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 * will decrement the reference count on the inode. But it will also free * the message queue if that reference count decrements to zero. Since we * hold one reference, that can only occur if the message queue is not * in-use. */ inode_semgive(); mq_inode_release(inode); sched_unlock(); return OK; errout_with_semaphore: inode_semgive(); errout_with_inode: inode_release(inode); errout: set_errno(errcode); sched_unlock(); return ERROR; }