blob: 40e2e117a2eb2b77898d4bcaccd14e6fea756f57 [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
Jake Teslerb121f632019-05-22 08:43:17 -070015#if defined(__linux__)
16# include <sys/syscall.h> /* syscall(SYS_gettid) */
17#elif defined(__FreeBSD__)
18# include <pthread_np.h> /* pthread_getthreadid_np() */
David Carlier0b9956e2019-06-03 16:43:33 +010019#elif defined(__OpenBSD__)
20# include <unistd.h> /* getthrid() */
Michael Feltd0eeb932019-06-14 00:34:46 +020021#elif defined(_AIX)
22# include <sys/thread.h> /* thread_self() */
23#elif defined(__NetBSD__)
24# include <lwp.h> /* _lwp_self() */
Jake Teslerb121f632019-05-22 08:43:17 -070025#endif
26
Thomas Wouters0e3f5912006-08-11 14:57:12 +000027/* The POSIX spec requires that use of pthread_attr_setstacksize
28 be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
29#ifdef _POSIX_THREAD_ATTR_STACKSIZE
30#ifndef THREAD_STACK_SIZE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000031#define THREAD_STACK_SIZE 0 /* use default stack size */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000032#endif
Ned Deily9a7c5242011-05-28 00:19:56 -070033
Ned Deily7ca97d52012-03-13 11:18:18 -070034/* The default stack size for new threads on OSX and BSD is small enough that
35 * we'll get hard crashes instead of 'maximum recursion depth exceeded'
36 * exceptions.
37 *
38 * The default stack sizes below are the empirically determined minimal stack
39 * sizes where a simple recursive function doesn't cause a hard crash.
40 */
41#if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
42#undef THREAD_STACK_SIZE
Ronald Oussoren1a057ba2019-08-01 07:43:07 +020043/* Note: This matches the value of -Wl,-stack_size in configure.ac */
44#define THREAD_STACK_SIZE 0x1000000
Ned Deily7ca97d52012-03-13 11:18:18 -070045#endif
46#if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
Ned Deily9a7c5242011-05-28 00:19:56 -070047#undef THREAD_STACK_SIZE
48#define THREAD_STACK_SIZE 0x400000
49#endif
Michael Felt9670ce72019-08-03 08:12:26 +020050#if defined(_AIX) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
51#undef THREAD_STACK_SIZE
52#define THREAD_STACK_SIZE 0x200000
53#endif
xdegaye00ada2c2019-12-08 08:40:14 +010054/* bpo-38852: test_threading.test_recursion_limit() checks that 1000 recursive
55 Python calls (default recursion limit) doesn't crash, but raise a regular
56 RecursionError exception. In debug mode, Python function calls allocates
57 more memory on the stack, so use a stack of 8 MiB. */
58#if defined(__ANDROID__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
59# ifdef Py_DEBUG
60# undef THREAD_STACK_SIZE
61# define THREAD_STACK_SIZE 0x800000
62# endif
63#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064/* for safety, ensure a viable minimum stacksize */
Victor Stinner8c663fd2017-11-08 14:44:44 -080065#define THREAD_STACK_MIN 0x8000 /* 32 KiB */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
67#ifdef THREAD_STACK_SIZE
68#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
69#endif
70#endif
71
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000072/* The POSIX spec says that implementations supporting the sem_*
73 family of functions must indicate this by defining
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 _POSIX_SEMAPHORES. */
Martin v. Löwiscc898662002-03-17 09:53:51 +000075#ifdef _POSIX_SEMAPHORES
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000076/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
Martin v. Löwis8b8fb3d2005-03-28 12:34:20 +000077 we need to add 0 to make it work there as well. */
78#if (_POSIX_SEMAPHORES+0) == -1
Anthony Baxter19b23692005-03-16 04:15:07 +000079#define HAVE_BROKEN_POSIX_SEMAPHORES
80#else
Martin v. Löwiscc898662002-03-17 09:53:51 +000081#include <semaphore.h>
82#include <errno.h>
83#endif
Anthony Baxter19b23692005-03-16 04:15:07 +000084#endif
Guido van Rossum66020991996-06-11 18:32:18 +000085
Guido van Rossumd6353e21997-05-13 17:51:13 +000086
Martin v. Löwiscc898662002-03-17 09:53:51 +000087/* Whether or not to use semaphores directly rather than emulating them with
88 * mutexes and condition variables:
89 */
Antoine Pitrou19f8edc2010-10-10 08:37:22 +000090#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
91 defined(HAVE_SEM_TIMEDWAIT))
Martin v. Löwiscc898662002-03-17 09:53:51 +000092# define USE_SEMAPHORES
93#else
94# undef USE_SEMAPHORES
95#endif
96
97
Guido van Rossum80230992001-10-12 21:49:17 +000098/* On platforms that don't use standard POSIX threads pthread_sigmask()
99 * isn't present. DEC threads uses sigprocmask() instead as do most
100 * other UNIX International compliant systems that don't have the full
101 * pthread implementation.
102 */
Jason Tishlerfac083d2003-07-22 15:20:49 +0000103#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Guido van Rossum80230992001-10-12 21:49:17 +0000104# define SET_THREAD_SIGMASK pthread_sigmask
105#else
106# define SET_THREAD_SIGMASK sigprocmask
107#endif
108
109
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000110#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
111do { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112 struct timeval tv; \
Benjamin Petersonf1c19032019-09-10 11:37:59 +0100113 gettimeofday(&tv, NULL); \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114 tv.tv_usec += microseconds % 1000000; \
115 tv.tv_sec += microseconds / 1000000; \
116 tv.tv_sec += tv.tv_usec / 1000000; \
117 tv.tv_usec %= 1000000; \
118 ts.tv_sec = tv.tv_sec; \
119 ts.tv_nsec = tv.tv_usec * 1000; \
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000120} while(0)
121
122
Inada Naoki001fee12019-02-20 10:00:09 +0900123/*
124 * pthread_cond support
125 */
126
127#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
128// monotonic is supported statically. It doesn't mean it works on runtime.
129#define CONDATTR_MONOTONIC
130#endif
131
132// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
133static pthread_condattr_t *condattr_monotonic = NULL;
134
135static void
136init_condattr()
137{
138#ifdef CONDATTR_MONOTONIC
139 static pthread_condattr_t ca;
140 pthread_condattr_init(&ca);
141 if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) {
142 condattr_monotonic = &ca; // Use monotonic clock
143 }
144#endif
145}
146
147int
148_PyThread_cond_init(PyCOND_T *cond)
149{
150 return pthread_cond_init(cond, condattr_monotonic);
151}
152
153void
154_PyThread_cond_after(long long us, struct timespec *abs)
155{
156#ifdef CONDATTR_MONOTONIC
157 if (condattr_monotonic) {
158 clock_gettime(CLOCK_MONOTONIC, abs);
159 abs->tv_sec += us / 1000000;
160 abs->tv_nsec += (us % 1000000) * 1000;
161 abs->tv_sec += abs->tv_nsec / 1000000000;
162 abs->tv_nsec %= 1000000000;
163 return;
164 }
165#endif
166
167 struct timespec ts;
168 MICROSECONDS_TO_TIMESPEC(us, ts);
169 *abs = ts;
170}
171
172
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000173/* A pthread mutex isn't sufficient to model the Python lock type
174 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
175 * following are undefined:
176 * -> a thread tries to lock a mutex it already has locked
177 * -> a thread tries to unlock a mutex locked by a different thread
178 * pthread mutexes are designed for serializing threads over short pieces
179 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000180 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000181 *
182 * The pthread_lock struct implements a Python lock as a "locked?" bit
183 * and a <condition, mutex> pair. In general, if the bit can be acquired
184 * instantly, it is, else the pair is used to block the thread until the
185 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000186 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000187
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000188typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 char locked; /* 0=unlocked, 1=locked */
190 /* a <cond, mutex> pair to handle an acquire of a locked lock */
191 pthread_cond_t lock_released;
192 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000193} pthread_lock;
194
Guido van Rossum9e46e561998-10-07 16:39:47 +0000195#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100196#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
197 "%s: %s\n", name, strerror(status)); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000198
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000199/*
200 * Initialization.
201 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000202static void
203PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000204{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000205#if defined(_AIX) && defined(__GNUC__)
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200206 extern void pthread_init(void);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 pthread_init();
Guido van Rossumd21744a1998-09-10 03:04:40 +0000208#endif
Inada Naoki001fee12019-02-20 10:00:09 +0900209 init_condattr();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000210}
211
212/*
213 * Thread support.
214 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000215
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530216/* bpo-33015: pythread_callback struct and pythread_wrapper() cast
217 "void func(void *)" to "void* func(void *)": always return NULL.
218
219 PyThread_start_new_thread() uses "void func(void *)" type, whereas
220 pthread_create() requires a void* return value. */
221typedef struct {
222 void (*func) (void *);
223 void *arg;
224} pythread_callback;
225
226static void *
227pythread_wrapper(void *arg)
228{
229 /* copy func and func_arg and free the temporary structure */
230 pythread_callback *callback = arg;
231 void (*func)(void *) = callback->func;
232 void *func_arg = callback->arg;
233 PyMem_RawFree(arg);
234
235 func(func_arg);
236 return NULL;
237}
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000238
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200239unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000240PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 pthread_t th;
243 int status;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000244#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 pthread_attr_t attrs;
Jack Jansenc51395d2001-08-29 15:24:53 +0000246#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000247#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 size_t tss;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000249#endif
250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 dprintf(("PyThread_start_new_thread called\n"));
252 if (!initialized)
253 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000254
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000255#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 if (pthread_attr_init(&attrs) != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200257 return PYTHREAD_INVALID_THREAD_ID;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000258#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000259#if defined(THREAD_STACK_SIZE)
Victor Stinner50b48572018-11-01 01:51:40 +0100260 PyThreadState *tstate = _PyThreadState_GET();
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600261 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
262 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 if (tss != 0) {
264 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
265 pthread_attr_destroy(&attrs);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200266 return PYTHREAD_INVALID_THREAD_ID;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 }
268 }
Jack Jansenc51395d2001-08-29 15:24:53 +0000269#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000270#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000272#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000273
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530274 pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
275
276 if (callback == NULL) {
277 return PYTHREAD_INVALID_THREAD_ID;
278 }
279
280 callback->func = func;
281 callback->arg = arg;
282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 status = pthread_create(&th,
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000284#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 &attrs,
Jack Jansenc51395d2001-08-29 15:24:53 +0000286#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000288#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530289 pythread_wrapper, callback);
Guido van Rossum80230992001-10-12 21:49:17 +0000290
Fred Drake03459a52001-11-09 16:00:41 +0000291#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 pthread_attr_destroy(&attrs);
Jack Jansenc51395d2001-08-29 15:24:53 +0000293#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530294
295 if (status != 0) {
296 PyMem_RawFree(callback);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200297 return PYTHREAD_INVALID_THREAD_ID;
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530298 }
Martin v. Löwis910ae622003-04-19 07:44:52 +0000299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 pthread_detach(th);
Martin v. Löwis910ae622003-04-19 07:44:52 +0000301
Guido van Rossum3c288632001-10-16 21:13:49 +0000302#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200303 return (unsigned long) th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000304#else
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200305 return (unsigned long) *(unsigned long *) &th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000306#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000307}
308
Trent Mick635f6fb2000-08-23 21:33:05 +0000309/* XXX This implementation is considered (to quote Tim Peters) "inherently
310 hosed" because:
Skip Montanaro6babcc22004-03-03 08:42:23 +0000311 - It does not guarantee the promise that a non-zero integer is returned.
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200312 - The cast to unsigned long is inherently unsafe.
Jesus Cea736e7fc2011-03-14 17:36:54 +0100313 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
Trent Mick635f6fb2000-08-23 21:33:05 +0000314*/
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200315unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000316PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000317{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 volatile pthread_t threadid;
319 if (!initialized)
320 PyThread_init_thread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321 threadid = pthread_self();
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200322 return (unsigned long) threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000323}
324
Jake Teslerb121f632019-05-22 08:43:17 -0700325#ifdef PY_HAVE_THREAD_NATIVE_ID
326unsigned long
327PyThread_get_thread_native_id(void)
328{
329 if (!initialized)
330 PyThread_init_thread();
331#ifdef __APPLE__
332 uint64_t native_id;
333 (void) pthread_threadid_np(NULL, &native_id);
334#elif defined(__linux__)
335 pid_t native_id;
336 native_id = syscall(SYS_gettid);
337#elif defined(__FreeBSD__)
338 int native_id;
339 native_id = pthread_getthreadid_np();
David Carlier0b9956e2019-06-03 16:43:33 +0100340#elif defined(__OpenBSD__)
341 pid_t native_id;
342 native_id = getthrid();
Michael Feltd0eeb932019-06-14 00:34:46 +0200343#elif defined(_AIX)
344 tid_t native_id;
345 native_id = thread_self();
David Carlier52870222019-06-12 15:37:56 +0000346#elif defined(__NetBSD__)
347 lwpid_t native_id;
348 native_id = _lwp_self();
Jake Teslerb121f632019-05-22 08:43:17 -0700349#endif
350 return (unsigned long) native_id;
351}
352#endif
353
Victor Stinnerc664b342019-05-04 11:48:05 -0400354void _Py_NO_RETURN
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000355PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000356{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200358 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200360 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000361}
362
Martin v. Löwiscc898662002-03-17 09:53:51 +0000363#ifdef USE_SEMAPHORES
364
365/*
366 * Lock support.
367 */
368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000370PyThread_allocate_lock(void)
371{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 sem_t *lock;
373 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 dprintf(("PyThread_allocate_lock called\n"));
376 if (!initialized)
377 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000378
Victor Stinner80aa5652013-07-07 17:17:59 +0200379 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 if (lock) {
382 status = sem_init(lock,0,1);
383 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200386 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000387 lock = NULL;
388 }
389 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000390
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600391 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000393}
394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000396PyThread_free_lock(PyThread_type_lock lock)
397{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 sem_t *thelock = (sem_t *)lock;
399 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000400
Christian Heimes56379c02012-12-02 08:37:00 +0100401 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 if (!thelock)
405 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 status = sem_destroy(thelock);
408 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000409
Victor Stinner80aa5652013-07-07 17:17:59 +0200410 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000411}
412
413/*
414 * As of February 2002, Cygwin thread implementations mistakenly report error
415 * codes in the return value of the sem_ calls (like the pthread_ functions).
416 * Correct implementations return -1 and put the code in errno. This supports
417 * either.
418 */
419static int
420fix_status(int status)
421{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000423}
424
Antoine Pitrou810023d2010-12-15 22:59:16 +0000425PyLockStatus
426PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
427 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000428{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000429 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000430 sem_t *thelock = (sem_t *)lock;
431 int status, error = 0;
432 struct timespec ts;
Victor Stinner850a18e2017-10-24 16:53:32 -0700433 _PyTime_t deadline = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000434
Christian Heimes56379c02012-12-02 08:37:00 +0100435 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000436 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
437 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000438
Victor Stinner850a18e2017-10-24 16:53:32 -0700439 if (microseconds > PY_TIMEOUT_MAX) {
440 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
441 }
442
443 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700445
446 if (!intr_flag) {
447 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
448 check done above */
449 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
450 deadline = _PyTime_GetMonotonicClock() + timeout;
451 }
452 }
453
454 while (1) {
455 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner850a18e2017-10-24 16:53:32 -0700457 }
458 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700460 }
461 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700463 }
464
Antoine Pitrou810023d2010-12-15 22:59:16 +0000465 /* Retry if interrupted by a signal, unless the caller wants to be
466 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700467 if (intr_flag || status != EINTR) {
468 break;
469 }
470
471 if (microseconds > 0) {
472 /* wait interrupted by a signal (EINTR): recompute the timeout */
473 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
474 if (dt < 0) {
475 status = ETIMEDOUT;
476 break;
477 }
478 else if (dt > 0) {
479 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
480 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
481 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
482 check done above */
483 Py_UNREACHABLE();
484 }
485 /* no need to update microseconds value, the code only care
486 if (microseconds > 0 or (microseconds == 0). */
487 }
488 else {
489 microseconds = 0;
490 }
491 }
492 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000493
Antoine Pitrou810023d2010-12-15 22:59:16 +0000494 /* Don't check the status if we're stopping because of an interrupt. */
495 if (!(intr_flag && status == EINTR)) {
496 if (microseconds > 0) {
497 if (status != ETIMEDOUT)
498 CHECK_STATUS("sem_timedwait");
499 }
500 else if (microseconds == 0) {
501 if (status != EAGAIN)
502 CHECK_STATUS("sem_trywait");
503 }
504 else {
505 CHECK_STATUS("sem_wait");
506 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000508
Antoine Pitrou810023d2010-12-15 22:59:16 +0000509 if (status == 0) {
510 success = PY_LOCK_ACQUIRED;
511 } else if (intr_flag && status == EINTR) {
512 success = PY_LOCK_INTR;
513 } else {
514 success = PY_LOCK_FAILURE;
515 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000516
Antoine Pitrou810023d2010-12-15 22:59:16 +0000517 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
518 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000520}
521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000523PyThread_release_lock(PyThread_type_lock lock)
524{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000525 sem_t *thelock = (sem_t *)lock;
526 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000527
Christian Heimes56379c02012-12-02 08:37:00 +0100528 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 status = sem_post(thelock);
532 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000533}
534
535#else /* USE_SEMAPHORES */
536
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000537/*
538 * Lock support.
539 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000541PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000542{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 pthread_lock *lock;
544 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 dprintf(("PyThread_allocate_lock called\n"));
547 if (!initialized)
548 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000549
Andy Lester7668a8b2020-03-24 23:26:44 -0500550 lock = (pthread_lock *) PyMem_RawCalloc(1, sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 if (lock) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000553
Inada Naoki001fee12019-02-20 10:00:09 +0900554 status = pthread_mutex_init(&lock->mut, NULL);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100555 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 /* Mark the pthread mutex underlying a Python mutex as
557 pure happens-before. We can't simply mark the
558 Python-level mutex as a mutex because it can be
559 acquired and released in different threads, which
560 will cause errors. */
561 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000562
Inada Naoki001fee12019-02-20 10:00:09 +0900563 status = _PyThread_cond_init(&lock->lock_released);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100564 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200567 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000568 lock = 0;
569 }
570 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000571
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600572 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000574}
575
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000576void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000577PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000578{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 pthread_lock *thelock = (pthread_lock *)lock;
580 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000581
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200582 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000584
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000585 /* some pthread-like implementations tie the mutex to the cond
586 * and must have the cond destroyed first.
587 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100589 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000590
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000591 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100592 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000593
Victor Stinner80aa5652013-07-07 17:17:59 +0200594 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000595}
596
Antoine Pitrou810023d2010-12-15 22:59:16 +0000597PyLockStatus
598PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
599 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000600{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200601 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 pthread_lock *thelock = (pthread_lock *)lock;
603 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000604
Antoine Pitrou810023d2010-12-15 22:59:16 +0000605 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
606 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000607
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200608 if (microseconds == 0) {
609 status = pthread_mutex_trylock( &thelock->mut );
610 if (status != EBUSY)
611 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
612 }
613 else {
614 status = pthread_mutex_lock( &thelock->mut );
615 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
616 }
617 if (status == 0) {
618 if (thelock->locked == 0) {
619 success = PY_LOCK_ACQUIRED;
620 }
621 else if (microseconds != 0) {
Inada Naoki001fee12019-02-20 10:00:09 +0900622 struct timespec abs;
623 if (microseconds > 0) {
624 _PyThread_cond_after(microseconds, &abs);
625 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200626 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000627
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200628 /* mut must be locked by me -- part of the condition
629 * protocol */
630 while (success == PY_LOCK_FAILURE) {
631 if (microseconds > 0) {
632 status = pthread_cond_timedwait(
633 &thelock->lock_released,
Inada Naoki001fee12019-02-20 10:00:09 +0900634 &thelock->mut, &abs);
635 if (status == 1) {
636 break;
637 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200638 if (status == ETIMEDOUT)
639 break;
Inada Naoki001fee12019-02-20 10:00:09 +0900640 CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200641 }
642 else {
643 status = pthread_cond_wait(
644 &thelock->lock_released,
645 &thelock->mut);
646 CHECK_STATUS_PTHREAD("pthread_cond_wait");
647 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000648
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200649 if (intr_flag && status == 0 && thelock->locked) {
650 /* We were woken up, but didn't get the lock. We probably received
651 * a signal. Return PY_LOCK_INTR to allow the caller to handle
652 * it and retry. */
653 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200655 }
656 else if (status == 0 && !thelock->locked) {
657 success = PY_LOCK_ACQUIRED;
658 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000659 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200661 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
662 status = pthread_mutex_unlock( &thelock->mut );
663 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000665
Antoine Pitrou810023d2010-12-15 22:59:16 +0000666 if (error) success = PY_LOCK_FAILURE;
667 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
668 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000670}
671
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000673PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000674{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 pthread_lock *thelock = (pthread_lock *)lock;
676 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000677
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200678 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100682 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000683
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000684 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000685
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000686 /* wake up someone (anyone, if any) waiting on the lock */
687 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100688 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000689
690 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100691 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000692}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000693
694#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000695
Antoine Pitrou810023d2010-12-15 22:59:16 +0000696int
697PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
698{
699 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
700}
701
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000702/* set the thread stack size.
703 * Return 0 if size is valid, -1 if size is invalid,
704 * -2 if setting stack size is not supported.
705 */
706static int
707_pythread_pthread_set_stacksize(size_t size)
708{
709#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000710 pthread_attr_t attrs;
711 size_t tss_min;
712 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000713#endif
714
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 /* set to default */
716 if (size == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100717 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 return 0;
719 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000720
721#if defined(THREAD_STACK_SIZE)
722#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
724 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000725#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000727#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 if (size >= tss_min) {
729 /* validate stack size by setting thread attribute */
730 if (pthread_attr_init(&attrs) == 0) {
731 rc = pthread_attr_setstacksize(&attrs, size);
732 pthread_attr_destroy(&attrs);
733 if (rc == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100734 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 return 0;
736 }
737 }
738 }
739 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000740#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000742#endif
743}
744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000746
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000747
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900748/* Thread Local Storage (TLS) API
749
750 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
751*/
752
753/* Issue #25658: On platforms where native TLS key is defined in a way that
754 cannot be safely cast to int, PyThread_create_key returns immediately a
755 failure status and other TLS functions all are no-ops. This indicates
756 clearly that the old API is not supported on platforms where it cannot be
757 used reliably, and that no effort will be made to add such support.
758
759 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
760 removing this API.
761*/
762
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000763int
764PyThread_create_key(void)
765{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900766#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000767 pthread_key_t key;
768 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200769 if (fail)
770 return -1;
771 if (key > INT_MAX) {
772 /* Issue #22206: handle integer overflow */
773 pthread_key_delete(key);
774 errno = ENOMEM;
775 return -1;
776 }
777 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900778#else
779 return -1; /* never return valid key value. */
780#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000781}
782
783void
784PyThread_delete_key(int key)
785{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900786#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000787 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900788#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000789}
790
791void
792PyThread_delete_key_value(int key)
793{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900794#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000795 pthread_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900796#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000797}
798
799int
800PyThread_set_key_value(int key, void *value)
801{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900802#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
803 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000804 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900805#else
806 return -1;
807#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000808}
809
810void *
811PyThread_get_key_value(int key)
812{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900813#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000814 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900815#else
816 return NULL;
817#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000818}
819
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900820
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000821void
822PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900823{
824}
825
826
827/* Thread Specific Storage (TSS) API
828
829 Platform-specific components of TSS API implementation.
830*/
831
832int
833PyThread_tss_create(Py_tss_t *key)
834{
835 assert(key != NULL);
836 /* If the key has been created, function is silently skipped. */
837 if (key->_is_initialized) {
838 return 0;
839 }
840
841 int fail = pthread_key_create(&(key->_key), NULL);
842 if (fail) {
843 return -1;
844 }
845 key->_is_initialized = 1;
846 return 0;
847}
848
849void
850PyThread_tss_delete(Py_tss_t *key)
851{
852 assert(key != NULL);
853 /* If the key has not been created, function is silently skipped. */
854 if (!key->_is_initialized) {
855 return;
856 }
857
858 pthread_key_delete(key->_key);
859 /* pthread has not provided the defined invalid value for the key. */
860 key->_is_initialized = 0;
861}
862
863int
864PyThread_tss_set(Py_tss_t *key, void *value)
865{
866 assert(key != NULL);
867 int fail = pthread_setspecific(key->_key, value);
868 return fail ? -1 : 0;
869}
870
871void *
872PyThread_tss_get(Py_tss_t *key)
873{
874 assert(key != NULL);
875 return pthread_getspecific(key->_key);
876}