(root)/
glibc-2.38/
nptl/
tst-tsd3.c
       1  /* Copyright (C) 2003-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <limits.h>
      19  #include <pthread.h>
      20  #include <stdio.h>
      21  #include <stdlib.h>
      22  #include <unistd.h>
      23  
      24  
      25  static pthread_key_t key1;
      26  static pthread_key_t key2;
      27  
      28  
      29  static int left;
      30  
      31  
      32  static void
      33  destr1 (void *arg)
      34  {
      35    if (--left > 0)
      36      {
      37        puts ("set key2");
      38  
      39        /* Use an arbitrary but valid pointer to avoid GCC warnings.  */
      40        if (pthread_setspecific (key2, (void *) &left) != 0)
      41  	{
      42  	  puts ("destr1: setspecific failed");
      43  	  exit (1);
      44  	}
      45      }
      46  }
      47  
      48  
      49  static void
      50  destr2 (void *arg)
      51  {
      52    if (--left > 0)
      53      {
      54        puts ("set key1");
      55  
      56        /* Use an arbitrary but valid pointer to avoid GCC warnings.  */
      57        if (pthread_setspecific (key1, (void *) &left) != 0)
      58  	{
      59  	  puts ("destr2: setspecific failed");
      60  	  exit (1);
      61  	}
      62      }
      63  }
      64  
      65  
      66  static void *
      67  tf (void *arg)
      68  {
      69    /* Let the destructors work.  */
      70    left = 7;
      71  
      72    /* Use an arbitrary but valid pointer to avoid GCC warnings.  */
      73    if (pthread_setspecific (key1, (void *) &left) != 0
      74        || pthread_setspecific (key2, (void *) &left) != 0)
      75      {
      76        puts ("tf: setspecific failed");
      77        exit (1);
      78      }
      79  
      80    return NULL;
      81  }
      82  
      83  
      84  static int
      85  do_test (void)
      86  {
      87    /* Allocate two keys, both with destructors.  */
      88    if (pthread_key_create (&key1, destr1) != 0
      89        || pthread_key_create (&key2, destr2) != 0)
      90      {
      91        puts ("key_create failed");
      92        return 1;
      93      }
      94  
      95    pthread_t th;
      96    if (pthread_create (&th, NULL, tf, NULL) != 0)
      97      {
      98        puts ("create failed");
      99        return 1;
     100      }
     101  
     102    if (pthread_join (th, NULL) != 0)
     103      {
     104        puts ("join failed");
     105        return 1;
     106      }
     107  
     108    if (left != 0)
     109      {
     110        printf ("left == %d\n", left);
     111        return 1;
     112      }
     113  
     114    if (pthread_getspecific (key1) != NULL)
     115      {
     116        puts ("key1 data != NULL");
     117        return 1;
     118      }
     119    if (pthread_getspecific (key2) != NULL)
     120      {
     121        puts ("key2 data != NULL");
     122        return 1;
     123      }
     124  
     125    return 0;
     126  }
     127  
     128  
     129  #define TEST_FUNCTION do_test ()
     130  #include "../test-skeleton.c"