blob: a36d16c19eade5e07d2678077bfdb914905e0809 [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
43#define THREAD_STACK_SIZE 0x500000
44#endif
45#if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
Ned Deily9a7c5242011-05-28 00:19:56 -070046#undef THREAD_STACK_SIZE
47#define THREAD_STACK_SIZE 0x400000
48#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000049/* for safety, ensure a viable minimum stacksize */
Victor Stinner8c663fd2017-11-08 14:44:44 -080050#define THREAD_STACK_MIN 0x8000 /* 32 KiB */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000051#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
52#ifdef THREAD_STACK_SIZE
53#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
54#endif
55#endif
56
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000057/* The POSIX spec says that implementations supporting the sem_*
58 family of functions must indicate this by defining
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000059 _POSIX_SEMAPHORES. */
Martin v. Löwiscc898662002-03-17 09:53:51 +000060#ifdef _POSIX_SEMAPHORES
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000061/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
Martin v. Löwis8b8fb3d2005-03-28 12:34:20 +000062 we need to add 0 to make it work there as well. */
63#if (_POSIX_SEMAPHORES+0) == -1
Anthony Baxter19b23692005-03-16 04:15:07 +000064#define HAVE_BROKEN_POSIX_SEMAPHORES
65#else
Martin v. Löwiscc898662002-03-17 09:53:51 +000066#include <semaphore.h>
67#include <errno.h>
68#endif
Anthony Baxter19b23692005-03-16 04:15:07 +000069#endif
Guido van Rossum66020991996-06-11 18:32:18 +000070
Guido van Rossumd6353e21997-05-13 17:51:13 +000071
Martin v. Löwiscc898662002-03-17 09:53:51 +000072/* Whether or not to use semaphores directly rather than emulating them with
73 * mutexes and condition variables:
74 */
Antoine Pitrou19f8edc2010-10-10 08:37:22 +000075#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
76 defined(HAVE_SEM_TIMEDWAIT))
Martin v. Löwiscc898662002-03-17 09:53:51 +000077# define USE_SEMAPHORES
78#else
79# undef USE_SEMAPHORES
80#endif
81
82
Guido van Rossum80230992001-10-12 21:49:17 +000083/* On platforms that don't use standard POSIX threads pthread_sigmask()
84 * isn't present. DEC threads uses sigprocmask() instead as do most
85 * other UNIX International compliant systems that don't have the full
86 * pthread implementation.
87 */
Jason Tishlerfac083d2003-07-22 15:20:49 +000088#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Guido van Rossum80230992001-10-12 21:49:17 +000089# define SET_THREAD_SIGMASK pthread_sigmask
90#else
91# define SET_THREAD_SIGMASK sigprocmask
92#endif
93
94
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000095/* We assume all modern POSIX systems have gettimeofday() */
96#ifdef GETTIMEOFDAY_NO_TZ
97#define GETTIMEOFDAY(ptv) gettimeofday(ptv)
98#else
99#define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL)
100#endif
101
102#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
103do { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 struct timeval tv; \
105 GETTIMEOFDAY(&tv); \
106 tv.tv_usec += microseconds % 1000000; \
107 tv.tv_sec += microseconds / 1000000; \
108 tv.tv_sec += tv.tv_usec / 1000000; \
109 tv.tv_usec %= 1000000; \
110 ts.tv_sec = tv.tv_sec; \
111 ts.tv_nsec = tv.tv_usec * 1000; \
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000112} while(0)
113
114
Inada Naoki001fee12019-02-20 10:00:09 +0900115/*
116 * pthread_cond support
117 */
118
119#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
120// monotonic is supported statically. It doesn't mean it works on runtime.
121#define CONDATTR_MONOTONIC
122#endif
123
124// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
125static pthread_condattr_t *condattr_monotonic = NULL;
126
127static void
128init_condattr()
129{
130#ifdef CONDATTR_MONOTONIC
131 static pthread_condattr_t ca;
132 pthread_condattr_init(&ca);
133 if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) {
134 condattr_monotonic = &ca; // Use monotonic clock
135 }
136#endif
137}
138
139int
140_PyThread_cond_init(PyCOND_T *cond)
141{
142 return pthread_cond_init(cond, condattr_monotonic);
143}
144
145void
146_PyThread_cond_after(long long us, struct timespec *abs)
147{
148#ifdef CONDATTR_MONOTONIC
149 if (condattr_monotonic) {
150 clock_gettime(CLOCK_MONOTONIC, abs);
151 abs->tv_sec += us / 1000000;
152 abs->tv_nsec += (us % 1000000) * 1000;
153 abs->tv_sec += abs->tv_nsec / 1000000000;
154 abs->tv_nsec %= 1000000000;
155 return;
156 }
157#endif
158
159 struct timespec ts;
160 MICROSECONDS_TO_TIMESPEC(us, ts);
161 *abs = ts;
162}
163
164
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000165/* A pthread mutex isn't sufficient to model the Python lock type
166 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
167 * following are undefined:
168 * -> a thread tries to lock a mutex it already has locked
169 * -> a thread tries to unlock a mutex locked by a different thread
170 * pthread mutexes are designed for serializing threads over short pieces
171 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000172 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000173 *
174 * The pthread_lock struct implements a Python lock as a "locked?" bit
175 * and a <condition, mutex> pair. In general, if the bit can be acquired
176 * instantly, it is, else the pair is used to block the thread until the
177 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000178 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000179
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000180typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000181 char locked; /* 0=unlocked, 1=locked */
182 /* a <cond, mutex> pair to handle an acquire of a locked lock */
183 pthread_cond_t lock_released;
184 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000185} pthread_lock;
186
Guido van Rossum9e46e561998-10-07 16:39:47 +0000187#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100188#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
189 "%s: %s\n", name, strerror(status)); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000190
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000191/*
192 * Initialization.
193 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000194static void
195PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000196{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000197#if defined(_AIX) && defined(__GNUC__)
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200198 extern void pthread_init(void);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 pthread_init();
Guido van Rossumd21744a1998-09-10 03:04:40 +0000200#endif
Inada Naoki001fee12019-02-20 10:00:09 +0900201 init_condattr();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000202}
203
204/*
205 * Thread support.
206 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000207
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530208/* bpo-33015: pythread_callback struct and pythread_wrapper() cast
209 "void func(void *)" to "void* func(void *)": always return NULL.
210
211 PyThread_start_new_thread() uses "void func(void *)" type, whereas
212 pthread_create() requires a void* return value. */
213typedef struct {
214 void (*func) (void *);
215 void *arg;
216} pythread_callback;
217
218static void *
219pythread_wrapper(void *arg)
220{
221 /* copy func and func_arg and free the temporary structure */
222 pythread_callback *callback = arg;
223 void (*func)(void *) = callback->func;
224 void *func_arg = callback->arg;
225 PyMem_RawFree(arg);
226
227 func(func_arg);
228 return NULL;
229}
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000230
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200231unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000232PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000233{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 pthread_t th;
235 int status;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000236#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 pthread_attr_t attrs;
Jack Jansenc51395d2001-08-29 15:24:53 +0000238#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000239#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000240 size_t tss;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000241#endif
242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000243 dprintf(("PyThread_start_new_thread called\n"));
244 if (!initialized)
245 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000246
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000247#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 if (pthread_attr_init(&attrs) != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200249 return PYTHREAD_INVALID_THREAD_ID;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000250#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000251#if defined(THREAD_STACK_SIZE)
Victor Stinner50b48572018-11-01 01:51:40 +0100252 PyThreadState *tstate = _PyThreadState_GET();
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600253 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
254 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255 if (tss != 0) {
256 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
257 pthread_attr_destroy(&attrs);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200258 return PYTHREAD_INVALID_THREAD_ID;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 }
260 }
Jack Jansenc51395d2001-08-29 15:24:53 +0000261#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000262#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000264#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000265
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530266 pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
267
268 if (callback == NULL) {
269 return PYTHREAD_INVALID_THREAD_ID;
270 }
271
272 callback->func = func;
273 callback->arg = arg;
274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 status = pthread_create(&th,
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000276#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 &attrs,
Jack Jansenc51395d2001-08-29 15:24:53 +0000278#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000280#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530281 pythread_wrapper, callback);
Guido van Rossum80230992001-10-12 21:49:17 +0000282
Fred Drake03459a52001-11-09 16:00:41 +0000283#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 pthread_attr_destroy(&attrs);
Jack Jansenc51395d2001-08-29 15:24:53 +0000285#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530286
287 if (status != 0) {
288 PyMem_RawFree(callback);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200289 return PYTHREAD_INVALID_THREAD_ID;
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530290 }
Martin v. Löwis910ae622003-04-19 07:44:52 +0000291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 pthread_detach(th);
Martin v. Löwis910ae622003-04-19 07:44:52 +0000293
Guido van Rossum3c288632001-10-16 21:13:49 +0000294#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200295 return (unsigned long) th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000296#else
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200297 return (unsigned long) *(unsigned long *) &th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000298#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000299}
300
Trent Mick635f6fb2000-08-23 21:33:05 +0000301/* XXX This implementation is considered (to quote Tim Peters) "inherently
302 hosed" because:
Skip Montanaro6babcc22004-03-03 08:42:23 +0000303 - It does not guarantee the promise that a non-zero integer is returned.
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200304 - The cast to unsigned long is inherently unsafe.
Jesus Cea736e7fc2011-03-14 17:36:54 +0100305 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
Trent Mick635f6fb2000-08-23 21:33:05 +0000306*/
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200307unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000308PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000309{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 volatile pthread_t threadid;
311 if (!initialized)
312 PyThread_init_thread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 threadid = pthread_self();
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200314 return (unsigned long) threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000315}
316
Jake Teslerb121f632019-05-22 08:43:17 -0700317#ifdef PY_HAVE_THREAD_NATIVE_ID
318unsigned long
319PyThread_get_thread_native_id(void)
320{
321 if (!initialized)
322 PyThread_init_thread();
323#ifdef __APPLE__
324 uint64_t native_id;
325 (void) pthread_threadid_np(NULL, &native_id);
326#elif defined(__linux__)
327 pid_t native_id;
328 native_id = syscall(SYS_gettid);
329#elif defined(__FreeBSD__)
330 int native_id;
331 native_id = pthread_getthreadid_np();
David Carlier0b9956e2019-06-03 16:43:33 +0100332#elif defined(__OpenBSD__)
333 pid_t native_id;
334 native_id = getthrid();
Michael Feltd0eeb932019-06-14 00:34:46 +0200335#elif defined(_AIX)
336 tid_t native_id;
337 native_id = thread_self();
David Carlier52870222019-06-12 15:37:56 +0000338#elif defined(__NetBSD__)
339 lwpid_t native_id;
340 native_id = _lwp_self();
Jake Teslerb121f632019-05-22 08:43:17 -0700341#endif
342 return (unsigned long) native_id;
343}
344#endif
345
Victor Stinnerc664b342019-05-04 11:48:05 -0400346void _Py_NO_RETURN
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000347PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000348{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200350 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200352 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000353}
354
Martin v. Löwiscc898662002-03-17 09:53:51 +0000355#ifdef USE_SEMAPHORES
356
357/*
358 * Lock support.
359 */
360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000362PyThread_allocate_lock(void)
363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 sem_t *lock;
365 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 dprintf(("PyThread_allocate_lock called\n"));
368 if (!initialized)
369 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000370
Victor Stinner80aa5652013-07-07 17:17:59 +0200371 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 if (lock) {
374 status = sem_init(lock,0,1);
375 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200378 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 lock = NULL;
380 }
381 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000382
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600383 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000385}
386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000387void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000388PyThread_free_lock(PyThread_type_lock lock)
389{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390 sem_t *thelock = (sem_t *)lock;
391 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000392
Christian Heimes56379c02012-12-02 08:37:00 +0100393 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 if (!thelock)
397 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 status = sem_destroy(thelock);
400 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000401
Victor Stinner80aa5652013-07-07 17:17:59 +0200402 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000403}
404
405/*
406 * As of February 2002, Cygwin thread implementations mistakenly report error
407 * codes in the return value of the sem_ calls (like the pthread_ functions).
408 * Correct implementations return -1 and put the code in errno. This supports
409 * either.
410 */
411static int
412fix_status(int status)
413{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000415}
416
Antoine Pitrou810023d2010-12-15 22:59:16 +0000417PyLockStatus
418PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
419 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000420{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000421 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 sem_t *thelock = (sem_t *)lock;
423 int status, error = 0;
424 struct timespec ts;
Victor Stinner850a18e2017-10-24 16:53:32 -0700425 _PyTime_t deadline = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000426
Christian Heimes56379c02012-12-02 08:37:00 +0100427 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000428 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
429 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000430
Victor Stinner850a18e2017-10-24 16:53:32 -0700431 if (microseconds > PY_TIMEOUT_MAX) {
432 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
433 }
434
435 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700437
438 if (!intr_flag) {
439 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
440 check done above */
441 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
442 deadline = _PyTime_GetMonotonicClock() + timeout;
443 }
444 }
445
446 while (1) {
447 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner850a18e2017-10-24 16:53:32 -0700449 }
450 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700452 }
453 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700455 }
456
Antoine Pitrou810023d2010-12-15 22:59:16 +0000457 /* Retry if interrupted by a signal, unless the caller wants to be
458 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700459 if (intr_flag || status != EINTR) {
460 break;
461 }
462
463 if (microseconds > 0) {
464 /* wait interrupted by a signal (EINTR): recompute the timeout */
465 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
466 if (dt < 0) {
467 status = ETIMEDOUT;
468 break;
469 }
470 else if (dt > 0) {
471 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
472 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
473 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
474 check done above */
475 Py_UNREACHABLE();
476 }
477 /* no need to update microseconds value, the code only care
478 if (microseconds > 0 or (microseconds == 0). */
479 }
480 else {
481 microseconds = 0;
482 }
483 }
484 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000485
Antoine Pitrou810023d2010-12-15 22:59:16 +0000486 /* Don't check the status if we're stopping because of an interrupt. */
487 if (!(intr_flag && status == EINTR)) {
488 if (microseconds > 0) {
489 if (status != ETIMEDOUT)
490 CHECK_STATUS("sem_timedwait");
491 }
492 else if (microseconds == 0) {
493 if (status != EAGAIN)
494 CHECK_STATUS("sem_trywait");
495 }
496 else {
497 CHECK_STATUS("sem_wait");
498 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000500
Antoine Pitrou810023d2010-12-15 22:59:16 +0000501 if (status == 0) {
502 success = PY_LOCK_ACQUIRED;
503 } else if (intr_flag && status == EINTR) {
504 success = PY_LOCK_INTR;
505 } else {
506 success = PY_LOCK_FAILURE;
507 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508
Antoine Pitrou810023d2010-12-15 22:59:16 +0000509 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
510 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000512}
513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000515PyThread_release_lock(PyThread_type_lock lock)
516{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517 sem_t *thelock = (sem_t *)lock;
518 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000519
Christian Heimes56379c02012-12-02 08:37:00 +0100520 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 status = sem_post(thelock);
524 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000525}
526
527#else /* USE_SEMAPHORES */
528
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000529/*
530 * Lock support.
531 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000533PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000534{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 pthread_lock *lock;
536 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 dprintf(("PyThread_allocate_lock called\n"));
539 if (!initialized)
540 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000541
Victor Stinner80aa5652013-07-07 17:17:59 +0200542 lock = (pthread_lock *) PyMem_RawMalloc(sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 if (lock) {
544 memset((void *)lock, '\0', sizeof(pthread_lock));
545 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000546
Inada Naoki001fee12019-02-20 10:00:09 +0900547 status = pthread_mutex_init(&lock->mut, NULL);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100548 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 /* Mark the pthread mutex underlying a Python mutex as
550 pure happens-before. We can't simply mark the
551 Python-level mutex as a mutex because it can be
552 acquired and released in different threads, which
553 will cause errors. */
554 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000555
Inada Naoki001fee12019-02-20 10:00:09 +0900556 status = _PyThread_cond_init(&lock->lock_released);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100557 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200560 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000561 lock = 0;
562 }
563 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000564
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600565 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000567}
568
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000570PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000571{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000572 pthread_lock *thelock = (pthread_lock *)lock;
573 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000574
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200575 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000576 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000577
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000578 /* some pthread-like implementations tie the mutex to the cond
579 * and must have the cond destroyed first.
580 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100582 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000583
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000584 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100585 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000586
Victor Stinner80aa5652013-07-07 17:17:59 +0200587 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000588}
589
Antoine Pitrou810023d2010-12-15 22:59:16 +0000590PyLockStatus
591PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
592 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000593{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200594 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 pthread_lock *thelock = (pthread_lock *)lock;
596 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000597
Antoine Pitrou810023d2010-12-15 22:59:16 +0000598 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
599 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000600
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200601 if (microseconds == 0) {
602 status = pthread_mutex_trylock( &thelock->mut );
603 if (status != EBUSY)
604 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
605 }
606 else {
607 status = pthread_mutex_lock( &thelock->mut );
608 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
609 }
610 if (status == 0) {
611 if (thelock->locked == 0) {
612 success = PY_LOCK_ACQUIRED;
613 }
614 else if (microseconds != 0) {
Inada Naoki001fee12019-02-20 10:00:09 +0900615 struct timespec abs;
616 if (microseconds > 0) {
617 _PyThread_cond_after(microseconds, &abs);
618 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200619 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000620
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200621 /* mut must be locked by me -- part of the condition
622 * protocol */
623 while (success == PY_LOCK_FAILURE) {
624 if (microseconds > 0) {
625 status = pthread_cond_timedwait(
626 &thelock->lock_released,
Inada Naoki001fee12019-02-20 10:00:09 +0900627 &thelock->mut, &abs);
628 if (status == 1) {
629 break;
630 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200631 if (status == ETIMEDOUT)
632 break;
Inada Naoki001fee12019-02-20 10:00:09 +0900633 CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200634 }
635 else {
636 status = pthread_cond_wait(
637 &thelock->lock_released,
638 &thelock->mut);
639 CHECK_STATUS_PTHREAD("pthread_cond_wait");
640 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000641
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200642 if (intr_flag && status == 0 && thelock->locked) {
643 /* We were woken up, but didn't get the lock. We probably received
644 * a signal. Return PY_LOCK_INTR to allow the caller to handle
645 * it and retry. */
646 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000647 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200648 }
649 else if (status == 0 && !thelock->locked) {
650 success = PY_LOCK_ACQUIRED;
651 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000652 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000653 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200654 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
655 status = pthread_mutex_unlock( &thelock->mut );
656 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000657 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000658
Antoine Pitrou810023d2010-12-15 22:59:16 +0000659 if (error) success = PY_LOCK_FAILURE;
660 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
661 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000663}
664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000666PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000667{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000668 pthread_lock *thelock = (pthread_lock *)lock;
669 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000670
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200671 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000673
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100675 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 /* wake up someone (anyone, if any) waiting on the lock */
680 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100681 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000682
683 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100684 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000685}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000686
687#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000688
Antoine Pitrou810023d2010-12-15 22:59:16 +0000689int
690PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
691{
692 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
693}
694
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000695/* set the thread stack size.
696 * Return 0 if size is valid, -1 if size is invalid,
697 * -2 if setting stack size is not supported.
698 */
699static int
700_pythread_pthread_set_stacksize(size_t size)
701{
702#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000703 pthread_attr_t attrs;
704 size_t tss_min;
705 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000706#endif
707
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 /* set to default */
709 if (size == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100710 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 return 0;
712 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000713
714#if defined(THREAD_STACK_SIZE)
715#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
717 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000718#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000720#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 if (size >= tss_min) {
722 /* validate stack size by setting thread attribute */
723 if (pthread_attr_init(&attrs) == 0) {
724 rc = pthread_attr_setstacksize(&attrs, size);
725 pthread_attr_destroy(&attrs);
726 if (rc == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100727 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 return 0;
729 }
730 }
731 }
732 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000733#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000735#endif
736}
737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000739
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000740
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900741/* Thread Local Storage (TLS) API
742
743 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
744*/
745
746/* Issue #25658: On platforms where native TLS key is defined in a way that
747 cannot be safely cast to int, PyThread_create_key returns immediately a
748 failure status and other TLS functions all are no-ops. This indicates
749 clearly that the old API is not supported on platforms where it cannot be
750 used reliably, and that no effort will be made to add such support.
751
752 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
753 removing this API.
754*/
755
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000756int
757PyThread_create_key(void)
758{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900759#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000760 pthread_key_t key;
761 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200762 if (fail)
763 return -1;
764 if (key > INT_MAX) {
765 /* Issue #22206: handle integer overflow */
766 pthread_key_delete(key);
767 errno = ENOMEM;
768 return -1;
769 }
770 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900771#else
772 return -1; /* never return valid key value. */
773#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000774}
775
776void
777PyThread_delete_key(int key)
778{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900779#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000780 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900781#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000782}
783
784void
785PyThread_delete_key_value(int key)
786{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900787#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000788 pthread_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900789#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000790}
791
792int
793PyThread_set_key_value(int key, void *value)
794{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900795#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
796 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000797 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900798#else
799 return -1;
800#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000801}
802
803void *
804PyThread_get_key_value(int key)
805{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900806#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000807 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900808#else
809 return NULL;
810#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000811}
812
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900813
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000814void
815PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900816{
817}
818
819
820/* Thread Specific Storage (TSS) API
821
822 Platform-specific components of TSS API implementation.
823*/
824
825int
826PyThread_tss_create(Py_tss_t *key)
827{
828 assert(key != NULL);
829 /* If the key has been created, function is silently skipped. */
830 if (key->_is_initialized) {
831 return 0;
832 }
833
834 int fail = pthread_key_create(&(key->_key), NULL);
835 if (fail) {
836 return -1;
837 }
838 key->_is_initialized = 1;
839 return 0;
840}
841
842void
843PyThread_tss_delete(Py_tss_t *key)
844{
845 assert(key != NULL);
846 /* If the key has not been created, function is silently skipped. */
847 if (!key->_is_initialized) {
848 return;
849 }
850
851 pthread_key_delete(key->_key);
852 /* pthread has not provided the defined invalid value for the key. */
853 key->_is_initialized = 0;
854}
855
856int
857PyThread_tss_set(Py_tss_t *key, void *value)
858{
859 assert(key != NULL);
860 int fail = pthread_setspecific(key->_key, value);
861 return fail ? -1 : 0;
862}
863
864void *
865PyThread_tss_get(Py_tss_t *key)
866{
867 assert(key != NULL);
868 return pthread_getspecific(key->_key);
869}