mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-02-04 20:51:36 +00:00
posix: Prevent pthread_setspecific from returning EAGAIN.
The man-page for pthread_setspecific does not define the EAGAIN return value. Further without this patch it was not possible to set keys that have been already set a new value. Add test for setting a new value to a already set key.
This commit is contained in:
committed by
Sebastian Huber
parent
8e133b2500
commit
01f2337432
@@ -37,37 +37,48 @@ int pthread_setspecific(
|
||||
POSIX_Keys_Control *the_key;
|
||||
Objects_Locations location;
|
||||
POSIX_Keys_Key_value_pair *value_pair_ptr;
|
||||
RBTree_Node *p;
|
||||
POSIX_Keys_Key_value_pair search_node;
|
||||
|
||||
the_key = _POSIX_Keys_Get( key, &location );
|
||||
switch ( location ) {
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
value_pair_ptr = _POSIX_Keys_Key_value_pair_allocate();
|
||||
search_node.key = key;
|
||||
search_node.thread_id = _Thread_Executing->Object.id;
|
||||
p = _RBTree_Find( &_POSIX_Keys_Key_value_lookup_tree,
|
||||
&search_node.Key_value_lookup_node );
|
||||
|
||||
if ( !value_pair_ptr ) {
|
||||
_Objects_Put( &the_key->Object );
|
||||
if ( p ) {
|
||||
value_pair_ptr = _RBTree_Container_of( p,
|
||||
POSIX_Keys_Key_value_pair,
|
||||
Key_value_lookup_node );
|
||||
|
||||
return ENOMEM;
|
||||
value_pair_ptr->value = value;
|
||||
} else {
|
||||
value_pair_ptr = _POSIX_Keys_Key_value_pair_allocate();
|
||||
|
||||
if ( !value_pair_ptr ) {
|
||||
_Objects_Put( &the_key->Object );
|
||||
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
value_pair_ptr->key = key;
|
||||
value_pair_ptr->thread_id = _Thread_Executing->Object.id;
|
||||
value_pair_ptr->value = value;
|
||||
/* The insert can only go wrong if the same node is already in a unique
|
||||
* tree. This has been already checked with the _RBTree_Find() */
|
||||
(void) _RBTree_Insert( &_POSIX_Keys_Key_value_lookup_tree,
|
||||
&(value_pair_ptr->Key_value_lookup_node) );
|
||||
|
||||
/** append rb_node to the thread API extension's chain */
|
||||
_Chain_Append_unprotected(
|
||||
&_Thread_Executing->Key_Chain,
|
||||
&value_pair_ptr->Key_values_per_thread_node
|
||||
);
|
||||
}
|
||||
|
||||
value_pair_ptr->key = key;
|
||||
value_pair_ptr->thread_id = _Thread_Executing->Object.id;
|
||||
value_pair_ptr->value = value;
|
||||
if ( _RBTree_Insert( &_POSIX_Keys_Key_value_lookup_tree,
|
||||
&(value_pair_ptr->Key_value_lookup_node) ) ) {
|
||||
_Freechain_Put( (Freechain_Control *)&_POSIX_Keys_Keypool,
|
||||
(void *) value_pair_ptr );
|
||||
_Objects_Put( &the_key->Object );
|
||||
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
/** append rb_node to the thread API extension's chain */
|
||||
_Chain_Append_unprotected(
|
||||
&_Thread_Executing->Key_Chain,
|
||||
&value_pair_ptr->Key_values_per_thread_node
|
||||
);
|
||||
|
||||
_Objects_Put( &the_key->Object );
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -52,6 +52,14 @@ rtems_task Init( rtems_task_argument ignored )
|
||||
value = pthread_getspecific( key2 );
|
||||
rtems_test_assert( *value == Data_array[1] );
|
||||
|
||||
puts( "Init - key1 pthread_setspecific - OK" );
|
||||
sc = pthread_setspecific( key1, &Data_array[1] );
|
||||
rtems_test_assert( !sc );
|
||||
|
||||
puts( "Init - key1 pthread_getspecific - OK" );
|
||||
value = pthread_getspecific( key1 );
|
||||
rtems_test_assert( *value == Data_array[1] );
|
||||
|
||||
puts( "Init - pthread key1 delete - OK" );
|
||||
sc = pthread_key_delete( key1 );
|
||||
rtems_test_assert( sc == 0 );
|
||||
|
||||
@@ -20,3 +20,4 @@ directives:
|
||||
concepts:
|
||||
|
||||
+ Ensure that key data's operation(create, set, get and delete) under multikeys work.
|
||||
+ Ensure that key can be set to a new value.
|
||||
|
||||
@@ -8,6 +8,8 @@ Init - key1 pthread_setspecific - OK
|
||||
Init - key2 pthread_setspecific - OK
|
||||
Init - key1 pthread_getspecific - OK
|
||||
Init - key2 pthread_getspecific - OK
|
||||
Init - key1 pthread_setspecific - OK
|
||||
Init - key1 pthread_getspecific - OK
|
||||
Init - pthread key1 delete - OK
|
||||
Init - pthread key2 delete - OK
|
||||
*** END OF TEST KEY 05 ***
|
||||
|
||||
Reference in New Issue
Block a user