From 05d470a557a36988125199e2a8dc9da5b4d6df76 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 9 Aug 2010 08:13:21 +0000 Subject: 2010-08-09 Sebastian Huber PR 1615/cpukit * posix/src/keyrundestructors.c: Improved POSIX compliance. Now we may have an unlimited number of iterations. --- cpukit/ChangeLog | 6 +++ cpukit/posix/src/keyrundestructors.c | 85 ++++++++++++++---------------------- 2 files changed, 38 insertions(+), 53 deletions(-) diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index c982bac47e..c9d87b8897 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,9 @@ +2010-08-09 Sebastian Huber + + PR 1615/cpukit + * posix/src/keyrundestructors.c: Improved POSIX compliance. Now we may + have an unlimited number of iterations. + 2010-08-09 Sebastian Huber * sapi/inline/rtems/chain.inl: Added diff --git a/cpukit/posix/src/keyrundestructors.c b/cpukit/posix/src/keyrundestructors.c index 3d5c0dae68..cc8bad94e8 100644 --- a/cpukit/posix/src/keyrundestructors.c +++ b/cpukit/posix/src/keyrundestructors.c @@ -1,4 +1,6 @@ /* + * Copyright (c) 2010 embedded brains GmbH. + * * COPYRIGHT (c) 1989-2007. * On-Line Applications Research Corporation (OAR). * @@ -13,14 +15,9 @@ #include "config.h" #endif -#include -#include -#include -#include - #include +#include #include -#include #include /*PAGE @@ -37,54 +34,36 @@ void _POSIX_Keys_Run_destructors( Thread_Control *thread ) { - uint32_t index; - uint32_t thread_index; - uint32_t thread_api; - uint32_t iterations; - bool are_all_null; - POSIX_Keys_Control *the_key; - void *value; - - thread_index = _Objects_Get_index( thread->Object.id ); - thread_api = _Objects_Get_API( thread->Object.id ); - - iterations = 0; - - for ( ; ; ) { - - are_all_null = true; - - for ( index=1 ; index <= _POSIX_Keys_Information.maximum ; index++ ) { - - the_key = (POSIX_Keys_Control *) - _POSIX_Keys_Information.local_table[ index ]; - - if ( !the_key ) - continue; - if ( !the_key->destructor ) - continue; - - value = the_key->Values[ thread_api ][ thread_index ]; - if ( value ) { - (*the_key->destructor)( value ); - if ( the_key->Values[ thread_api ][ thread_index ] ) - are_all_null = false; + Objects_Maximum thread_index = _Objects_Get_index( thread->Object.id ); + Objects_APIs thread_api = _Objects_Get_API( thread->Object.id ); + bool done = false; + + /* + * The standard allows one to avoid a potential infinite loop and limit the + * number of iterations. An infinite loop may happen if destructors set + * thread specific data. This can be considered dubious. + * + * Reference: 17.1.1.2 P1003.1c/Draft 10, p. 163, line 99. + */ + while ( !done ) { + Objects_Maximum index = 0; + Objects_Maximum max = _POSIX_Keys_Information.maximum; + + done = true; + + for ( index = 1 ; index <= max ; ++index ) { + POSIX_Keys_Control *key = (POSIX_Keys_Control *) + _POSIX_Keys_Information.local_table [ index ]; + + if ( key != NULL && key->destructor != NULL ) { + void *value = key->Values [ thread_api ][ thread_index ]; + + if ( value != NULL ) { + key->Values [ thread_api ][ thread_index ] = NULL; + (*key->destructor)( value ); + done = false; + } } } - - if ( are_all_null == true ) - return; - - iterations++; - - /* - * The standard allows one to not do this and thus go into an infinite - * loop. It seems rude to unnecessarily lock up a system. - * - * Reference: 17.1.1.2 P1003.1c/Draft 10, p. 163, line 99. - */ - - if ( iterations >= PTHREAD_DESTRUCTOR_ITERATIONS ) - return; } } -- cgit v1.2.3