summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-09-29 14:59:31 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-09-29 14:59:31 -0600
commit92b3c77f738b63b1eedc4977f1c68a1fdcc74268 (patch)
treed2b94ae762cc25fcc1543393cf069cebfaba7eb1
parent96c1138b01020dee669415d903f0af8e9d31f137 (diff)
downloadnuttx-92b3c77f738b63b1eedc4977f1c68a1fdcc74268.tar.gz
nuttx-92b3c77f738b63b1eedc4977f1c68a1fdcc74268.tar.bz2
nuttx-92b3c77f738b63b1eedc4977f1c68a1fdcc74268.zip
Complete re-implementation of mq_open()
-rw-r--r--nuttx/fs/mqueue/mq_open.c186
-rw-r--r--nuttx/fs/mqueue/mqueue.h77
-rw-r--r--nuttx/fs/semaphore/sem_open.c2
-rw-r--r--nuttx/include/nuttx/mqueue.h25
-rw-r--r--nuttx/sched/mqueue/mq_descreate.c23
-rw-r--r--nuttx/sched/mqueue/mq_msgqalloc.c131
-rw-r--r--nuttx/sched/mqueue/mqueue.h2
7 files changed, 374 insertions, 72 deletions
diff --git a/nuttx/fs/mqueue/mq_open.c b/nuttx/fs/mqueue/mq_open.c
index e0d47aa46..299afc4fd 100644
--- a/nuttx/fs/mqueue/mq_open.c
+++ b/nuttx/fs/mqueue/mq_open.c
@@ -1,7 +1,7 @@
/****************************************************************************
* sched/mqueue/mq_open.c
*
- * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009, 2011, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -39,24 +39,36 @@
#include <nuttx/config.h>
-#include <sys/types.h>
-#include <stdint.h>
#include <stdarg.h>
+#include <stdio.h>
+#include <sched.h>
#include <mqueue.h>
#include <fcntl.h>
-#include <string.h>
-#include <sched.h>
#include <errno.h>
+
+#include <nuttx/mqueue.h>
+#include <nuttx/fs/fs.h>
+
+#include "inode/inode.h"
+#include "mqueue/mqueue.h"
+
+#if 0
+#include <sys/types.h>
+#include <stdint.h>
#include <debug.h>
-#include <nuttx/kmalloc.h>
#include "sched/sched.h"
-#include "mqueue/mqueue.h"
+#endif
/****************************************************************************
* Pre-procesor Definitions
****************************************************************************/
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_FS_MQUEUE_MPATH
+# define CONFIG_FS_MQUEUE_MPATH "/var/mqueue"
+#endif
/****************************************************************************
* Private Type Declarations
@@ -109,83 +121,135 @@
mqd_t mq_open(const char *mq_name, int oflags, ...)
{
- FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head;
+ FAR struct inode *inode;
+ FAR const char *relpath = NULL;
FAR struct mqueue_inode_s *msgq;
- mqd_t mqdes = NULL;
- va_list arg;
+ char fullpath[MAX_MQUEUE_PATH];
+ va_list ap;
struct mq_attr *attr;
+ mqd_t mqdes;
mode_t mode;
- int namelen;
+ int errcode;
+ int ret;
/* Make sure that a non-NULL name is supplied */
if (mq_name)
{
+ /* Make sure that the check for the existence of the message queue
+ * and the creation of the message queue are atomic with respect to
+ * other processes executing mq_open(). A simple sched_lock() should
+ * be sufficientt.
+ */
+
sched_lock();
- namelen = strlen(mq_name);
- if (namelen > 0)
+
+ /* 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 mqueue. This should succeed if the message
+ * queue has already been created.
+ */
+
+ inode = inode_find(fullpath, &relpath);
+ if (inode)
{
- /* See if the message queue already exists */
+ /* It exists. Verify that the inode is a message queue */
+
+ if (!INODE_IS_MQUEUE(inode))
+ {
+ errcode = ENXIO;
+ goto errout_with_inode;
+ }
+
+ /* It exists and is a message queue. Check if the caller wanted to
+ * create a new mqueue with this name.
+ */
- msgq = mq_findnamed(mq_name);
- if (msgq)
+ if ((oflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
{
- /* It does. Check if the caller wanted to create a new
- * message queue with this name (i.e., O_CREAT|O_EXCL)
- */
-
- if ((oflags & O_CREAT) == 0 || (oflags & O_EXCL) == 0)
- {
- /* Create a message queue descriptor for the TCB */
-
- mqdes = mq_descreate(rtcb, msgq, oflags);
- if (mqdes)
- {
- /* Allow a new connection to the message queue */
-
- msgq->nconnect++;
- }
- }
+ errcode = EEXIST;
+ goto errout_with_inode;
}
- /* It doesn't exist. Should we create one? */
+ /* Create a message queue descriptor for the current thread */
- else if ((oflags & O_CREAT) != 0)
+ msgq = inode->u.i_mqueue;
+ mqdes = mq_descreate(NULL, msgq, oflags);
+ if (!mqdes)
{
- /* Yes.. Get the optional arguments needed to create a message
- * queue.
- */
+ errcode = ENOMEM;
+ goto errout_with_inode;
+ }
+ }
+ else
+ {
+ /* The mqueue does not exists. Were we asked to create it? */
- va_start(arg, oflags);
- mode = va_arg(arg, mode_t);
- attr = va_arg(arg, struct mq_attr*);
+ if ((oflags & O_CREAT) == 0)
+ {
+ /* The mqueue does not exist and O_CREAT is not set */
+
+ errcode = ENOENT;
+ goto errout_with_lock;
+ }
- /* Allocate memory for the new message queue. The size to
- * allocate is the size of the struct mqueue_inode_s header
- * plus the size of the message queue name+1.
- */
+ /* Create the mqueue. First we have to extract the additional
+ * parameters from the variable argument list.
+ */
- msgq = (FAR struct mqueue_inode_s*)mq_msgqalloc(oflags, mode, attr);
- if (msgq)
- {
-#warning Missing logic
- }
+ va_start(ap, oflags);
+ mode = va_arg(ap, mode_t);
+ attr = va_arg(ap, FAR struct mq_attr*);
+ va_end(ap);
- /* Clean-up variable argument stuff */
+ /* Create an inode in the pseudo-filesystem at this path */
- va_end(arg);
+ inode_semtake();
+ ret = inode_reserve(fullpath, &inode);
+ inode_semgive();
+
+ if (ret < 0)
+ {
+ errcode = -ret;
+ goto errout_with_lock;
}
- }
- sched_unlock();
- }
+ /* Allocate memory for the new message queue. */
- if (mqdes == NULL)
- {
- return (mqd_t)ERROR;
- }
- else
- {
- return mqdes;
+ msgq = (FAR struct mqueue_inode_s*)mq_msgqalloc(mode, attr);
+ if (!msgq)
+ {
+ errcode = ENOMEM;
+ goto errout_with_inode;
+ }
+
+ /* Create a message queue descriptor for the TCB */
+
+ mqdes = mq_descreate(NULL, msgq, oflags);
+ if (!mqdes)
+ {
+ errcode = ENOMEM;
+ goto errout_with_msgq;
+ }
+
+ /* Save the message queue in the inode structure */
+
+ inode->u.i_mqueue = msgq;
+ }
}
+
+ sched_unlock();
+ return mqdes;
+
+errout_with_msgq:
+ mq_msgqfree(msgq);
+ inode->u.i_mqueue = NULL;
+errout_with_inode:
+ inode_release(inode);
+errout_with_lock:
+ sched_unlock();
+ set_errno(errcode);
+ return (mqd_t)ERROR;
}
diff --git a/nuttx/fs/mqueue/mqueue.h b/nuttx/fs/mqueue/mqueue.h
new file mode 100644
index 000000000..e18302188
--- /dev/null
+++ b/nuttx/fs/mqueue/mqueue.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+ * fs/mqueue/mqueue.h
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __FS_MQUEUE_MQUEUE_H
+#define __FS_MQUEUE_MQUEUE_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_MQUEUE_PATH 64
+
+/****************************************************************************
+ * Public Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __FS_MQUEUE_MQUEUE_H */
+
diff --git a/nuttx/fs/semaphore/sem_open.c b/nuttx/fs/semaphore/sem_open.c
index e4a7da417..579a94455 100644
--- a/nuttx/fs/semaphore/sem_open.c
+++ b/nuttx/fs/semaphore/sem_open.c
@@ -234,7 +234,7 @@ FAR sem_t *sem_open (FAR const char *name, int oflags, ...)
if (!nsem)
{
errcode = ENOMEM;
- goto errout_with_lock;
+ goto errout_with_inode;
}
/* Link to the inode */
diff --git a/nuttx/include/nuttx/mqueue.h b/nuttx/include/nuttx/mqueue.h
index e3c3de32c..748e4a6a6 100644
--- a/nuttx/include/nuttx/mqueue.h
+++ b/nuttx/include/nuttx/mqueue.h
@@ -139,7 +139,6 @@ void mq_msgqfree(FAR struct mqueue_inode_s *msgq);
* It allocates and initializes a structu mqueue_inode_s structure.
*
* Parameters:
- * oflags - open flags
* mode - mode_t value is ignored
* attr - The mq_maxmsg attribute is used at the time that the message
* queue is created to determine the maximum number of
@@ -151,9 +150,31 @@ void mq_msgqfree(FAR struct mqueue_inode_s *msgq);
*
****************************************************************************/
-FAR struct mqueue_inode_s *mq_msgqalloc(int oflags, mode_t mode,
+struct mq_attr;
+FAR struct mqueue_inode_s *mq_msgqalloc(mode_t mode,
FAR struct mq_attr *attr);
+/****************************************************************************
+ * Name: mq_descreate
+ *
+ * Description:
+ * Create a message queue descriptor for the specified TCB
+ *
+ * Inputs:
+ * TCB - task that needs the descriptor.
+ * msgq - Named message queue containing the message
+ * oflags - access rights for the descriptor
+ *
+ * Return Value:
+ * On success, the message queue descriptor is returned. NULL is returned
+ * on a failure to allocate.
+ *
+ ****************************************************************************/
+
+struct tcb_s;
+mqd_t mq_descreate(FAR struct tcb_s* mtcb, FAR struct mqueue_inode_s* msgq,
+ int oflags);
+
#undef EXTERN
#ifdef __cplusplus
}
diff --git a/nuttx/sched/mqueue/mq_descreate.c b/nuttx/sched/mqueue/mq_descreate.c
index 237085d71..1320fb165 100644
--- a/nuttx/sched/mqueue/mq_descreate.c
+++ b/nuttx/sched/mqueue/mq_descreate.c
@@ -50,6 +50,7 @@
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
+#include <nuttx/mqueue.h>
#include "signal/signal.h"
@@ -124,8 +125,8 @@ static mqd_t mq_desalloc(void)
* Create a message queue descriptor for the specified TCB
*
* Inputs:
- * TCB - task that needs the descriptor.
- * msgq - Named message queue containing the message
+ * mtcb - task that needs the descriptor.
+ * msgq - Named message queue containing the message
* oflags - access rights for the descriptor
*
* Return Value:
@@ -134,12 +135,22 @@ static mqd_t mq_desalloc(void)
*
****************************************************************************/
-mqd_t mq_descreate(FAR struct tcb_s* mtcb, FAR struct mqueue_inode_s* msgq,
+mqd_t mq_descreate(FAR struct tcb_s *mtcb, FAR struct mqueue_inode_s *msgq,
int oflags)
{
- FAR struct task_group_s *group = mtcb->group;
+ FAR struct task_group_s *group;
mqd_t mqdes;
+ /* A NULL TCB pointer means to use the TCB of the currently executing
+ * task/thread.
+ */
+
+ if (!mtcb)
+ {
+ mtcb = sched_self();
+ }
+
+ group = mtcb->group;
DEBUGASSERT(group);
/* Create a message queue descriptor for the TCB */
@@ -147,13 +158,13 @@ mqd_t mq_descreate(FAR struct tcb_s* mtcb, FAR struct mqueue_inode_s* msgq,
mqdes = mq_desalloc();
if (mqdes)
{
- /* Initialize the MQ descriptor */
+ /* Initialize the message queue descriptor */
memset(mqdes, 0, sizeof(struct mq_des));
mqdes->msgq = msgq;
mqdes->oflags = oflags;
- /* And add it to the specified tasks's TCB */
+ /* And add it to the specified task's TCB */
sq_addlast((FAR sq_entry_t*)mqdes, &group->tg_msgdesq);
}
diff --git a/nuttx/sched/mqueue/mq_msgqalloc.c b/nuttx/sched/mqueue/mq_msgqalloc.c
new file mode 100644
index 000000000..f0ddd15dc
--- /dev/null
+++ b/nuttx/sched/mqueue/mq_msgqalloc.c
@@ -0,0 +1,131 @@
+/****************************************************************************
+ * sched/mqueue/mq_msgqalloc.c
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <mqueue.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/sched.h>
+#include <nuttx/mqueue.h>
+
+#include "sched/sched.h"
+#include "mqueue/mqueue.h"
+
+/****************************************************************************
+ * Pre-procesor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mq_msgqalloc
+ *
+ * Description:
+ * This function implements a part of the POSIX message queue open logic.
+ * It allocates and initializes a structu mqueue_inode_s structure.
+ *
+ * Parameters:
+ * mode - mode_t value is ignored
+ * 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.
+ *
+ * Return Value:
+ * The allocated and initalized message queue structure or NULL in the
+ * event of a failure.
+ *
+ ****************************************************************************/
+
+FAR struct mqueue_inode_s *mq_msgqalloc(mode_t mode,
+ FAR struct mq_attr *attr)
+{
+ FAR struct mqueue_inode_s *msgq;
+
+ /* Allocate memory for the new message queue. */
+
+ msgq = (FAR struct mqueue_inode_s*)kmm_zalloc(sizeof(struct mqueue_inode_s));
+ if (msgq)
+ {
+ /* Initialize the new named message queue */
+
+ sq_init(&msgq->msglist);
+ if (attr)
+ {
+ msgq->maxmsgs = (int16_t)attr->mq_maxmsg;
+ if (attr->mq_msgsize <= MQ_MAX_BYTES)
+ {
+ msgq->maxmsgsize = (int16_t)attr->mq_msgsize;
+ }
+ else
+ {
+ msgq->maxmsgsize = MQ_MAX_BYTES;
+ }
+ }
+ else
+ {
+ msgq->maxmsgs = MQ_MAX_MSGS;
+ msgq->maxmsgsize = MQ_MAX_BYTES;
+ }
+
+#ifndef CONFIG_DISABLE_SIGNALS
+ msgq->ntpid = INVALID_PROCESS_ID;
+#endif
+ }
+
+ return msgq;
+}
diff --git a/nuttx/sched/mqueue/mqueue.h b/nuttx/sched/mqueue/mqueue.h
index 4b382b8b0..f44d7654d 100644
--- a/nuttx/sched/mqueue/mqueue.h
+++ b/nuttx/sched/mqueue/mqueue.h
@@ -141,8 +141,6 @@ EXTERN sq_queue_t g_desfree;
void weak_function mq_initialize(void);
void mq_desblockalloc(void);
-mqd_t mq_descreate(FAR struct tcb_s* mtcb, FAR struct mqueue_inode_s* msgq,
- int oflags);
FAR struct mqueue_inode_s *mq_findnamed(FAR const char *mq_name);
void mq_msgfree(FAR struct mqueue_msg_s *mqmsg);