source: rtems/cpukit/posix/src/keysetspecific.c @ 01f23374

4.11
Last change on this file since 01f23374 was 01f23374, checked in by Christian Mauderer <Christian.Mauderer@…>, on Mar 21, 2014 at 11:07:27 AM

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.

  • Property mode set to 100644
File size: 2.4 KB
Line 
1/**
2 * @file
3 *
4 * @brief Set Specific Key
5 * @ingroup POSIXAPI
6 */
7
8/*
9 * Copyright (c) 2012 Zhongwei Yao.
10 * COPYRIGHT (c) 1989-2014.
11 * On-Line Applications Research Corporation (OAR).
12 *
13 * The license and distribution terms for this file may be
14 * found in the file LICENSE in this distribution or at
15 * http://www.rtems.org/license/LICENSE.
16 */
17
18#if HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#include <rtems/posix/keyimpl.h>
23#include <rtems/score/thread.h>
24#include <rtems/score/chainimpl.h>
25
26#include <errno.h>
27
28/*
29 *  17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
30 */
31
32int pthread_setspecific(
33  pthread_key_t  key,
34  const void    *value
35)
36{
37  POSIX_Keys_Control          *the_key;
38  Objects_Locations            location;
39  POSIX_Keys_Key_value_pair   *value_pair_ptr;
40  RBTree_Node                 *p;
41  POSIX_Keys_Key_value_pair    search_node;
42
43  the_key = _POSIX_Keys_Get( key, &location );
44  switch ( location ) {
45
46    case OBJECTS_LOCAL:
47      search_node.key = key;
48      search_node.thread_id = _Thread_Executing->Object.id;
49      p = _RBTree_Find( &_POSIX_Keys_Key_value_lookup_tree,
50                                    &search_node.Key_value_lookup_node );
51
52      if ( p ) {
53        value_pair_ptr = _RBTree_Container_of( p,
54                                          POSIX_Keys_Key_value_pair,
55                                          Key_value_lookup_node );
56
57        value_pair_ptr->value = value;
58      } else {
59        value_pair_ptr = _POSIX_Keys_Key_value_pair_allocate();
60
61        if ( !value_pair_ptr ) {
62          _Objects_Put( &the_key->Object );
63
64          return ENOMEM;
65        }
66
67        value_pair_ptr->key = key;
68        value_pair_ptr->thread_id = _Thread_Executing->Object.id;
69        value_pair_ptr->value = value;
70        /* The insert can only go wrong if the same node is already in a unique
71         * tree. This has been already checked with the _RBTree_Find() */
72        (void) _RBTree_Insert( &_POSIX_Keys_Key_value_lookup_tree,
73                             &(value_pair_ptr->Key_value_lookup_node) );
74
75        /** append rb_node to the thread API extension's chain */
76        _Chain_Append_unprotected(
77          &_Thread_Executing->Key_Chain,
78          &value_pair_ptr->Key_values_per_thread_node
79        );
80      }
81
82      _Objects_Put( &the_key->Object );
83
84      return 0;
85
86#if defined(RTEMS_MULTIPROCESSING)
87    case OBJECTS_REMOTE:   /* should never happen */
88#endif
89    case OBJECTS_ERROR:
90      break;
91  }
92
93  return EINVAL;
94}
Note: See TracBrowser for help on using the repository browser.