blob: f79f9b90a671a7bba5da53ab2efb8dee26b234d2 [file] [log] [blame]
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00001
Guido van Rossum66020991996-06-11 18:32:18 +00002/* Posix threads interface */
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00003
Guido van Rossum66020991996-06-11 18:32:18 +00004#include <stdlib.h>
Guido van Rossum9e46e561998-10-07 16:39:47 +00005#include <string.h>
Martin v. Löwisa7a76d32002-10-04 07:21:24 +00006#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
Jack Jansen76689572002-01-15 20:36:14 +00007#define destructor xxdestructor
8#endif
Guido van Rossum66020991996-06-11 18:32:18 +00009#include <pthread.h>
Martin v. Löwisa7a76d32002-10-04 07:21:24 +000010#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
Jack Jansen76689572002-01-15 20:36:14 +000011#undef destructor
12#endif
Guido van Rossum80230992001-10-12 21:49:17 +000013#include <signal.h>
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000014
Thomas Wouters0e3f5912006-08-11 14:57:12 +000015/* The POSIX spec requires that use of pthread_attr_setstacksize
16 be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
17#ifdef _POSIX_THREAD_ATTR_STACKSIZE
18#ifndef THREAD_STACK_SIZE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000019#define THREAD_STACK_SIZE 0 /* use default stack size */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000020#endif
Ned Deily9a7c5242011-05-28 00:19:56 -070021
Ned Deily7ca97d52012-03-13 11:18:18 -070022/* The default stack size for new threads on OSX and BSD is small enough that
23 * we'll get hard crashes instead of 'maximum recursion depth exceeded'
24 * exceptions.
25 *
26 * The default stack sizes below are the empirically determined minimal stack
27 * sizes where a simple recursive function doesn't cause a hard crash.
28 */
29#if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
30#undef THREAD_STACK_SIZE
31#define THREAD_STACK_SIZE 0x500000
32#endif
33#if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
Ned Deily9a7c5242011-05-28 00:19:56 -070034#undef THREAD_STACK_SIZE
35#define THREAD_STACK_SIZE 0x400000
36#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000037/* for safety, ensure a viable minimum stacksize */
Victor Stinner8c663fd2017-11-08 14:44:44 -080038#define THREAD_STACK_MIN 0x8000 /* 32 KiB */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000039#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
40#ifdef THREAD_STACK_SIZE
41#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
42#endif
43#endif
44
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000045/* The POSIX spec says that implementations supporting the sem_*
46 family of functions must indicate this by defining
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000047 _POSIX_SEMAPHORES. */
Martin v. Löwiscc898662002-03-17 09:53:51 +000048#ifdef _POSIX_SEMAPHORES
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000049/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
Martin v. Löwis8b8fb3d2005-03-28 12:34:20 +000050 we need to add 0 to make it work there as well. */
51#if (_POSIX_SEMAPHORES+0) == -1
Anthony Baxter19b23692005-03-16 04:15:07 +000052#define HAVE_BROKEN_POSIX_SEMAPHORES
53#else
Martin v. Löwiscc898662002-03-17 09:53:51 +000054#include <semaphore.h>
55#include <errno.h>
56#endif
Anthony Baxter19b23692005-03-16 04:15:07 +000057#endif
Guido van Rossum66020991996-06-11 18:32:18 +000058
Martin v. Löwisb0233812002-12-11 13:12:30 +000059#if !defined(pthread_attr_default)
Guido van Rossumd6353e21997-05-13 17:51:13 +000060# define pthread_attr_default ((pthread_attr_t *)NULL)
Martin v. Löwisb0233812002-12-11 13:12:30 +000061#endif
62#if !defined(pthread_mutexattr_default)
Guido van Rossumd6353e21997-05-13 17:51:13 +000063# define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL)
Martin v. Löwisb0233812002-12-11 13:12:30 +000064#endif
65#if !defined(pthread_condattr_default)
Guido van Rossumd6353e21997-05-13 17:51:13 +000066# define pthread_condattr_default ((pthread_condattr_t *)NULL)
Guido van Rossum1a623111996-08-08 18:53:41 +000067#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000068
Guido van Rossumd6353e21997-05-13 17:51:13 +000069
Martin v. Löwiscc898662002-03-17 09:53:51 +000070/* Whether or not to use semaphores directly rather than emulating them with
71 * mutexes and condition variables:
72 */
Antoine Pitrou19f8edc2010-10-10 08:37:22 +000073#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
74 defined(HAVE_SEM_TIMEDWAIT))
Martin v. Löwiscc898662002-03-17 09:53:51 +000075# define USE_SEMAPHORES
76#else
77# undef USE_SEMAPHORES
78#endif
79
80
Guido van Rossum80230992001-10-12 21:49:17 +000081/* On platforms that don't use standard POSIX threads pthread_sigmask()
82 * isn't present. DEC threads uses sigprocmask() instead as do most
83 * other UNIX International compliant systems that don't have the full
84 * pthread implementation.
85 */
Jason Tishlerfac083d2003-07-22 15:20:49 +000086#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Guido van Rossum80230992001-10-12 21:49:17 +000087# define SET_THREAD_SIGMASK pthread_sigmask
88#else
89# define SET_THREAD_SIGMASK sigprocmask
90#endif
91
92
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000093/* We assume all modern POSIX systems have gettimeofday() */
94#ifdef GETTIMEOFDAY_NO_TZ
95#define GETTIMEOFDAY(ptv) gettimeofday(ptv)
96#else
97#define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL)
98#endif
99
100#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
101do { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000102 struct timeval tv; \
103 GETTIMEOFDAY(&tv); \
104 tv.tv_usec += microseconds % 1000000; \
105 tv.tv_sec += microseconds / 1000000; \
106 tv.tv_sec += tv.tv_usec / 1000000; \
107 tv.tv_usec %= 1000000; \
108 ts.tv_sec = tv.tv_sec; \
109 ts.tv_nsec = tv.tv_usec * 1000; \
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000110} while(0)
111
112
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000113/* A pthread mutex isn't sufficient to model the Python lock type
114 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
115 * following are undefined:
116 * -> a thread tries to lock a mutex it already has locked
117 * -> a thread tries to unlock a mutex locked by a different thread
118 * pthread mutexes are designed for serializing threads over short pieces
119 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000120 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000121 *
122 * The pthread_lock struct implements a Python lock as a "locked?" bit
123 * and a <condition, mutex> pair. In general, if the bit can be acquired
124 * instantly, it is, else the pair is used to block the thread until the
125 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000126 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000127
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000128typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 char locked; /* 0=unlocked, 1=locked */
130 /* a <cond, mutex> pair to handle an acquire of a locked lock */
131 pthread_cond_t lock_released;
132 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000133} pthread_lock;
134
Guido van Rossum9e46e561998-10-07 16:39:47 +0000135#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100136#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
137 "%s: %s\n", name, strerror(status)); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000138
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000139/*
140 * Initialization.
141 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000142static void
143PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000144{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000145#if defined(_AIX) && defined(__GNUC__)
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200146 extern void pthread_init(void);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 pthread_init();
Guido van Rossumd21744a1998-09-10 03:04:40 +0000148#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000149}
150
151/*
152 * Thread support.
153 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000154
Miss Islington (bot)b1355352018-11-30 07:32:12 -0800155/* bpo-33015: pythread_callback struct and pythread_wrapper() cast
156 "void func(void *)" to "void* func(void *)": always return NULL.
157
158 PyThread_start_new_thread() uses "void func(void *)" type, whereas
159 pthread_create() requires a void* return value. */
160typedef struct {
161 void (*func) (void *);
162 void *arg;
163} pythread_callback;
164
165static void *
166pythread_wrapper(void *arg)
167{
168 /* copy func and func_arg and free the temporary structure */
169 pythread_callback *callback = arg;
170 void (*func)(void *) = callback->func;
171 void *func_arg = callback->arg;
172 PyMem_RawFree(arg);
173
174 func(func_arg);
175 return NULL;
176}
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000177
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200178unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000179PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000181 pthread_t th;
182 int status;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000183#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000184 pthread_attr_t attrs;
Jack Jansenc51395d2001-08-29 15:24:53 +0000185#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000186#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187 size_t tss;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000188#endif
189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000190 dprintf(("PyThread_start_new_thread called\n"));
191 if (!initialized)
192 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000193
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000194#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 if (pthread_attr_init(&attrs) != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200196 return PYTHREAD_INVALID_THREAD_ID;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000197#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000198#if defined(THREAD_STACK_SIZE)
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600199 PyThreadState *tstate = PyThreadState_GET();
200 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
201 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000202 if (tss != 0) {
203 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
204 pthread_attr_destroy(&attrs);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200205 return PYTHREAD_INVALID_THREAD_ID;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 }
207 }
Jack Jansenc51395d2001-08-29 15:24:53 +0000208#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000209#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000211#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000212
Miss Islington (bot)b1355352018-11-30 07:32:12 -0800213 pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
214
215 if (callback == NULL) {
216 return PYTHREAD_INVALID_THREAD_ID;
217 }
218
219 callback->func = func;
220 callback->arg = arg;
221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 status = pthread_create(&th,
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000223#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 &attrs,
Jack Jansenc51395d2001-08-29 15:24:53 +0000225#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000227#endif
Miss Islington (bot)b1355352018-11-30 07:32:12 -0800228 pythread_wrapper, callback);
Guido van Rossum80230992001-10-12 21:49:17 +0000229
Fred Drake03459a52001-11-09 16:00:41 +0000230#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 pthread_attr_destroy(&attrs);
Jack Jansenc51395d2001-08-29 15:24:53 +0000232#endif
Miss Islington (bot)b1355352018-11-30 07:32:12 -0800233
234 if (status != 0) {
235 PyMem_RawFree(callback);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200236 return PYTHREAD_INVALID_THREAD_ID;
Miss Islington (bot)b1355352018-11-30 07:32:12 -0800237 }
Martin v. Löwis910ae622003-04-19 07:44:52 +0000238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 pthread_detach(th);
Martin v. Löwis910ae622003-04-19 07:44:52 +0000240
Guido van Rossum3c288632001-10-16 21:13:49 +0000241#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200242 return (unsigned long) th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000243#else
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200244 return (unsigned long) *(unsigned long *) &th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000245#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000246}
247
Trent Mick635f6fb2000-08-23 21:33:05 +0000248/* XXX This implementation is considered (to quote Tim Peters) "inherently
249 hosed" because:
Skip Montanaro6babcc22004-03-03 08:42:23 +0000250 - It does not guarantee the promise that a non-zero integer is returned.
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200251 - The cast to unsigned long is inherently unsafe.
Jesus Cea736e7fc2011-03-14 17:36:54 +0100252 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
Trent Mick635f6fb2000-08-23 21:33:05 +0000253*/
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200254unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000255PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 volatile pthread_t threadid;
258 if (!initialized)
259 PyThread_init_thread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 threadid = pthread_self();
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200261 return (unsigned long) threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000262}
263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000265PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200268 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200270 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000271}
272
Martin v. Löwiscc898662002-03-17 09:53:51 +0000273#ifdef USE_SEMAPHORES
274
275/*
276 * Lock support.
277 */
278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000280PyThread_allocate_lock(void)
281{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 sem_t *lock;
283 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 dprintf(("PyThread_allocate_lock called\n"));
286 if (!initialized)
287 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000288
Victor Stinner80aa5652013-07-07 17:17:59 +0200289 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 if (lock) {
292 status = sem_init(lock,0,1);
293 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200296 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 lock = NULL;
298 }
299 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 dprintf(("PyThread_allocate_lock() -> %p\n", lock));
302 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000303}
304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000306PyThread_free_lock(PyThread_type_lock lock)
307{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 sem_t *thelock = (sem_t *)lock;
309 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000310
Christian Heimes56379c02012-12-02 08:37:00 +0100311 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 if (!thelock)
315 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 status = sem_destroy(thelock);
318 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000319
Victor Stinner80aa5652013-07-07 17:17:59 +0200320 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000321}
322
323/*
324 * As of February 2002, Cygwin thread implementations mistakenly report error
325 * codes in the return value of the sem_ calls (like the pthread_ functions).
326 * Correct implementations return -1 and put the code in errno. This supports
327 * either.
328 */
329static int
330fix_status(int status)
331{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000333}
334
Antoine Pitrou810023d2010-12-15 22:59:16 +0000335PyLockStatus
336PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
337 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000338{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000339 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 sem_t *thelock = (sem_t *)lock;
341 int status, error = 0;
342 struct timespec ts;
Victor Stinner850a18e2017-10-24 16:53:32 -0700343 _PyTime_t deadline = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000344
Christian Heimes56379c02012-12-02 08:37:00 +0100345 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000346 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
347 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000348
Victor Stinner850a18e2017-10-24 16:53:32 -0700349 if (microseconds > PY_TIMEOUT_MAX) {
350 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
351 }
352
353 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700355
356 if (!intr_flag) {
357 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
358 check done above */
359 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
360 deadline = _PyTime_GetMonotonicClock() + timeout;
361 }
362 }
363
364 while (1) {
365 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner850a18e2017-10-24 16:53:32 -0700367 }
368 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700370 }
371 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700373 }
374
Antoine Pitrou810023d2010-12-15 22:59:16 +0000375 /* Retry if interrupted by a signal, unless the caller wants to be
376 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700377 if (intr_flag || status != EINTR) {
378 break;
379 }
380
381 if (microseconds > 0) {
382 /* wait interrupted by a signal (EINTR): recompute the timeout */
383 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
384 if (dt < 0) {
385 status = ETIMEDOUT;
386 break;
387 }
388 else if (dt > 0) {
389 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
390 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
391 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
392 check done above */
393 Py_UNREACHABLE();
394 }
395 /* no need to update microseconds value, the code only care
396 if (microseconds > 0 or (microseconds == 0). */
397 }
398 else {
399 microseconds = 0;
400 }
401 }
402 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000403
Antoine Pitrou810023d2010-12-15 22:59:16 +0000404 /* Don't check the status if we're stopping because of an interrupt. */
405 if (!(intr_flag && status == EINTR)) {
406 if (microseconds > 0) {
407 if (status != ETIMEDOUT)
408 CHECK_STATUS("sem_timedwait");
409 }
410 else if (microseconds == 0) {
411 if (status != EAGAIN)
412 CHECK_STATUS("sem_trywait");
413 }
414 else {
415 CHECK_STATUS("sem_wait");
416 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000418
Antoine Pitrou810023d2010-12-15 22:59:16 +0000419 if (status == 0) {
420 success = PY_LOCK_ACQUIRED;
421 } else if (intr_flag && status == EINTR) {
422 success = PY_LOCK_INTR;
423 } else {
424 success = PY_LOCK_FAILURE;
425 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426
Antoine Pitrou810023d2010-12-15 22:59:16 +0000427 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
428 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000430}
431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000433PyThread_release_lock(PyThread_type_lock lock)
434{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 sem_t *thelock = (sem_t *)lock;
436 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000437
Christian Heimes56379c02012-12-02 08:37:00 +0100438 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000439 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 status = sem_post(thelock);
442 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000443}
444
445#else /* USE_SEMAPHORES */
446
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000447/*
448 * Lock support.
449 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000451PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000452{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 pthread_lock *lock;
454 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 dprintf(("PyThread_allocate_lock called\n"));
457 if (!initialized)
458 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000459
Victor Stinner80aa5652013-07-07 17:17:59 +0200460 lock = (pthread_lock *) PyMem_RawMalloc(sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 if (lock) {
462 memset((void *)lock, '\0', sizeof(pthread_lock));
463 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 status = pthread_mutex_init(&lock->mut,
466 pthread_mutexattr_default);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100467 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 /* Mark the pthread mutex underlying a Python mutex as
469 pure happens-before. We can't simply mark the
470 Python-level mutex as a mutex because it can be
471 acquired and released in different threads, which
472 will cause errors. */
473 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 status = pthread_cond_init(&lock->lock_released,
476 pthread_condattr_default);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100477 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200480 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 lock = 0;
482 }
483 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 dprintf(("PyThread_allocate_lock() -> %p\n", lock));
486 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000487}
488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000490PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 pthread_lock *thelock = (pthread_lock *)lock;
493 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000494
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200495 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000497
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000498 /* some pthread-like implementations tie the mutex to the cond
499 * and must have the cond destroyed first.
500 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100502 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000503
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000504 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100505 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000506
Victor Stinner80aa5652013-07-07 17:17:59 +0200507 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000508}
509
Antoine Pitrou810023d2010-12-15 22:59:16 +0000510PyLockStatus
511PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
512 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000513{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200514 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 pthread_lock *thelock = (pthread_lock *)lock;
516 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000517
Antoine Pitrou810023d2010-12-15 22:59:16 +0000518 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
519 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000520
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200521 if (microseconds == 0) {
522 status = pthread_mutex_trylock( &thelock->mut );
523 if (status != EBUSY)
524 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
525 }
526 else {
527 status = pthread_mutex_lock( &thelock->mut );
528 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
529 }
530 if (status == 0) {
531 if (thelock->locked == 0) {
532 success = PY_LOCK_ACQUIRED;
533 }
534 else if (microseconds != 0) {
535 struct timespec ts;
536 if (microseconds > 0)
537 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
538 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000539
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200540 /* mut must be locked by me -- part of the condition
541 * protocol */
542 while (success == PY_LOCK_FAILURE) {
543 if (microseconds > 0) {
544 status = pthread_cond_timedwait(
545 &thelock->lock_released,
546 &thelock->mut, &ts);
547 if (status == ETIMEDOUT)
548 break;
549 CHECK_STATUS_PTHREAD("pthread_cond_timed_wait");
550 }
551 else {
552 status = pthread_cond_wait(
553 &thelock->lock_released,
554 &thelock->mut);
555 CHECK_STATUS_PTHREAD("pthread_cond_wait");
556 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000557
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200558 if (intr_flag && status == 0 && thelock->locked) {
559 /* We were woken up, but didn't get the lock. We probably received
560 * a signal. Return PY_LOCK_INTR to allow the caller to handle
561 * it and retry. */
562 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000563 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200564 }
565 else if (status == 0 && !thelock->locked) {
566 success = PY_LOCK_ACQUIRED;
567 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000568 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200570 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
571 status = pthread_mutex_unlock( &thelock->mut );
572 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000574
Antoine Pitrou810023d2010-12-15 22:59:16 +0000575 if (error) success = PY_LOCK_FAILURE;
576 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
577 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000579}
580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000582PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000583{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 pthread_lock *thelock = (pthread_lock *)lock;
585 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000586
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200587 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000589
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100591 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 /* wake up someone (anyone, if any) waiting on the lock */
596 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100597 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000598
599 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100600 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000601}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000602
603#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000604
Antoine Pitrou810023d2010-12-15 22:59:16 +0000605int
606PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
607{
608 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
609}
610
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000611/* set the thread stack size.
612 * Return 0 if size is valid, -1 if size is invalid,
613 * -2 if setting stack size is not supported.
614 */
615static int
616_pythread_pthread_set_stacksize(size_t size)
617{
618#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 pthread_attr_t attrs;
620 size_t tss_min;
621 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000622#endif
623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 /* set to default */
625 if (size == 0) {
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600626 PyThreadState_GET()->interp->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 return 0;
628 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000629
630#if defined(THREAD_STACK_SIZE)
631#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000632 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
633 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000634#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000636#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 if (size >= tss_min) {
638 /* validate stack size by setting thread attribute */
639 if (pthread_attr_init(&attrs) == 0) {
640 rc = pthread_attr_setstacksize(&attrs, size);
641 pthread_attr_destroy(&attrs);
642 if (rc == 0) {
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600643 PyThreadState_GET()->interp->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 return 0;
645 }
646 }
647 }
648 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000649#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000650 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000651#endif
652}
653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000655
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000656
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900657/* Thread Local Storage (TLS) API
658
659 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
660*/
661
662/* Issue #25658: On platforms where native TLS key is defined in a way that
663 cannot be safely cast to int, PyThread_create_key returns immediately a
664 failure status and other TLS functions all are no-ops. This indicates
665 clearly that the old API is not supported on platforms where it cannot be
666 used reliably, and that no effort will be made to add such support.
667
668 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
669 removing this API.
670*/
671
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000672int
673PyThread_create_key(void)
674{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900675#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000676 pthread_key_t key;
677 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200678 if (fail)
679 return -1;
680 if (key > INT_MAX) {
681 /* Issue #22206: handle integer overflow */
682 pthread_key_delete(key);
683 errno = ENOMEM;
684 return -1;
685 }
686 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900687#else
688 return -1; /* never return valid key value. */
689#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000690}
691
692void
693PyThread_delete_key(int key)
694{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900695#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000696 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900697#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000698}
699
700void
701PyThread_delete_key_value(int key)
702{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900703#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000704 pthread_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900705#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000706}
707
708int
709PyThread_set_key_value(int key, void *value)
710{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900711#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
712 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000713 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900714#else
715 return -1;
716#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000717}
718
719void *
720PyThread_get_key_value(int key)
721{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900722#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000723 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900724#else
725 return NULL;
726#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000727}
728
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900729
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000730void
731PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900732{
733}
734
735
736/* Thread Specific Storage (TSS) API
737
738 Platform-specific components of TSS API implementation.
739*/
740
741int
742PyThread_tss_create(Py_tss_t *key)
743{
744 assert(key != NULL);
745 /* If the key has been created, function is silently skipped. */
746 if (key->_is_initialized) {
747 return 0;
748 }
749
750 int fail = pthread_key_create(&(key->_key), NULL);
751 if (fail) {
752 return -1;
753 }
754 key->_is_initialized = 1;
755 return 0;
756}
757
758void
759PyThread_tss_delete(Py_tss_t *key)
760{
761 assert(key != NULL);
762 /* If the key has not been created, function is silently skipped. */
763 if (!key->_is_initialized) {
764 return;
765 }
766
767 pthread_key_delete(key->_key);
768 /* pthread has not provided the defined invalid value for the key. */
769 key->_is_initialized = 0;
770}
771
772int
773PyThread_tss_set(Py_tss_t *key, void *value)
774{
775 assert(key != NULL);
776 int fail = pthread_setspecific(key->_key, value);
777 return fail ? -1 : 0;
778}
779
780void *
781PyThread_tss_get(Py_tss_t *key)
782{
783 assert(key != NULL);
784 return pthread_getspecific(key->_key);
785}