source: rtems/cpukit/posix/src/key.c @ 7d1436e

4.115
Last change on this file since 7d1436e was 7d1436e, checked in by Sebastian Huber <sebastian.huber@…>, on 05/06/14 at 11:41:28

posix: Fix POSIX keys initialization

Always initialize the freechain. This prevents a NULL pointer access in
case no initial key value pairs are defined.

  • Property mode set to 100644
File size: 4.4 KB
RevLine 
[a0e6c73]1/**
2 * @file
3 *
4 * @brief POSIX Keys Manager Initialization
5 * @ingroup POSIX_KEY Key
6 */
7
[7f72217e]8/*
[b5c9064]9 * Copyright (c) 2012 Zhongwei Yao.
[e6c87f7]10 * COPYRIGHT (c) 1989-2014.
[b5c9064]11 * On-Line Applications Research Corporation (OAR).
[feaa007]12 *
[b5c9064]13 * The license and distribution terms for this file may be
14 * found in the file LICENSE in this distribution or at
[c499856]15 * http://www.rtems.org/license/LICENSE.
[5e9b32b]16 */
17
[f42b726]18#if HAVE_CONFIG_H
19#include "config.h"
20#endif
21
[e6c87f7]22#include <rtems/config.h>
23
[2ad250e]24#include <rtems/posix/keyimpl.h>
25#include <rtems/score/chainimpl.h>
[c9b784f]26#include <rtems/score/objectimpl.h>
[5e9b32b]27#include <rtems/score/wkspace.h>
[b5c9064]28
29/**
30 * @brief This routine compares the rbtree node by comparing POSIX key first
31 * and comparing thread id second.
[309e2f6]32 *
[b5c9064]33 * if either of the input nodes's thread_id member is 0, then it will only
34 * compare the pthread_key_t member. That is when we pass thread_id = 0 node
35 * as a search node, the search is done only by pthread_key_t.
[309e2f6]36 *
[b5c9064]37 * @param[in] node1 The node to be compared
38 * @param[in] node2 The node to be compared
39 * @retval positive if first node has higher key than second
40 * @retval negative if lower
41 * @retval 0 if equal,and for all the thread id is unique, then return 0 is
42 * impossible
[5e9b32b]43 */
[874297f3]44
[b5c9064]45int _POSIX_Keys_Key_value_lookup_tree_compare_function(
46  const RBTree_Node *node1,
47  const RBTree_Node *node2
48)
49{
50  POSIX_Keys_Key_value_pair *n1;
51  POSIX_Keys_Key_value_pair *n2;
52  Objects_Id thread_id1, thread_id2;
53  int diff;
54
55  n1 = _RBTree_Container_of( node1, POSIX_Keys_Key_value_pair, Key_value_lookup_node );
56  n2 = _RBTree_Container_of( node2, POSIX_Keys_Key_value_pair, Key_value_lookup_node );
57
58  diff = n1->key - n2->key;
59  if ( diff )
60    return diff;
61
62  thread_id1 = n1->thread_id;
63  thread_id2 = n2->thread_id;
64
65  /**
66   * if thread_id1 or thread_id2 equals to 0, only key1 and key2 is valued.
67   * it enables us search node only by pthread_key_t type key.
68   */
69  if ( thread_id1 && thread_id2 )
70    return thread_id1 - thread_id2;
71  return 0;
72}
73
[c9b784f]74static uint32_t _POSIX_Keys_Get_keypool_bump_count( void )
[b5c9064]75{
[e6c87f7]76  uint32_t max = Configuration.maximum_key_value_pairs;
[b5c9064]77
[c9b784f]78  return _Objects_Is_unlimited( max ) ?
79    _Objects_Maximum_per_allocation( max ) : 0;
[b5c9064]80}
81
[c9b784f]82static uint32_t _POSIX_Keys_Get_initial_keypool_size( void )
[2ad250e]83{
[e6c87f7]84  uint32_t max = Configuration.maximum_key_value_pairs;
[2ad250e]85
[c9b784f]86  return _Objects_Maximum_per_allocation( max );
[2ad250e]87}
88
[c9b784f]89static bool _POSIX_Keys_Keypool_extend( Freechain_Control *keypool )
[b5c9064]90{
[c9b784f]91  size_t bump_count = _POSIX_Keys_Get_keypool_bump_count();
92  bool ok = bump_count > 0;
93
94  if ( ok ) {
95    size_t size = bump_count * sizeof( POSIX_Keys_Key_value_pair );
96    POSIX_Keys_Key_value_pair *nodes = _Workspace_Allocate( size );
97
98    ok = nodes != NULL;
99
100    if ( ok ) {
101      _Chain_Initialize(
102        &keypool->Freechain,
103        nodes,
104        bump_count,
105        sizeof( *nodes )
106      );
107    }
[b5c9064]108  }
[c9b784f]109
110  return ok;
111}
112
113static void _POSIX_Keys_Initialize_keypool( void )
114{
[7d1436e]115  Freechain_Control *keypool = &_POSIX_Keys_Keypool;
[c9b784f]116  size_t initial_count = _POSIX_Keys_Get_initial_keypool_size();
117
[7d1436e]118  _Freechain_Initialize( keypool, _POSIX_Keys_Keypool_extend );
119
120  if ( initial_count > 0 ) {
121    size_t size = initial_count * sizeof( POSIX_Keys_Key_value_pair );
[57c2985]122    POSIX_Keys_Key_value_pair *nodes =
123      _Workspace_Allocate_or_fatal_error( size );
[c9b784f]124
[57c2985]125    _Chain_Initialize(
126      &keypool->Freechain,
127      nodes,
128      initial_count,
129      sizeof( *nodes )
130    );
131  }
[b5c9064]132}
133
134/**
135 * @brief This routine performs the initialization necessary for this manager.
136 */
[309e2f6]137void _POSIX_Key_Manager_initialization(void)
[5e9b32b]138{
139  _Objects_Initialize_information(
[3c465878]140    &_POSIX_Keys_Information,   /* object information table */
141    OBJECTS_POSIX_API,          /* object API */
142    OBJECTS_POSIX_KEYS,         /* object class */
[e6c87f7]143    Configuration.maximum_keys,
[309e2f6]144                                /* maximum objects of this class */
[5e9b32b]145    sizeof( POSIX_Keys_Control ),
[3c465878]146                                /* size of this object's control block */
[b1dbfd7]147    true,                       /* true if names for this object are strings */
[74d0cb44]148    _POSIX_PATH_MAX             /* maximum length of each object's name */
[3c465878]149#if defined(RTEMS_MULTIPROCESSING)
150    ,
[b1dbfd7]151    false,                      /* true if this is a global object class */
[3c465878]152    NULL                        /* Proxy extraction support callout */
153#endif
[5e9b32b]154  );
[b5c9064]155
156  _RBTree_Initialize_empty(
157      &_POSIX_Keys_Key_value_lookup_tree,
158      _POSIX_Keys_Key_value_lookup_tree_compare_function,
159      true
160  );
161
[c9b784f]162  _POSIX_Keys_Initialize_keypool();
[5e9b32b]163}
Note: See TracBrowser for help on using the repository browser.