summaryrefslogtreecommitdiffstats
path: root/cpukit/posix/src/mqueueopen.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-04-26 21:20:31 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-02 07:46:15 +0200
commitc8982e5f6a4857444676165deab1e08dc91a6847 (patch)
tree9862d54650522b55afac8a4e1b84ab078a69dff5 /cpukit/posix/src/mqueueopen.c
parentrtems: Avoid Giant lock for message queues (diff)
downloadrtems-c8982e5f6a4857444676165deab1e08dc91a6847.tar.bz2
posix: Simplify message queues
The mq_open() function returns a descriptor to a POSIX message queue object identified by a name. This is similar to sem_open(). In contrast to the POSIX semaphore the POSIX message queues use a separate object for the descriptor. This extra object is superfluous, since the object identifier can be used directly for this purpose, just like for the semaphores. Update #2702. Update #2555.
Diffstat (limited to 'cpukit/posix/src/mqueueopen.c')
-rw-r--r--cpukit/posix/src/mqueueopen.c204
1 files changed, 72 insertions, 132 deletions
diff --git a/cpukit/posix/src/mqueueopen.c b/cpukit/posix/src/mqueueopen.c
index 973c9b8e74..fe63d4ea6e 100644
--- a/cpukit/posix/src/mqueueopen.c
+++ b/cpukit/posix/src/mqueueopen.c
@@ -30,59 +30,48 @@
#include "config.h"
#endif
-#include <stdarg.h>
+#include <rtems/posix/mqueueimpl.h>
+#include <rtems/score/wkspace.h>
-#include <pthread.h>
-#include <limits.h>
-#include <errno.h>
+#include <stdarg.h>
#include <fcntl.h>
-#include <mqueue.h>
-
-#include <rtems/score/todimpl.h>
-#include <rtems/score/watchdog.h>
-#include <rtems/posix/mqueueimpl.h>
-#include <rtems/seterr.h>
#define MQ_OPEN_FAILED ((mqd_t) -1)
-static int _POSIX_Message_queue_Create_support(
- const char *name_arg,
- size_t name_len,
- struct mq_attr *attr_ptr,
- POSIX_Message_queue_Control **message_queue
+/*
+ * There is no real basis for the default values. They will work
+ * but were not compared against any existing implementation for
+ * compatibility. See README.mqueue for an example program we
+ * think will print out the defaults. Report anything you find with it.
+ */
+static const struct mq_attr _POSIX_Message_queue_Default_attributes = {
+ .mq_maxmsg = 10,
+ .mq_msgsize = 16
+};
+
+static mqd_t _POSIX_Message_queue_Create(
+ const char *name_arg,
+ size_t name_len,
+ int oflag,
+ const struct mq_attr *attr
)
{
- POSIX_Message_queue_Control *the_mq;
- struct mq_attr attr;
- char *name;
+ POSIX_Message_queue_Control *the_mq;
+ char *name;
/* length of name has already been validated */
- /*
- * There is no real basis for the default values. They will work
- * but were not compared against any existing implementation for
- * compatibility. See README.mqueue for an example program we
- * think will print out the defaults. Report anything you find with it.
- */
- if ( attr_ptr == NULL ) {
- attr.mq_maxmsg = 10;
- attr.mq_msgsize = 16;
- } else {
- if ( attr_ptr->mq_maxmsg <= 0 ){
- rtems_set_errno_and_return_minus_one( EINVAL );
- }
-
- if ( attr_ptr->mq_msgsize <= 0 ){
- rtems_set_errno_and_return_minus_one( EINVAL );
- }
+ if ( attr->mq_maxmsg <= 0 ){
+ rtems_set_errno_and_return_value( EINVAL, MQ_OPEN_FAILED );
+ }
- attr = *attr_ptr;
+ if ( attr->mq_msgsize <= 0 ){
+ rtems_set_errno_and_return_value( EINVAL, MQ_OPEN_FAILED );
}
- the_mq = _POSIX_Message_queue_Allocate();
+ the_mq = _POSIX_Message_queue_Allocate_unprotected();
if ( !the_mq ) {
- _Objects_Allocator_unlock();
- rtems_set_errno_and_return_minus_one( ENFILE );
+ rtems_set_errno_and_return_value( ENFILE, MQ_OPEN_FAILED );
}
/*
@@ -92,12 +81,12 @@ static int _POSIX_Message_queue_Create_support(
name = _Workspace_String_duplicate( name_arg, name_len );
if ( !name ) {
_POSIX_Message_queue_Free( the_mq );
- _Objects_Allocator_unlock();
- rtems_set_errno_and_return_minus_one( ENOMEM );
+ rtems_set_errno_and_return_value( ENOMEM, MQ_OPEN_FAILED );
}
the_mq->open_count = 1;
the_mq->linked = true;
+ the_mq->oflag = oflag;
/*
* NOTE: That thread blocking discipline should be based on the
@@ -106,17 +95,17 @@ static int _POSIX_Message_queue_Create_support(
* Joel: Cite POSIX or OpenGroup on above statement so we can determine
* if it is a real requirement.
*/
- if ( !_CORE_message_queue_Initialize(
- &the_mq->Message_queue,
- CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO,
- attr.mq_maxmsg,
- attr.mq_msgsize
- ) ) {
-
+ if (
+ !_CORE_message_queue_Initialize(
+ &the_mq->Message_queue,
+ CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO,
+ attr->mq_maxmsg,
+ attr->mq_msgsize
+ )
+ ) {
_POSIX_Message_queue_Free( the_mq );
- _Workspace_Free(name);
- _Objects_Allocator_unlock();
- rtems_set_errno_and_return_minus_one( ENOSPC );
+ _Workspace_Free( name );
+ rtems_set_errno_and_return_value( ENOSPC, MQ_OPEN_FAILED );
}
_Objects_Open_string(
@@ -124,11 +113,7 @@ static int _POSIX_Message_queue_Create_support(
&the_mq->Object,
name
);
-
- *message_queue = the_mq;
-
- _Objects_Allocator_unlock();
- return 0;
+ return the_mq->Object.id;
}
/*
@@ -142,36 +127,12 @@ mqd_t mq_open(
/* struct mq_attr attr */
)
{
- /*
- * mode is set but never used. GCC gives a warning for this
- * and we need to tell GCC not to complain. But we have to
- * have it because we have to work through the variable
- * arguments to get to attr.
- */
- mode_t mode RTEMS_UNUSED;
-
- va_list arg;
- struct mq_attr *attr = NULL;
- int status;
- POSIX_Message_queue_Control *the_mq;
- POSIX_Message_queue_Control_fd *the_mq_fd;
- size_t name_len;
- Objects_Get_by_name_error error;
-
- if ( oflag & O_CREAT ) {
- va_start(arg, oflag);
- mode = va_arg( arg, mode_t );
- attr = va_arg( arg, struct mq_attr * );
- va_end(arg);
- }
-
- the_mq_fd = _POSIX_Message_queue_Allocate_fd();
- if ( !the_mq_fd ) {
- _Objects_Allocator_unlock();
- rtems_set_errno_and_return_value( ENFILE, MQ_OPEN_FAILED );
- }
- the_mq_fd->oflag = oflag;
+ POSIX_Message_queue_Control *the_mq;
+ size_t name_len;
+ Objects_Get_by_name_error error;
+ mqd_t status;
+ _Objects_Allocator_lock();
the_mq = _POSIX_Message_queue_Get_by_name( name, &name_len, &error );
/*
@@ -181,12 +142,15 @@ mqd_t mq_open(
* or some other miscellaneous error on the name.
*/
if ( the_mq == NULL ) {
+ va_list ap;
+ const struct mq_attr *attr;
+
/*
* Unless provided a valid name that did not already exist
* and we are willing to create then it is an error.
*/
- if ( !( error == OBJECTS_GET_BY_NAME_NO_OBJECT && (oflag & O_CREAT) ) ) {
- _POSIX_Message_queue_Free_fd( the_mq_fd );
+
+ if ( error != OBJECTS_GET_BY_NAME_NO_OBJECT || ( oflag & O_CREAT ) == 0 ) {
_Objects_Allocator_unlock();
rtems_set_errno_and_return_value(
_POSIX_Get_by_name_error( error ),
@@ -194,60 +158,36 @@ mqd_t mq_open(
);
}
- } else { /* name -> ID translation succeeded */
+ va_start( ap, oflag );
+ va_arg( ap, mode_t );
+ attr = va_arg( ap, const struct mq_attr * );
+ va_end( ap );
+
+ if ( attr == NULL ) {
+ attr = &_POSIX_Message_queue_Default_attributes;
+ }
+
+ /*
+ * At this point, the message queue does not exist and everything has been
+ * checked. We should go ahead and create a message queue.
+ */
+
+ status = _POSIX_Message_queue_Create( name, name_len, oflag, attr );
+ } else {
+
/*
* Check for existence with creation.
*/
- if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) {
- _POSIX_Message_queue_Free_fd( the_mq_fd );
+
+ if ( ( oflag & ( O_CREAT | O_EXCL ) ) == ( O_CREAT | O_EXCL ) ) {
_Objects_Allocator_unlock();
rtems_set_errno_and_return_value( EEXIST, MQ_OPEN_FAILED );
}
- /*
- * In this case we need to do an ID->pointer conversion to
- * check the mode.
- */
the_mq->open_count += 1;
- the_mq_fd->Queue = the_mq;
- _Objects_Open_string(
- &_POSIX_Message_queue_Information_fds,
- &the_mq_fd->Object,
- NULL
- );
- _Objects_Allocator_unlock();
- return the_mq_fd->Object.id;
-
+ status = the_mq->Object.id;
}
- /*
- * At this point, the message queue does not exist and everything has been
- * checked. We should go ahead and create a message queue.
- */
- status = _POSIX_Message_queue_Create_support(
- name,
- name_len,
- attr,
- &the_mq
- );
-
- /*
- * errno was set by Create_support, so don't set it again.
- */
- if ( status != 0 ) {
- _POSIX_Message_queue_Free_fd( the_mq_fd );
- _Objects_Allocator_unlock();
- return MQ_OPEN_FAILED;
- }
-
- the_mq_fd->Queue = the_mq;
- _Objects_Open_string(
- &_POSIX_Message_queue_Information_fds,
- &the_mq_fd->Object,
- NULL
- );
-
_Objects_Allocator_unlock();
-
- return the_mq_fd->Object.id;
+ return status;
}