Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:21

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup POSIXAPI
0007  *
0008  * @brief Set Specific Key
0009  */
0010 
0011 /*
0012  * Copyright (c) 2012 Zhongwei Yao.
0013  * COPYRIGHT (c) 1989-2014.
0014  * On-Line Applications Research Corporation (OAR).
0015  * Copyright (c) 2016 embedded brains GmbH & Co. KG
0016  *
0017  * Redistribution and use in source and binary forms, with or without
0018  * modification, are permitted provided that the following conditions
0019  * are met:
0020  * 1. Redistributions of source code must retain the above copyright
0021  *    notice, this list of conditions and the following disclaimer.
0022  * 2. Redistributions in binary form must reproduce the above copyright
0023  *    notice, this list of conditions and the following disclaimer in the
0024  *    documentation and/or other materials provided with the distribution.
0025  *
0026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0036  * POSSIBILITY OF SUCH DAMAGE.
0037  */
0038 
0039 #ifdef HAVE_CONFIG_H
0040 #include "config.h"
0041 #endif
0042 
0043 #include <rtems/posix/keyimpl.h>
0044 
0045 #include <errno.h>
0046 
0047 static int _POSIX_Keys_Set_value(
0048   POSIX_Keys_Key_value_pair *key_value_pair,
0049   const void                *value
0050 )
0051 {
0052   key_value_pair->value = RTEMS_DECONST( void *, value );
0053 
0054   return 0;
0055 }
0056 
0057 static int _POSIX_Keys_Create_value(
0058   pthread_key_t       key,
0059   const void         *value,
0060   Thread_Control     *executing
0061 )
0062 {
0063   POSIX_Keys_Control *the_key;
0064   int                 eno;
0065 
0066   _Objects_Allocator_lock();
0067 
0068   the_key = _POSIX_Keys_Get( key );
0069   if ( the_key != NULL ) {
0070     POSIX_Keys_Key_value_pair *key_value_pair;
0071 
0072     key_value_pair = _POSIX_Keys_Key_value_allocate();
0073     if ( key_value_pair != NULL ) {
0074       ISR_lock_Context lock_context;
0075 
0076       key_value_pair->key = key;
0077       key_value_pair->thread = executing;
0078       key_value_pair->value = RTEMS_DECONST( void *, value );
0079 
0080       _RBTree_Initialize_node( &key_value_pair->Lookup_node );
0081 
0082       _Chain_Initialize_node( &key_value_pair->Key_node );
0083       _Chain_Append_unprotected(
0084         &the_key->Key_value_pairs,
0085         &key_value_pair->Key_node
0086       );
0087 
0088       _POSIX_Keys_Key_value_acquire( executing, &lock_context );
0089       _POSIX_Keys_Key_value_insert( key, key_value_pair, executing );
0090       _POSIX_Keys_Key_value_release( executing, &lock_context );
0091       eno = 0;
0092     } else {
0093       eno = ENOMEM;
0094     }
0095 
0096   } else {
0097     eno = EINVAL;
0098   }
0099 
0100   _Objects_Allocator_unlock();
0101 
0102   return eno;
0103 }
0104 
0105 static int _POSIX_Keys_Delete_value(
0106   pthread_key_t   key,
0107   Thread_Control *executing
0108 )
0109 {
0110   POSIX_Keys_Control *the_key;
0111   int                 eno;
0112 
0113   _Objects_Allocator_lock();
0114 
0115   the_key = _POSIX_Keys_Get( key );
0116   if ( the_key != NULL ) {
0117     POSIX_Keys_Key_value_pair *key_value_pair;
0118     ISR_lock_Context           lock_context;
0119 
0120     _POSIX_Keys_Key_value_acquire( executing, &lock_context );
0121 
0122     key_value_pair = _POSIX_Keys_Key_value_find( key, executing );
0123     if ( key_value_pair != NULL ) {
0124       _RBTree_Extract(
0125         &executing->Keys.Key_value_pairs,
0126         &key_value_pair->Lookup_node
0127       );
0128 
0129       _POSIX_Keys_Key_value_release( executing, &lock_context );
0130 
0131       _POSIX_Keys_Key_value_free( key_value_pair );
0132     } else {
0133       _POSIX_Keys_Key_value_release( executing, &lock_context );
0134     }
0135 
0136     eno = 0;
0137   } else {
0138     eno = EINVAL;
0139   }
0140 
0141   _Objects_Allocator_unlock();
0142 
0143   return eno;
0144 }
0145 
0146 /*
0147  *  17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
0148  */
0149 
0150 int pthread_setspecific(
0151   pthread_key_t  key,
0152   const void    *value
0153 )
0154 {
0155   Thread_Control   *executing;
0156   int               eno;
0157 
0158   executing = _Thread_Get_executing();
0159 
0160   if ( value != NULL ) {
0161     ISR_lock_Context           lock_context;
0162     POSIX_Keys_Key_value_pair *key_value_pair;
0163 
0164     _POSIX_Keys_Key_value_acquire( executing, &lock_context );
0165 
0166     key_value_pair = _POSIX_Keys_Key_value_find( key, executing );
0167     if ( key_value_pair != NULL ) {
0168       eno = _POSIX_Keys_Set_value( key_value_pair, value );
0169       _POSIX_Keys_Key_value_release( executing, &lock_context );
0170     } else {
0171       _POSIX_Keys_Key_value_release( executing, &lock_context );
0172       eno = _POSIX_Keys_Create_value( key, value, executing );
0173     }
0174   } else {
0175     eno = _POSIX_Keys_Delete_value( key, executing );
0176   }
0177 
0178   return eno;
0179 }