(root)/
gettext-0.22.4/
gettext-tools/
gnulib-tests/
pthread-thread.c
       1  /* Creating and controlling POSIX threads.
       2     Copyright (C) 2010-2023 Free Software Foundation, Inc.
       3  
       4     This file is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU Lesser General Public License as
       6     published by the Free Software Foundation; either version 2.1 of the
       7     License, or (at your option) any later version.
       8  
       9     This file 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
      12     GNU Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  /* Written by Paul Eggert, 2010, and Bruno Haible <bruno@clisp.org>, 2019.  */
      18  
      19  #include <config.h>
      20  
      21  /* Specification.  */
      22  #include <pthread.h>
      23  
      24  #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS
      25  # include "windows-thread.h"
      26  #else
      27  # include <stdlib.h>
      28  #endif
      29  
      30  typedef void * (* pthread_main_function_t) (void *);
      31  
      32  #if ((defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS) || !HAVE_PTHREAD_H
      33  
      34  int
      35  pthread_attr_init (pthread_attr_t *attr)
      36  {
      37    *attr = PTHREAD_CREATE_JOINABLE;
      38    return 0;
      39  }
      40  
      41  int
      42  pthread_attr_getdetachstate (const pthread_attr_t *attr, int *detachstatep)
      43  {
      44    *detachstatep = *attr & (PTHREAD_CREATE_JOINABLE | PTHREAD_CREATE_DETACHED);
      45    return 0;
      46  }
      47  
      48  int
      49  pthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate)
      50  {
      51    if (!(detachstate == PTHREAD_CREATE_JOINABLE
      52          || detachstate == PTHREAD_CREATE_DETACHED))
      53      return EINVAL;
      54    *attr ^= (*attr ^ detachstate)
      55             & (PTHREAD_CREATE_JOINABLE | PTHREAD_CREATE_DETACHED);
      56    return 0;
      57  }
      58  
      59  int
      60  pthread_attr_destroy (_GL_UNUSED pthread_attr_t *attr)
      61  {
      62    return 0;
      63  }
      64  
      65  #endif
      66  
      67  #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS
      68  /* Use Windows threads.  */
      69  
      70  int
      71  pthread_create (pthread_t *threadp, const pthread_attr_t *attr,
      72                  pthread_main_function_t mainfunc, void *arg)
      73  {
      74    unsigned int glwthread_attr =
      75      (attr != NULL
      76       && (*attr & (PTHREAD_CREATE_JOINABLE | PTHREAD_CREATE_DETACHED))
      77          != PTHREAD_CREATE_JOINABLE
      78       ? GLWTHREAD_ATTR_DETACHED
      79       : 0);
      80    return glwthread_thread_create (threadp, glwthread_attr, mainfunc, arg);
      81  }
      82  
      83  pthread_t
      84  pthread_self (void)
      85  {
      86    return glwthread_thread_self ();
      87  }
      88  
      89  int
      90  pthread_equal (pthread_t thread1, pthread_t thread2)
      91  {
      92    return thread1 == thread2;
      93  }
      94  
      95  int
      96  pthread_detach (pthread_t thread)
      97  {
      98    return glwthread_thread_detach (thread);
      99  }
     100  
     101  int
     102  pthread_join (pthread_t thread, void **valuep)
     103  {
     104    return glwthread_thread_join (thread, valuep);
     105  }
     106  
     107  void
     108  pthread_exit (void *value)
     109  {
     110    glwthread_thread_exit (value);
     111  }
     112  
     113  #elif HAVE_PTHREAD_H
     114  /* Provide workarounds for POSIX threads.  */
     115  
     116  # if PTHREAD_CREATE_IS_INLINE
     117  int
     118  pthread_create (pthread_t *threadp, const pthread_attr_t *attr,
     119                  pthread_main_function_t mainfunc, void *arg)
     120  #  undef pthread_create
     121  {
     122    return pthread_create (threadp, attr, mainfunc, arg);
     123  }
     124  
     125  int
     126  pthread_attr_init (pthread_attr_t *attr)
     127  #  undef pthread_attr_init
     128  {
     129    return pthread_attr_init (attr);
     130  }
     131  
     132  # endif
     133  
     134  #else
     135  /* Provide a dummy implementation for single-threaded applications.  */
     136  
     137  int
     138  pthread_create (pthread_t *threadp, const pthread_attr_t *attr,
     139                  pthread_main_function_t mainfunc, void *arg)
     140  {
     141    /* The maximum number of threads is reached.  Do not create a thread.  */
     142    return EAGAIN;
     143  }
     144  
     145  pthread_t
     146  pthread_self (void)
     147  {
     148    return 42;
     149  }
     150  
     151  int
     152  pthread_equal (pthread_t thread1, pthread_t thread2)
     153  {
     154    return thread1 == thread2;
     155  }
     156  
     157  int
     158  pthread_detach (pthread_t thread)
     159  {
     160    /* There are no joinable threads.  */
     161    return EINVAL;
     162  }
     163  
     164  int
     165  pthread_join (pthread_t thread, void **valuep)
     166  {
     167    /* There are no joinable threads.  */
     168    return EINVAL;
     169  }
     170  
     171  void
     172  pthread_exit (void *value)
     173  {
     174    /* There is just one thread, so the process exits.  */
     175    exit (0);
     176  }
     177  
     178  #endif