[rtems commit] posix: Prevent pthread_setspecific from returning EAGAIN.
Sebastian Huber
sebh at rtems.org
Mon Mar 24 07:25:02 UTC 2014
Module: rtems
Branch: master
Commit: 01f2337432d6a0ac92a022161370955172bc95fc
Changeset: http://git.rtems.org/rtems/commit/?id=01f2337432d6a0ac92a022161370955172bc95fc
Author: Christian Mauderer <Christian.Mauderer at embedded-brains.de>
Date: Fri Mar 21 12:07:27 2014 +0100
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.
---
cpukit/posix/src/keysetspecific.c | 59 +++++++++++++++++------------
testsuites/psxtests/psxkey05/init.c | 8 ++++
testsuites/psxtests/psxkey05/psxkey05.doc | 1 +
testsuites/psxtests/psxkey05/psxkey05.scn | 2 +
4 files changed, 46 insertions(+), 24 deletions(-)
diff --git a/cpukit/posix/src/keysetspecific.c b/cpukit/posix/src/keysetspecific.c
index 9b2271e..3284991 100644
--- a/cpukit/posix/src/keysetspecific.c
+++ b/cpukit/posix/src/keysetspecific.c
@@ -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();
-
- 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;
- 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;
+ 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 ( p ) {
+ value_pair_ptr = _RBTree_Container_of( p,
+ POSIX_Keys_Key_value_pair,
+ Key_value_lookup_node );
+
+ 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
+ );
}
- /** 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;
diff --git a/testsuites/psxtests/psxkey05/init.c b/testsuites/psxtests/psxkey05/init.c
index 90fcb60..9fdd968 100644
--- a/testsuites/psxtests/psxkey05/init.c
+++ b/testsuites/psxtests/psxkey05/init.c
@@ -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 );
diff --git a/testsuites/psxtests/psxkey05/psxkey05.doc b/testsuites/psxtests/psxkey05/psxkey05.doc
index 9e0d04f..90158eb 100644
--- a/testsuites/psxtests/psxkey05/psxkey05.doc
+++ b/testsuites/psxtests/psxkey05/psxkey05.doc
@@ -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.
diff --git a/testsuites/psxtests/psxkey05/psxkey05.scn b/testsuites/psxtests/psxkey05/psxkey05.scn
index 89127af..9956501 100644
--- a/testsuites/psxtests/psxkey05/psxkey05.scn
+++ b/testsuites/psxtests/psxkey05/psxkey05.scn
@@ -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 ***
More information about the vc
mailing list