source: rtems/cpukit/posix/src/keysetspecific.c @ dac340dd

4.115
Last change on this file since dac340dd was dac340dd, checked in by Sebastian Huber <sebastian.huber@…>, on 12/12/14 at 10:19:10

posix: Simplify _POSIX_Keys_Find()

  • Property mode set to 100644
File size: 2.3 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  Thread_Control              *executing;
42
43  the_key = _POSIX_Keys_Get( key, &location );
44  switch ( location ) {
45
46    case OBJECTS_LOCAL:
47      executing = _Thread_Executing;
48      p = _POSIX_Keys_Find( key, executing );
49      if ( p != NULL ) {
50        value_pair_ptr = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( p );
51        value_pair_ptr->value = RTEMS_DECONST( void *, value );
52      } else {
53        value_pair_ptr = _POSIX_Keys_Key_value_pair_allocate();
54
55        if ( !value_pair_ptr ) {
56          _Objects_Put( &the_key->Object );
57
58          return ENOMEM;
59        }
60
61        value_pair_ptr->key = key;
62        value_pair_ptr->thread = executing;
63        value_pair_ptr->value = RTEMS_DECONST( void *, value );
64        /* The insert can only go wrong if the same node is already in a unique
65         * tree. This has been already checked with the _RBTree_Find() */
66        _RBTree_Insert(
67          &_POSIX_Keys_Key_value_lookup_tree,
68          &value_pair_ptr->Key_value_lookup_node,
69          _POSIX_Keys_Key_value_compare,
70          true
71        );
72
73        /** append rb_node to the thread API extension's chain */
74        _Chain_Append_unprotected(
75          &_Thread_Executing->Key_Chain,
76          &value_pair_ptr->Key_values_per_thread_node
77        );
78      }
79
80      _Objects_Put( &the_key->Object );
81
82      return 0;
83
84#if defined(RTEMS_MULTIPROCESSING)
85    case OBJECTS_REMOTE:   /* should never happen */
86#endif
87    case OBJECTS_ERROR:
88      break;
89  }
90
91  return EINVAL;
92}
Note: See TracBrowser for help on using the repository browser.