diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-04-26 21:20:31 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-05-02 07:46:15 +0200 |
commit | c8982e5f6a4857444676165deab1e08dc91a6847 (patch) | |
tree | 9862d54650522b55afac8a4e1b84ab078a69dff5 /cpukit/posix/src/mqueueopen.c | |
parent | rtems: Avoid Giant lock for message queues (diff) | |
download | rtems-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.c | 204 |
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; } |