Use proper CORE_semaphore_Status for _CORE_semaphore_Flush() and _CORE_semaphore_Destroy() operations.
Close #2696. --- cpukit/posix/include/rtems/posix/semaphoreimpl.h | 1 - cpukit/posix/src/semaphorecreatesupp.c | 12 +++--- cpukit/posix/src/semaphoredeletesupp.c | 2 +- cpukit/posix/src/semaphoretranslatereturncode.c | 2 +- cpukit/rtems/src/semdelete.c | 6 +-- cpukit/rtems/src/semflush.c | 1 - cpukit/score/include/rtems/score/coresemimpl.h | 26 ++++++++---- testsuites/psxtests/psxsem01/init.c | 52 +++++++++++++++++++++++- 8 files changed, 79 insertions(+), 23 deletions(-) diff --git a/cpukit/posix/include/rtems/posix/semaphoreimpl.h b/cpukit/posix/include/rtems/posix/semaphoreimpl.h index 8608e6f..41bfdad 100644 --- a/cpukit/posix/include/rtems/posix/semaphoreimpl.h +++ b/cpukit/posix/include/rtems/posix/semaphoreimpl.h @@ -58,7 +58,6 @@ RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Free ( POSIX_Semaphore_Control *the_semaphore ) { - _CORE_semaphore_Destroy( &the_semaphore->Semaphore ); _Objects_Free( &_POSIX_Semaphore_Information, &the_semaphore->Object ); } diff --git a/cpukit/posix/src/semaphorecreatesupp.c b/cpukit/posix/src/semaphorecreatesupp.c index 9a24e0a..79db888 100644 --- a/cpukit/posix/src/semaphorecreatesupp.c +++ b/cpukit/posix/src/semaphorecreatesupp.c @@ -54,11 +54,6 @@ int _POSIX_Semaphore_Create_support( if (pshared != 0) rtems_set_errno_and_return_minus_one( ENOSYS ); - the_semaphore = _POSIX_Semaphore_Allocate_unprotected(); - if ( !the_semaphore ) { - rtems_set_errno_and_return_minus_one( ENOSPC ); - } - /* * Make a copy of the user's string for name just in case it was * dynamically constructed. @@ -66,13 +61,18 @@ int _POSIX_Semaphore_Create_support( if ( name_arg != NULL ) { name = _Workspace_String_duplicate( name_arg, name_len ); if ( !name ) { - _POSIX_Semaphore_Free( the_semaphore ); rtems_set_errno_and_return_minus_one( ENOMEM ); } } else { name = NULL; } + the_semaphore = _POSIX_Semaphore_Allocate_unprotected(); + if ( !the_semaphore ) { + _Workspace_Free( name ); + rtems_set_errno_and_return_minus_one( ENOSPC ); + } + the_semaphore->process_shared = pshared; if ( name ) { diff --git a/cpukit/posix/src/semaphoredeletesupp.c b/cpukit/posix/src/semaphoredeletesupp.c index 650cdcd..43946746 100644 --- a/cpukit/posix/src/semaphoredeletesupp.c +++ b/cpukit/posix/src/semaphoredeletesupp.c @@ -36,7 +36,7 @@ void _POSIX_Semaphore_Delete( { if ( !the_semaphore->linked && !the_semaphore->open_count ) { _Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object ); - _CORE_semaphore_Flush( &the_semaphore->Semaphore, -1, NULL, 0 ); + _CORE_semaphore_Destroy( &the_semaphore->Semaphore, NULL, 0 ); _POSIX_Semaphore_Free( the_semaphore ); } } diff --git a/cpukit/posix/src/semaphoretranslatereturncode.c b/cpukit/posix/src/semaphoretranslatereturncode.c index 37e7d07..d7b99ea 100644 --- a/cpukit/posix/src/semaphoretranslatereturncode.c +++ b/cpukit/posix/src/semaphoretranslatereturncode.c @@ -25,7 +25,7 @@ const int _POSIX_Semaphore_Return_codes[CORE_SEMAPHORE_STATUS_LAST + 1] = { 0, /* CORE_SEMAPHORE_STATUS_SUCCESSFUL */ EAGAIN, /* CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT */ - EAGAIN, /* CORE_SEMAPHORE_WAS_DELETED */ + EINVAL, /* CORE_SEMAPHORE_WAS_DELETED */ ETIMEDOUT, /* CORE_SEMAPHORE_TIMEOUT */ /* The next error can not occur since we set the maximum * count to the largest value the count can hold. diff --git a/cpukit/rtems/src/semdelete.c b/cpukit/rtems/src/semdelete.c index 6a83d25..d3d6264 100644 --- a/cpukit/rtems/src/semdelete.c +++ b/cpukit/rtems/src/semdelete.c @@ -73,13 +73,11 @@ rtems_status_code rtems_semaphore_delete( ); _CORE_mutex_Destroy( &the_semaphore->Core_control.mutex ); } else { - _CORE_semaphore_Flush( + _CORE_semaphore_Destroy( &the_semaphore->Core_control.semaphore, - CORE_SEMAPHORE_WAS_DELETED, _Semaphore_MP_Send_object_was_deleted, id - ); - _CORE_semaphore_Destroy( &the_semaphore->Core_control.semaphore ); + ) } _Objects_Close( &_Semaphore_Information, &the_semaphore->Object ); diff --git a/cpukit/rtems/src/semflush.c b/cpukit/rtems/src/semflush.c index ea06883..64386b0 100644 --- a/cpukit/rtems/src/semflush.c +++ b/cpukit/rtems/src/semflush.c @@ -60,7 +60,6 @@ rtems_status_code rtems_semaphore_flush( } else { _CORE_semaphore_Flush( &the_semaphore->Core_control.semaphore, - CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT, _Semaphore_MP_Send_object_was_deleted, id ); diff --git a/cpukit/score/include/rtems/score/coresemimpl.h b/cpukit/score/include/rtems/score/coresemimpl.h index 79d907c..d68c3d7 100644 --- a/cpukit/score/include/rtems/score/coresemimpl.h +++ b/cpukit/score/include/rtems/score/coresemimpl.h @@ -86,12 +86,22 @@ void _CORE_semaphore_Initialize( uint32_t initial_value ); -RTEMS_INLINE_ROUTINE void _CORE_semaphore_Destroy( - CORE_semaphore_Control *the_semaphore -) -{ - _Thread_queue_Destroy( &the_semaphore->Wait_queue ); -} +#define _CORE_semaphore_Destroy( \ + the_semaphore, \ + mp_callout, \ + mp_id \ +) \ + do { \ + _Thread_queue_Flush( \ + &( the_semaphore )->Wait_queue, \ + ( the_semaphore )->operations, \ + CORE_SEMAPHORE_WAS_DELETED, \ + mp_callout, \ + mp_id, \ + &_core_semaphore_flush_lock_context \ + ); \ + _Thread_queue_Destroy( &( the_semaphore )->Wait_queue ); \ + } while ( 0 ) RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Do_surrender( CORE_semaphore_Control *the_semaphore, @@ -180,14 +190,14 @@ RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Do_surrender( /* Must be a macro due to the multiprocessing dependent parameters */ #define _CORE_semaphore_Flush( \ the_semaphore, \ - status, \ + CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT, \ mp_callout, \ mp_id \ ) \ _Thread_queue_Flush( \ &( the_semaphore )->Wait_queue, \ ( the_semaphore )->operations, \ - status, \ + CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT, \ mp_callout, \ mp_id \ ) diff --git a/testsuites/psxtests/psxsem01/init.c b/testsuites/psxtests/psxsem01/init.c index c1752f3..24f6d96 100644 --- a/testsuites/psxtests/psxsem01/init.c +++ b/testsuites/psxtests/psxsem01/init.c @@ -27,6 +27,55 @@ void *POSIX_Init(void *argument); #define MAX_SEMS 10 +static void *sem_wait_task(void *arg) +{ + sem_t *sem; + int rv; + + sem = arg; + + rv = sem_wait( sem ); + rtems_test_assert( rv == 0 ); + + errno = 0; + rv = sem_wait( sem ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + return NULL; +} + +static void test_sem_wait_during_delete(void) +{ + sem_t sem; + int rv; + pthread_t th; + int eno; + int val; + + rv = sem_init( &sem, 0, 1 ); + rtems_test_assert( rv == 0 ); + + eno = pthread_create( &th, NULL, sem_wait_task, &sem ); + rtems_test_assert( eno == 0 ); + + rv = sem_getvalue( &sem, &val ); + rtems_test_assert( rv == 0 ); + rtems_test_assert( val == 1 ); + + sched_yield(); + + rv = sem_getvalue( &sem, &val ); + rtems_test_assert( rv == 0 ); + rtems_test_assert( val == 0 ); + + rv = sem_destroy( &sem ); + rtems_test_assert( rv == 0 ); + + eno = pthread_join( th, NULL ); + rtems_test_assert( eno == 0 ); +} + void *POSIX_Init( void *argument ) @@ -295,6 +344,7 @@ void *POSIX_Init( fatal_posix_service_status( errno, ENOENT, "sem_unlink errno ENOENT"); rtems_test_assert( (status == -1) && (errno == ENOENT) ); + test_sem_wait_during_delete(); /* Try adding in unlinking before closing... (can we still open?) */ @@ -312,7 +362,7 @@ void *POSIX_Init( #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION -#define CONFIGURE_MAXIMUM_POSIX_THREADS 1 +#define CONFIGURE_MAXIMUM_POSIX_THREADS 2 #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES MAX_SEMS #define CONFIGURE_POSIX_INIT_THREAD_TABLE -- 1.8.4.5 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel