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 | |
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')
-rw-r--r-- | cpukit/posix/include/rtems/posix/config.h | 11 | ||||
-rw-r--r-- | cpukit/posix/include/rtems/posix/mqueue.h | 7 | ||||
-rw-r--r-- | cpukit/posix/include/rtems/posix/mqueueimpl.h | 89 | ||||
-rw-r--r-- | cpukit/posix/src/mqueue.c | 11 | ||||
-rw-r--r-- | cpukit/posix/src/mqueueclose.c | 62 | ||||
-rw-r--r-- | cpukit/posix/src/mqueuedeletesupp.c | 56 | ||||
-rw-r--r-- | cpukit/posix/src/mqueuegetattr.c | 60 | ||||
-rw-r--r-- | cpukit/posix/src/mqueuenotify.c | 78 | ||||
-rw-r--r-- | cpukit/posix/src/mqueueopen.c | 204 | ||||
-rw-r--r-- | cpukit/posix/src/mqueuerecvsupp.c | 167 | ||||
-rw-r--r-- | cpukit/posix/src/mqueuesendsupp.c | 162 | ||||
-rw-r--r-- | cpukit/posix/src/mqueuesetattr.c | 66 | ||||
-rw-r--r-- | cpukit/posix/src/mqueueunlink.c | 11 |
13 files changed, 354 insertions, 630 deletions
diff --git a/cpukit/posix/include/rtems/posix/config.h b/cpukit/posix/include/rtems/posix/config.h index 08d764b46a..636f1e7d79 100644 --- a/cpukit/posix/include/rtems/posix/config.h +++ b/cpukit/posix/include/rtems/posix/config.h @@ -94,17 +94,6 @@ typedef struct { /** * This field contains the maximum number of POSIX API - * message queue file descriptors which are configured - * for this application. - * - * @note There can be one or more file descriptors used with - * each message queue. This value should be greater than - * or equal to the number of message queues. - */ - uint32_t maximum_message_queue_descriptors; - - /** - * This field contains the maximum number of POSIX API * semaphores which are configured for this application. */ uint32_t maximum_semaphores; diff --git a/cpukit/posix/include/rtems/posix/mqueue.h b/cpukit/posix/include/rtems/posix/mqueue.h index df9daff999..cdf94514af 100644 --- a/cpukit/posix/include/rtems/posix/mqueue.h +++ b/cpukit/posix/include/rtems/posix/mqueue.h @@ -58,14 +58,9 @@ typedef struct { bool linked; uint32_t open_count; struct sigevent notification; + int oflag; } POSIX_Message_queue_Control; -typedef struct { - Objects_Control Object; - POSIX_Message_queue_Control *Queue; - int oflag; -} POSIX_Message_queue_Control_fd; - /** @} */ #ifdef __cplusplus diff --git a/cpukit/posix/include/rtems/posix/mqueueimpl.h b/cpukit/posix/include/rtems/posix/mqueueimpl.h index 1cdf6191c7..491f716a47 100644 --- a/cpukit/posix/include/rtems/posix/mqueueimpl.h +++ b/cpukit/posix/include/rtems/posix/mqueueimpl.h @@ -23,6 +23,8 @@ #include <rtems/posix/posixapi.h> #include <rtems/score/coremsgimpl.h> +#include <rtems/seterr.h> + #ifdef __cplusplus extern "C" { #endif @@ -34,19 +36,14 @@ extern "C" { extern Objects_Information _POSIX_Message_queue_Information; /** - * The is used to manage the set of "file descriptors" associated with - * the message queues. - */ -extern Objects_Information _POSIX_Message_queue_Information_fds; - -/** * @brief Delete a POSIX Message Queue * * This routine supports the mq_unlink and mq_close routines by * doing most of the work involved with removing a message queue. */ void _POSIX_Message_queue_Delete( - POSIX_Message_queue_Control *the_mq + POSIX_Message_queue_Control *the_mq, + ISR_lock_Context *lock_context ); /*@ @@ -88,17 +85,11 @@ int _POSIX_Message_queue_Send_support( Watchdog_Interval timeout ); -/** - * @brief POSIX Message Queue Allocate - * - * This function allocates a message queue control block from - * the inactive chain of free message queue control blocks. - */ -RTEMS_INLINE_ROUTINE - POSIX_Message_queue_Control *_POSIX_Message_queue_Allocate( void ) +RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control * + _POSIX_Message_queue_Allocate_unprotected( void ) { return (POSIX_Message_queue_Control *) - _Objects_Allocate( &_POSIX_Message_queue_Information ); + _Objects_Allocate_unprotected( &_POSIX_Message_queue_Information ); } /** @@ -115,24 +106,13 @@ RTEMS_INLINE_ROUTINE void _POSIX_Message_queue_Free( } -/** - * @brief POSIX Message Queue Get - * - * This function maps message queue IDs to message queue control blocks. - * If ID corresponds to a local message queue, then it returns - * the_mq control pointer which maps to ID and location - * is set to OBJECTS_LOCAL. if the message queue ID is global and - * resides on a remote node, then location is set to OBJECTS_REMOTE, - * and the_message queue is undefined. Otherwise, location is set - * to OBJECTS_ERROR and the_mq is undefined. - */ -RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control *_POSIX_Message_queue_Get ( - Objects_Id id, - Objects_Locations *location +RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control *_POSIX_Message_queue_Get( + Objects_Id id, + ISR_lock_Context *lock_context ) { return (POSIX_Message_queue_Control *) - _Objects_Get( &_POSIX_Message_queue_Information, id, location ); + _Objects_Get_local( id, &_POSIX_Message_queue_Information, lock_context ); } /* @@ -171,26 +151,6 @@ RTEMS_INLINE_ROUTINE unsigned int _POSIX_Message_queue_Priority_from_core( int _POSIX_Message_queue_Translate_core_message_queue_return_code( uint32_t the_message_queue_status ); - -/** - * @brief POSIX Message Queue Allocate File Descriptor - */ -RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control_fd * - _POSIX_Message_queue_Allocate_fd( void ) -{ - return (POSIX_Message_queue_Control_fd *) - _Objects_Allocate( &_POSIX_Message_queue_Information_fds ); -} - -/** - * @brief POSIX Message Queue Free File Descriptor - */ -RTEMS_INLINE_ROUTINE void _POSIX_Message_queue_Free_fd ( - POSIX_Message_queue_Control_fd *the_mq_fd -) -{ - _Objects_Free( &_POSIX_Message_queue_Information_fds, &the_mq_fd->Object ); -} /** * @brief POSIX Message Queue Remove from Namespace @@ -202,33 +162,16 @@ RTEMS_INLINE_ROUTINE void _POSIX_Message_queue_Namespace_remove ( _Objects_Namespace_remove( &_POSIX_Message_queue_Information, &the_mq->Object ); } - -/* - * @brief POSIX Message Queue Get File Descriptor - */ -RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control_fd *_POSIX_Message_queue_Get_fd ( - mqd_t id, - Objects_Locations *location -) -{ - return (POSIX_Message_queue_Control_fd *) _Objects_Get( - &_POSIX_Message_queue_Information_fds, - (Objects_Id)id, - location - ); -} -RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control_fd * -_POSIX_Message_queue_Get_fd_interrupt_disable( +RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control * +_POSIX_Message_queue_Get_interrupt_disable( mqd_t id, - Objects_Locations *location, ISR_lock_Context *lock_context ) { - return (POSIX_Message_queue_Control_fd *) _Objects_Get_isr_disable( - &_POSIX_Message_queue_Information_fds, - (Objects_Id)id, - location, + return (POSIX_Message_queue_Control *) _Objects_Get_local( + (Objects_Id) id, + &_POSIX_Message_queue_Information, lock_context ); } diff --git a/cpukit/posix/src/mqueue.c b/cpukit/posix/src/mqueue.c index e5fc3a0b5d..fca9929294 100644 --- a/cpukit/posix/src/mqueue.c +++ b/cpukit/posix/src/mqueue.c @@ -61,17 +61,6 @@ static void _POSIX_Message_queue_Manager_initialization(void) _POSIX_PATH_MAX, /* maximum length of each object's name */ NULL /* Proxy extraction support callout */ ); - _Objects_Initialize_information( - &_POSIX_Message_queue_Information_fds, - OBJECTS_POSIX_API, - OBJECTS_POSIX_MESSAGE_QUEUE_FDS, - Configuration_POSIX_API.maximum_message_queue_descriptors, - sizeof( POSIX_Message_queue_Control_fd ), - /* size of this object's control block */ - true, /* true if names for this object are strings */ - NAME_MAX, /* maximum length of each object's name */ - NULL /* Proxy extraction support callout */ - ); } RTEMS_SYSINIT_ITEM( diff --git a/cpukit/posix/src/mqueueclose.c b/cpukit/posix/src/mqueueclose.c index 2864e95f3c..28a7d164d9 100644 --- a/cpukit/posix/src/mqueueclose.c +++ b/cpukit/posix/src/mqueueclose.c @@ -30,17 +30,6 @@ #include "config.h" #endif -#include <stdarg.h> - -#include <pthread.h> -#include <limits.h> -#include <errno.h> -#include <fcntl.h> -#include <mqueue.h> - -#include <rtems/system.h> -#include <rtems/score/watchdog.h> -#include <rtems/seterr.h> #include <rtems/posix/mqueueimpl.h> /* @@ -52,42 +41,31 @@ int mq_close( mqd_t mqdes ) { - POSIX_Message_queue_Control *the_mq; - POSIX_Message_queue_Control_fd *the_mq_fd; - Objects_Locations location; + POSIX_Message_queue_Control *the_mq; + ISR_lock_Context lock_context; _Objects_Allocator_lock(); - the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location ); - if ( location == OBJECTS_LOCAL ) { - /* OBJECTS_LOCAL: - * - * First update the actual message queue to reflect this descriptor - * being disassociated. This may result in the queue being really - * deleted. - */ - - the_mq = the_mq_fd->Queue; - the_mq->open_count -= 1; - _POSIX_Message_queue_Delete( the_mq ); + the_mq = _POSIX_Message_queue_Get( mqdes, &lock_context ); - /* - * Now close this file descriptor. - */ + if ( the_mq == NULL ) { + _Objects_Allocator_unlock(); + rtems_set_errno_and_return_minus_one( EBADF ); + } - _Objects_Close( - &_POSIX_Message_queue_Information_fds, &the_mq_fd->Object ); - _POSIX_Message_queue_Free_fd( the_mq_fd ); + _CORE_message_queue_Acquire_critical( + &the_mq->Message_queue, + &lock_context + ); - _Objects_Put( &the_mq_fd->Object ); - _Objects_Allocator_unlock(); - return 0; - } + if ( the_mq->open_count == 0 ) { + _CORE_message_queue_Release( &the_mq->Message_queue, &lock_context ); + _Objects_Allocator_unlock(); + rtems_set_errno_and_return_minus_one( EBADF ); + } - _Objects_Allocator_unlock(); + the_mq->open_count -= 1; + _POSIX_Message_queue_Delete( the_mq, &lock_context ); - /* - * OBJECTS_REMOTE: - * OBJECTS_ERROR: - */ - rtems_set_errno_and_return_minus_one( EBADF ); + _Objects_Allocator_unlock(); + return 0; } diff --git a/cpukit/posix/src/mqueuedeletesupp.c b/cpukit/posix/src/mqueuedeletesupp.c index 5382dd4149..61f330a1fb 100644 --- a/cpukit/posix/src/mqueuedeletesupp.c +++ b/cpukit/posix/src/mqueuedeletesupp.c @@ -18,56 +18,22 @@ #include "config.h" #endif -#include <stdarg.h> - -#include <pthread.h> -#include <limits.h> -#include <errno.h> -#include <fcntl.h> -#include <mqueue.h> - -#include <rtems/system.h> -#include <rtems/score/watchdog.h> -#include <rtems/score/wkspace.h> -#include <rtems/seterr.h> #include <rtems/posix/mqueueimpl.h> -#if defined(RTEMS_DEBUG) - #include <rtems/bspIo.h> -#endif void _POSIX_Message_queue_Delete( - POSIX_Message_queue_Control *the_mq + POSIX_Message_queue_Control *the_mq, + ISR_lock_Context *lock_context ) { - if ( !the_mq->linked && !the_mq->open_count ) { - Objects_Control *the_object = &the_mq->Object; - ISR_lock_Context lock_context; - - #if defined(RTEMS_DEBUG) - /* - * the name memory will have been freed by unlink. - */ - if ( the_object->name.name_p ) { - printk( - "POSIX MQ name (%p) not freed by unlink\n", - (void *)the_object->name.name_p - ); - _Workspace_Free( (void *)the_object->name.name_p ); - } - #endif - - _CORE_message_queue_Acquire( &the_mq->Message_queue, &lock_context ); - - _Objects_Close( &_POSIX_Message_queue_Information, the_object ); - - _CORE_message_queue_Close( - &the_mq->Message_queue, - NULL, /* no MP support */ - 0, - &lock_context - ); - + if ( !the_mq->linked && the_mq->open_count == 0 ) { + _CORE_message_queue_Close( + &the_mq->Message_queue, + NULL, /* no MP support */ + 0, + lock_context + ); _POSIX_Message_queue_Free( the_mq ); - + } else { + _CORE_message_queue_Release( &the_mq->Message_queue, lock_context ); } } diff --git a/cpukit/posix/src/mqueuegetattr.c b/cpukit/posix/src/mqueuegetattr.c index 735bb12f01..dae14e3f2e 100644 --- a/cpukit/posix/src/mqueuegetattr.c +++ b/cpukit/posix/src/mqueuegetattr.c @@ -30,17 +30,6 @@ #include "config.h" #endif -#include <stdarg.h> - -#include <pthread.h> -#include <limits.h> -#include <errno.h> -#include <fcntl.h> -#include <mqueue.h> - -#include <rtems/system.h> -#include <rtems/score/watchdog.h> -#include <rtems/seterr.h> #include <rtems/posix/mqueueimpl.h> /* @@ -52,36 +41,37 @@ int mq_getattr( struct mq_attr *mqstat ) { - POSIX_Message_queue_Control *the_mq; - POSIX_Message_queue_Control_fd *the_mq_fd; - Objects_Locations location; + POSIX_Message_queue_Control *the_mq; + ISR_lock_Context lock_context; - if ( !mqstat ) + if ( mqstat == NULL ) { rtems_set_errno_and_return_minus_one( EINVAL ); + } - the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location ); - switch ( location ) { - - case OBJECTS_LOCAL: - the_mq = the_mq_fd->Queue; + the_mq = _POSIX_Message_queue_Get( mqdes, &lock_context ); - /* - * Return the old values. - */ - mqstat->mq_flags = the_mq_fd->oflag; - mqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size; - mqstat->mq_maxmsg = the_mq->Message_queue.maximum_pending_messages; - mqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages; + if ( the_mq == NULL ) { + rtems_set_errno_and_return_minus_one( EBADF ); + } - _Objects_Put( &the_mq_fd->Object ); - return 0; + _CORE_message_queue_Acquire_critical( + &the_mq->Message_queue, + &lock_context + ); -#if defined(RTEMS_MULTIPROCESSING) - case OBJECTS_REMOTE: -#endif - case OBJECTS_ERROR: - break; + if ( the_mq->open_count == 0 ) { + _CORE_message_queue_Release( &the_mq->Message_queue, &lock_context ); + rtems_set_errno_and_return_minus_one( EBADF ); } - rtems_set_errno_and_return_minus_one( EBADF ); + /* + * Return the old values. + */ + mqstat->mq_flags = the_mq->oflag; + mqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size; + mqstat->mq_maxmsg = the_mq->Message_queue.maximum_pending_messages; + mqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages; + + _CORE_message_queue_Release( &the_mq->Message_queue, &lock_context ); + return 0; } diff --git a/cpukit/posix/src/mqueuenotify.c b/cpukit/posix/src/mqueuenotify.c index d31a8e662d..adcfdcb8f2 100644 --- a/cpukit/posix/src/mqueuenotify.c +++ b/cpukit/posix/src/mqueuenotify.c @@ -18,25 +18,9 @@ #include "config.h" #endif -#include <stdarg.h> - -#include <pthread.h> -#include <limits.h> -#include <errno.h> -#include <fcntl.h> -#include <mqueue.h> -#include <sys/types.h> -#include <signal.h> - -#include <rtems/system.h> -#include <rtems/score/watchdog.h> -#include <rtems/seterr.h> #include <rtems/posix/mqueueimpl.h> -/* - * _POSIX_Message_queue_Notify_handler - * - */ +#include <signal.h> static void _POSIX_Message_queue_Notify_handler( CORE_message_queue_Control *the_message_queue, @@ -64,45 +48,41 @@ int mq_notify( const struct sigevent *notification ) { - POSIX_Message_queue_Control *the_mq; - POSIX_Message_queue_Control_fd *the_mq_fd; - Objects_Locations location; - - the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location ); - switch ( location ) { - - case OBJECTS_LOCAL: - the_mq = the_mq_fd->Queue; - - if ( notification ) { - if ( _CORE_message_queue_Is_notify_enabled( &the_mq->Message_queue ) ) { - _Objects_Put( &the_mq_fd->Object ); - rtems_set_errno_and_return_minus_one( EBUSY ); - } + POSIX_Message_queue_Control *the_mq; + ISR_lock_Context lock_context; - _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL ); + the_mq = _POSIX_Message_queue_Get( mqdes, &lock_context ); - the_mq->notification = *notification; + if ( the_mq == NULL ) { + rtems_set_errno_and_return_minus_one( EBADF ); + } - _CORE_message_queue_Set_notify( - &the_mq->Message_queue, - _POSIX_Message_queue_Notify_handler - ); - } else { + _CORE_message_queue_Acquire_critical( + &the_mq->Message_queue, + &lock_context + ); - _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL ); + if ( the_mq->open_count == 0 ) { + _CORE_message_queue_Release( &the_mq->Message_queue, &lock_context ); + rtems_set_errno_and_return_minus_one( EBADF ); + } - } + if ( notification != NULL ) { + if ( _CORE_message_queue_Is_notify_enabled( &the_mq->Message_queue ) ) { + _CORE_message_queue_Release( &the_mq->Message_queue, &lock_context ); + rtems_set_errno_and_return_minus_one( EBUSY ); + } - _Objects_Put( &the_mq_fd->Object ); - return 0; + the_mq->notification = *notification; -#if defined(RTEMS_MULTIPROCESSING) - case OBJECTS_REMOTE: -#endif - case OBJECTS_ERROR: - break; + _CORE_message_queue_Set_notify( + &the_mq->Message_queue, + _POSIX_Message_queue_Notify_handler + ); + } else { + _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL ); } - rtems_set_errno_and_return_minus_one( EBADF ); + _CORE_message_queue_Release( &the_mq->Message_queue, &lock_context ); + return 0; } 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; } diff --git a/cpukit/posix/src/mqueuerecvsupp.c b/cpukit/posix/src/mqueuerecvsupp.c index ecdadb344e..b1d830e3d2 100644 --- a/cpukit/posix/src/mqueuerecvsupp.c +++ b/cpukit/posix/src/mqueuerecvsupp.c @@ -18,19 +18,10 @@ #include "config.h" #endif -#include <stdarg.h> +#include <rtems/posix/mqueueimpl.h> +#include <rtems/score/threadimpl.h> -#include <pthread.h> -#include <limits.h> -#include <errno.h> #include <fcntl.h> -#include <mqueue.h> - -#include <rtems/system.h> -#include <rtems/score/watchdog.h> -#include <rtems/score/threadimpl.h> -#include <rtems/seterr.h> -#include <rtems/posix/mqueueimpl.h> THREAD_WAIT_QUEUE_OBJECT_ASSERT( POSIX_Message_queue_Control, @@ -53,90 +44,82 @@ ssize_t _POSIX_Message_queue_Receive_support( Watchdog_Interval timeout ) { - POSIX_Message_queue_Control *the_mq; - POSIX_Message_queue_Control_fd *the_mq_fd; - Objects_Locations location; - size_t length_out; - bool do_wait; - Thread_Control *executing; - ISR_lock_Context lock_context; - - the_mq_fd = _POSIX_Message_queue_Get_fd_interrupt_disable( + POSIX_Message_queue_Control *the_mq; + ISR_lock_Context lock_context; + size_t length_out; + bool do_wait; + Thread_Control *executing; + + the_mq = _POSIX_Message_queue_Get( mqdes, &lock_context ); + + if ( the_mq == NULL ) { + rtems_set_errno_and_return_minus_one( EBADF ); + } + + if ( ( the_mq->oflag & O_ACCMODE ) == O_WRONLY ) { + _ISR_lock_ISR_enable( &lock_context ); + rtems_set_errno_and_return_minus_one( EBADF ); + } + + if ( msg_len < the_mq->Message_queue.maximum_message_size ) { + _ISR_lock_ISR_enable( &lock_context ); + rtems_set_errno_and_return_minus_one( EMSGSIZE ); + } + + /* + * Now if something goes wrong, we return a "length" of -1 + * to indicate an error. + */ + + length_out = -1; + + /* + * A timed receive with a bad time will do a poll regardless. + */ + if ( wait ) { + do_wait = ( the_mq->oflag & O_NONBLOCK ) == 0; + } else { + do_wait = wait; + } + + _CORE_message_queue_Acquire_critical( + &the_mq->Message_queue, + &lock_context + ); + + if ( the_mq->open_count == 0 ) { + _CORE_message_queue_Release( &the_mq->Message_queue, &lock_context ); + rtems_set_errno_and_return_minus_one( EBADF ); + } + + /* + * Now perform the actual message receive + */ + executing = _Thread_Executing; + _CORE_message_queue_Seize( + &the_mq->Message_queue, + executing, mqdes, - &location, + msg_ptr, + &length_out, + do_wait, + timeout, &lock_context ); - switch ( location ) { - - case OBJECTS_LOCAL: - if ( (the_mq_fd->oflag & O_ACCMODE) == O_WRONLY ) { - _ISR_lock_ISR_enable( &lock_context ); - rtems_set_errno_and_return_minus_one( EBADF ); - } - - the_mq = the_mq_fd->Queue; - - if ( msg_len < the_mq->Message_queue.maximum_message_size ) { - _ISR_lock_ISR_enable( &lock_context ); - rtems_set_errno_and_return_minus_one( EMSGSIZE ); - } - - /* - * Now if something goes wrong, we return a "length" of -1 - * to indicate an error. - */ - - length_out = -1; - - /* - * A timed receive with a bad time will do a poll regardless. - */ - if ( wait ) - do_wait = (the_mq_fd->oflag & O_NONBLOCK) ? false : true; - else - do_wait = wait; - - _CORE_message_queue_Acquire_critical( - &the_mq->Message_queue, - &lock_context - ); - - /* - * Now perform the actual message receive - */ - executing = _Thread_Executing; - _CORE_message_queue_Seize( - &the_mq->Message_queue, - executing, - mqdes, - msg_ptr, - &length_out, - do_wait, - timeout, - &lock_context - ); - - if (msg_prio) { - *msg_prio = _POSIX_Message_queue_Priority_from_core( - executing->Wait.count - ); - } - - if ( !executing->Wait.return_code ) - return length_out; - - rtems_set_errno_and_return_minus_one( - _POSIX_Message_queue_Translate_core_message_queue_return_code( - executing->Wait.return_code - ) - ); - -#if defined(RTEMS_MULTIPROCESSING) - case OBJECTS_REMOTE: -#endif - case OBJECTS_ERROR: - break; + + if ( msg_prio != NULL ) { + *msg_prio = _POSIX_Message_queue_Priority_from_core( + executing->Wait.count + ); + } + + if ( executing->Wait.return_code != CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL ) { + rtems_set_errno_and_return_minus_one( + _POSIX_Message_queue_Translate_core_message_queue_return_code( + executing->Wait.return_code + ) + ); } - rtems_set_errno_and_return_minus_one( EBADF ); + return length_out; } diff --git a/cpukit/posix/src/mqueuesendsupp.c b/cpukit/posix/src/mqueuesendsupp.c index ade92b0621..0d9974afe4 100644 --- a/cpukit/posix/src/mqueuesendsupp.c +++ b/cpukit/posix/src/mqueuesendsupp.c @@ -30,23 +30,9 @@ #include "config.h" #endif -#include <stdarg.h> - -#include <pthread.h> -#include <limits.h> -#include <errno.h> -#include <fcntl.h> -#include <mqueue.h> - -#include <rtems/system.h> -#include <rtems/score/watchdog.h> -#include <rtems/seterr.h> #include <rtems/posix/mqueueimpl.h> - -/* - * _POSIX_Message_queue_Send_support - */ +#include <fcntl.h> int _POSIX_Message_queue_Send_support( mqd_t mqdes, @@ -57,92 +43,86 @@ int _POSIX_Message_queue_Send_support( Watchdog_Interval timeout ) { - POSIX_Message_queue_Control *the_mq; - POSIX_Message_queue_Control_fd *the_mq_fd; - Objects_Locations location; - CORE_message_queue_Status msg_status; - bool do_wait; - Thread_Control *executing; - ISR_lock_Context lock_context; + POSIX_Message_queue_Control *the_mq; + ISR_lock_Context lock_context; + CORE_message_queue_Status msg_status; + bool do_wait; + Thread_Control *executing; /* * Validate the priority. * XXX - Do not validate msg_prio is not less than 0. */ - if ( msg_prio > MQ_PRIO_MAX ) + if ( msg_prio > MQ_PRIO_MAX ) { rtems_set_errno_and_return_minus_one( EINVAL ); + } - the_mq_fd = _POSIX_Message_queue_Get_fd_interrupt_disable( - mqdes, - &location, + the_mq = _POSIX_Message_queue_Get( mqdes, &lock_context ); + + if ( the_mq == NULL ) { + rtems_set_errno_and_return_minus_one( EBADF ); + } + + if ( ( the_mq->oflag & O_ACCMODE ) == O_RDONLY ) { + _ISR_lock_ISR_enable( &lock_context ); + rtems_set_errno_and_return_minus_one( EBADF ); + } + + /* + * A timed receive with a bad time will do a poll regardless. + */ + if ( wait ) { + do_wait = ( the_mq->oflag & O_NONBLOCK ) == 0; + } else { + do_wait = wait; + } + + _CORE_message_queue_Acquire_critical( + &the_mq->Message_queue, &lock_context ); - switch ( location ) { - - case OBJECTS_LOCAL: - if ( (the_mq_fd->oflag & O_ACCMODE) == O_RDONLY ) { - _ISR_lock_ISR_enable( &lock_context ); - rtems_set_errno_and_return_minus_one( EBADF ); - } - - the_mq = the_mq_fd->Queue; - - /* - * A timed receive with a bad time will do a poll regardless. - */ - if ( wait ) - do_wait = (the_mq_fd->oflag & O_NONBLOCK) ? false : true; - else - do_wait = wait; - - _CORE_message_queue_Acquire_critical( - &the_mq->Message_queue, - &lock_context - ); - - /* - * Now perform the actual message receive - */ - executing = _Thread_Executing; - msg_status = _CORE_message_queue_Submit( - &the_mq->Message_queue, - executing, - msg_ptr, - msg_len, - NULL, - 0, - _POSIX_Message_queue_Priority_to_core( msg_prio ), - do_wait, - timeout, /* no timeout */ - &lock_context - ); - - /* - * If we had to block, then this is where the task returns - * after it wakes up. The returned status is correct for - * non-blocking operations but if we blocked, then we need - * to look at the status in our TCB. - */ - - if ( msg_status == CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT ) - msg_status = executing->Wait.return_code; - - if ( !msg_status ) - return msg_status; - - rtems_set_errno_and_return_minus_one( - _POSIX_Message_queue_Translate_core_message_queue_return_code( - msg_status - ) - ); - -#if defined(RTEMS_MULTIPROCESSING) - case OBJECTS_REMOTE: -#endif - case OBJECTS_ERROR: - break; + + if ( the_mq->open_count == 0 ) { + _CORE_message_queue_Release( &the_mq->Message_queue, &lock_context ); + rtems_set_errno_and_return_minus_one( EBADF ); + } + + /* + * Now perform the actual message receive + */ + executing = _Thread_Executing; + msg_status = _CORE_message_queue_Submit( + &the_mq->Message_queue, + executing, + msg_ptr, + msg_len, + NULL, + 0, + _POSIX_Message_queue_Priority_to_core( msg_prio ), + do_wait, + timeout, + &lock_context + ); + + /* + * If we had to block, then this is where the task returns + * after it wakes up. The returned status is correct for + * non-blocking operations but if we blocked, then we need + * to look at the status in our TCB. + */ + + if ( msg_status == CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT ) { + msg_status = executing->Wait.return_code; + } + + if ( msg_status != CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL ) { + rtems_set_errno_and_return_minus_one( + _POSIX_Message_queue_Translate_core_message_queue_return_code( + msg_status + ) + ); } - rtems_set_errno_and_return_minus_one( EBADF ); + return 0; } diff --git a/cpukit/posix/src/mqueuesetattr.c b/cpukit/posix/src/mqueuesetattr.c index 13e6974b96..dfd9bab216 100644 --- a/cpukit/posix/src/mqueuesetattr.c +++ b/cpukit/posix/src/mqueuesetattr.c @@ -18,17 +18,6 @@ #include "config.h" #endif -#include <stdarg.h> - -#include <pthread.h> -#include <limits.h> -#include <errno.h> -#include <fcntl.h> -#include <mqueue.h> - -#include <rtems/system.h> -#include <rtems/score/watchdog.h> -#include <rtems/seterr.h> #include <rtems/posix/mqueueimpl.h> int mq_setattr( @@ -37,41 +26,42 @@ int mq_setattr( struct mq_attr *__restrict omqstat ) { - POSIX_Message_queue_Control_fd *the_mq_fd; - CORE_message_queue_Control *the_core_mq; - Objects_Locations location; + POSIX_Message_queue_Control *the_mq; + ISR_lock_Context lock_context; - if ( !mqstat ) + if ( mqstat == NULL ) { rtems_set_errno_and_return_minus_one( EINVAL ); + } - the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location ); - switch ( location ) { - - case OBJECTS_LOCAL: + the_mq = _POSIX_Message_queue_Get( mqdes, &lock_context ); - the_core_mq = &the_mq_fd->Queue->Message_queue; + if ( the_mq == NULL ) { + rtems_set_errno_and_return_minus_one( EBADF ); + } - /* - * Return the old values. - */ + _CORE_message_queue_Acquire_critical( + &the_mq->Message_queue, + &lock_context + ); - if ( omqstat ) { - omqstat->mq_flags = the_mq_fd->oflag; - omqstat->mq_msgsize = the_core_mq->maximum_message_size; - omqstat->mq_maxmsg = the_core_mq->maximum_pending_messages; - omqstat->mq_curmsgs = the_core_mq->number_of_pending_messages; - } + if ( the_mq->open_count == 0 ) { + _CORE_message_queue_Release( &the_mq->Message_queue, &lock_context ); + rtems_set_errno_and_return_minus_one( EBADF ); + } - the_mq_fd->oflag = mqstat->mq_flags; - _Objects_Put( &the_mq_fd->Object ); - return 0; + /* + * Return the old values. + */ -#if defined(RTEMS_MULTIPROCESSING) - case OBJECTS_REMOTE: -#endif - case OBJECTS_ERROR: - break; + if ( omqstat != NULL ) { + omqstat->mq_flags = the_mq->oflag; + omqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size; + omqstat->mq_maxmsg = the_mq->Message_queue.maximum_pending_messages; + omqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages; } - rtems_set_errno_and_return_minus_one( EBADF ); + the_mq->oflag = mqstat->mq_flags; + + _CORE_message_queue_Release( &the_mq->Message_queue, &lock_context ); + return 0; } diff --git a/cpukit/posix/src/mqueueunlink.c b/cpukit/posix/src/mqueueunlink.c index d5182d21fc..dc485ba657 100644 --- a/cpukit/posix/src/mqueueunlink.c +++ b/cpukit/posix/src/mqueueunlink.c @@ -18,10 +18,7 @@ #include "config.h" #endif -#include <mqueue.h> - #include <rtems/posix/mqueueimpl.h> -#include <rtems/seterr.h> /* * 15.2.2 Remove a Message Queue, P1003.1b-1993, p. 276 @@ -33,6 +30,7 @@ int mq_unlink( { POSIX_Message_queue_Control *the_mq; Objects_Get_by_name_error error; + ISR_lock_Context lock_context; _Objects_Allocator_lock(); @@ -42,9 +40,12 @@ int mq_unlink( rtems_set_errno_and_return_minus_one( _POSIX_Get_by_name_error( error ) ); } - the_mq->linked = false; _POSIX_Message_queue_Namespace_remove( the_mq ); - _POSIX_Message_queue_Delete( the_mq ); + + _CORE_message_queue_Acquire( &the_mq->Message_queue, &lock_context ); + + the_mq->linked = false; + _POSIX_Message_queue_Delete( the_mq, &lock_context ); _Objects_Allocator_unlock(); return 0; |