PR 1615/cpukit
	* posix/src/keyrundestructors.c: Improved POSIX compliance.  Now we may
	have an unlimited number of iterations.
This commit is contained in:
Sebastian Huber
2010-08-09 08:13:47 +00:00
parent 718a0c5fa3
commit e600b886f9
2 changed files with 33 additions and 48 deletions

View File

@@ -1,3 +1,9 @@
2010-08-09 Sebastian Huber <sebastian.huber@embedded-brains.de>
PR 1615/cpukit
* posix/src/keyrundestructors.c: Improved POSIX compliance. Now we may
have an unlimited number of iterations.
2010-08-09 Sebastian Huber <sebastian.huber@embedded-brains.de>
* sapi/inline/rtems/chain.inl: Added

View File

@@ -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 <errno.h>
#include <limits.h>
#include <pthread.h>
#include <string.h>
#include <rtems/system.h>
#include <rtems/score/object.h>
#include <rtems/score/thread.h>
#include <rtems/score/wkspace.h>
#include <rtems/posix/key.h>
/*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;
Objects_Maximum thread_index = _Objects_Get_index( thread->Object.id );
Objects_APIs thread_api = _Objects_Get_API( thread->Object.id );
bool done = false;
thread_index = _Objects_Get_index( thread->Object.id );
thread_api = _Objects_Get_API( thread->Object.id );
/*
* 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;
iterations = 0;
done = true;
for ( ; ; ) {
for ( index = 1 ; index <= max ; ++index ) {
POSIX_Keys_Control *key = (POSIX_Keys_Control *)
_POSIX_Keys_Information.local_table [ index ];
are_all_null = true;
if ( key != NULL && key->destructor != NULL ) {
void *value = key->Values [ thread_api ][ thread_index ];
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;
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;
}
}