source: rtems/cpukit/posix/src/keysetspecific.c @ 172e953

4.115
Last change on this file since 172e953 was 172e953, checked in by Sebastian Huber <sebastian.huber@…>, on 12/12/14 at 12:16:11

posix: Delete key/value if value is set to NULL

  • Property mode set to 100644
File size: 2.8 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
28static int _POSIX_Keys_Set_value(
29  pthread_key_t       key,
30  const void         *value,
31  POSIX_Keys_Control *the_key,
32  Thread_Control     *executing,
33  RBTree_Node        *rb_node
34)
35{
36  POSIX_Keys_Key_value_pair *key_value_pair;
37
38  if ( rb_node != NULL ) {
39    key_value_pair = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( rb_node );
40    key_value_pair->value = RTEMS_DECONST( void *, value );
41  } else {
42    key_value_pair = _POSIX_Keys_Key_value_pair_allocate();
43
44    if ( key_value_pair == NULL ) {
45      return ENOMEM;
46    }
47
48    key_value_pair->key = key;
49    key_value_pair->thread = executing;
50    key_value_pair->value = RTEMS_DECONST( void *, value );
51
52    /*
53     * The insert can only go wrong if the same node is already in a unique
54     * tree.  This has been already checked with the _RBTree_Find().
55     */
56    _RBTree_Insert(
57      &_POSIX_Keys_Key_value_lookup_tree,
58      &key_value_pair->Key_value_lookup_node,
59      _POSIX_Keys_Key_value_compare,
60      true
61    );
62
63    _Chain_Append_unprotected(
64      &executing->Key_Chain,
65      &key_value_pair->Key_values_per_thread_node
66    );
67  }
68
69  return 0;
70}
71
72static int _POSIX_Keys_Delete_value(
73  pthread_key_t       key,
74  POSIX_Keys_Control *the_key,
75  RBTree_Node        *rb_node
76)
77{
78
79  if ( rb_node != NULL ) {
80    POSIX_Keys_Key_value_pair *key_value_pair =
81      POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( rb_node );
82
83    _POSIX_Keys_Free_key_value_pair( key_value_pair );
84  }
85
86  return 0;
87}
88
89/*
90 *  17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
91 */
92
93int pthread_setspecific(
94  pthread_key_t  key,
95  const void    *value
96)
97{
98  POSIX_Keys_Control *the_key;
99  Objects_Locations   location;
100  Thread_Control     *executing;
101  RBTree_Node        *rb_node;
102  int                 eno;
103
104  the_key = _POSIX_Keys_Get( key, &location );
105  switch ( location ) {
106
107    case OBJECTS_LOCAL:
108      executing = _Thread_Executing;
109      rb_node = _POSIX_Keys_Find( key, executing );
110
111      if ( value != NULL ) {
112        eno = _POSIX_Keys_Set_value( key, value, the_key, executing, rb_node );
113      } else {
114        eno = _POSIX_Keys_Delete_value( key, the_key, rb_node );
115      }
116
117      _Objects_Put( &the_key->Object );
118
119      return eno;
120
121#if defined(RTEMS_MULTIPROCESSING)
122    case OBJECTS_REMOTE:   /* should never happen */
123#endif
124    case OBJECTS_ERROR:
125      break;
126  }
127
128  return EINVAL;
129}
Note: See TracBrowser for help on using the repository browser.