1 #include "pycore_interp.h" // _PyInterpreterState.pythread_stacksize
2
3 /* Posix threads interface */
4
5 #include <stdlib.h>
6 #include <string.h>
7 #if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
8 #define destructor xxdestructor
9 #endif
10 #include <pthread.h>
11 #if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
12 #undef destructor
13 #endif
14 #include <signal.h>
15
16 #if defined(__linux__)
17 # include <sys/syscall.h> /* syscall(SYS_gettid) */
18 #elif defined(__FreeBSD__)
19 # include <pthread_np.h> /* pthread_getthreadid_np() */
20 #elif defined(__OpenBSD__)
21 # include <unistd.h> /* getthrid() */
22 #elif defined(_AIX)
23 # include <sys/thread.h> /* thread_self() */
24 #elif defined(__NetBSD__)
25 # include <lwp.h> /* _lwp_self() */
26 #endif
27
28 /* The POSIX spec requires that use of pthread_attr_setstacksize
29 be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
30 #ifdef _POSIX_THREAD_ATTR_STACKSIZE
31 #ifndef THREAD_STACK_SIZE
32 #define THREAD_STACK_SIZE 0 /* use default stack size */
33 #endif
34
35 /* The default stack size for new threads on OSX and BSD is small enough that
36 * we'll get hard crashes instead of 'maximum recursion depth exceeded'
37 * exceptions.
38 *
39 * The default stack sizes below are the empirically determined minimal stack
40 * sizes where a simple recursive function doesn't cause a hard crash.
41 */
42 #if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
43 #undef THREAD_STACK_SIZE
44 /* Note: This matches the value of -Wl,-stack_size in configure.ac */
45 #define THREAD_STACK_SIZE 0x1000000
46 #endif
47 #if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
48 #undef THREAD_STACK_SIZE
49 #define THREAD_STACK_SIZE 0x400000
50 #endif
51 #if defined(_AIX) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
52 #undef THREAD_STACK_SIZE
53 #define THREAD_STACK_SIZE 0x200000
54 #endif
55 /* bpo-38852: test_threading.test_recursion_limit() checks that 1000 recursive
56 Python calls (default recursion limit) doesn't crash, but raise a regular
57 RecursionError exception. In debug mode, Python function calls allocates
58 more memory on the stack, so use a stack of 8 MiB. */
59 #if defined(__ANDROID__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
60 # ifdef Py_DEBUG
61 # undef THREAD_STACK_SIZE
62 # define THREAD_STACK_SIZE 0x800000
63 # endif
64 #endif
65 /* for safety, ensure a viable minimum stacksize */
66 #define THREAD_STACK_MIN 0x8000 /* 32 KiB */
67 #else /* !_POSIX_THREAD_ATTR_STACKSIZE */
68 #ifdef THREAD_STACK_SIZE
69 #error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
70 #endif
71 #endif
72
73 /* The POSIX spec says that implementations supporting the sem_*
74 family of functions must indicate this by defining
75 _POSIX_SEMAPHORES. */
76 #ifdef _POSIX_SEMAPHORES
77 /* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
78 we need to add 0 to make it work there as well. */
79 #if (_POSIX_SEMAPHORES+0) == -1
80 #define HAVE_BROKEN_POSIX_SEMAPHORES
81 #else
82 #include <semaphore.h>
83 #include <errno.h>
84 #endif
85 #endif
86
87
88 /* Whether or not to use semaphores directly rather than emulating them with
89 * mutexes and condition variables:
90 */
91 #if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
92 defined(HAVE_SEM_TIMEDWAIT))
93 # define USE_SEMAPHORES
94 #else
95 # undef USE_SEMAPHORES
96 #endif
97
98
99 /* On platforms that don't use standard POSIX threads pthread_sigmask()
100 * isn't present. DEC threads uses sigprocmask() instead as do most
101 * other UNIX International compliant systems that don't have the full
102 * pthread implementation.
103 */
104 #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
105 # define SET_THREAD_SIGMASK pthread_sigmask
106 #else
107 # define SET_THREAD_SIGMASK sigprocmask
108 #endif
109
110
111 #define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
112 do { \
113 struct timeval tv; \
114 gettimeofday(&tv, NULL); \
115 tv.tv_usec += microseconds % 1000000; \
116 tv.tv_sec += microseconds / 1000000; \
117 tv.tv_sec += tv.tv_usec / 1000000; \
118 tv.tv_usec %= 1000000; \
119 ts.tv_sec = tv.tv_sec; \
120 ts.tv_nsec = tv.tv_usec * 1000; \
121 } while(0)
122
123
124 /*
125 * pthread_cond support
126 */
127
128 #if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
129 // monotonic is supported statically. It doesn't mean it works on runtime.
130 #define CONDATTR_MONOTONIC
131 #endif
132
133 // NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
134 static pthread_condattr_t *condattr_monotonic = NULL;
135
136 static void
init_condattr(void)137 init_condattr(void)
138 {
139 #ifdef CONDATTR_MONOTONIC
140 static pthread_condattr_t ca;
141 pthread_condattr_init(&ca);
142 if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) {
143 condattr_monotonic = &ca; // Use monotonic clock
144 }
145 #endif
146 }
147
148 int
_PyThread_cond_init(PyCOND_T * cond)149 _PyThread_cond_init(PyCOND_T *cond)
150 {
151 return pthread_cond_init(cond, condattr_monotonic);
152 }
153
154 void
_PyThread_cond_after(long long us,struct timespec * abs)155 _PyThread_cond_after(long long us, struct timespec *abs)
156 {
157 #ifdef CONDATTR_MONOTONIC
158 if (condattr_monotonic) {
159 clock_gettime(CLOCK_MONOTONIC, abs);
160 abs->tv_sec += us / 1000000;
161 abs->tv_nsec += (us % 1000000) * 1000;
162 abs->tv_sec += abs->tv_nsec / 1000000000;
163 abs->tv_nsec %= 1000000000;
164 return;
165 }
166 #endif
167
168 struct timespec ts;
169 MICROSECONDS_TO_TIMESPEC(us, ts);
170 *abs = ts;
171 }
172
173
174 /* A pthread mutex isn't sufficient to model the Python lock type
175 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
176 * following are undefined:
177 * -> a thread tries to lock a mutex it already has locked
178 * -> a thread tries to unlock a mutex locked by a different thread
179 * pthread mutexes are designed for serializing threads over short pieces
180 * of code anyway, so wouldn't be an appropriate implementation of
181 * Python's locks regardless.
182 *
183 * The pthread_lock struct implements a Python lock as a "locked?" bit
184 * and a <condition, mutex> pair. In general, if the bit can be acquired
185 * instantly, it is, else the pair is used to block the thread until the
186 * bit is cleared. 9 May 1994 tim@ksr.com
187 */
188
189 typedef struct {
190 char locked; /* 0=unlocked, 1=locked */
191 /* a <cond, mutex> pair to handle an acquire of a locked lock */
192 pthread_cond_t lock_released;
193 pthread_mutex_t mut;
194 } pthread_lock;
195
196 #define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
197 #define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
198 "%s: %s\n", name, strerror(status)); error = 1; }
199
200 /*
201 * Initialization.
202 */
203 static void
PyThread__init_thread(void)204 PyThread__init_thread(void)
205 {
206 #if defined(_AIX) && defined(__GNUC__)
207 extern void pthread_init(void);
208 pthread_init();
209 #endif
210 init_condattr();
211 }
212
213 /*
214 * Thread support.
215 */
216
217 /* bpo-33015: pythread_callback struct and pythread_wrapper() cast
218 "void func(void *)" to "void* func(void *)": always return NULL.
219
220 PyThread_start_new_thread() uses "void func(void *)" type, whereas
221 pthread_create() requires a void* return value. */
222 typedef struct {
223 void (*func) (void *);
224 void *arg;
225 } pythread_callback;
226
227 static void *
pythread_wrapper(void * arg)228 pythread_wrapper(void *arg)
229 {
230 /* copy func and func_arg and free the temporary structure */
231 pythread_callback *callback = arg;
232 void (*func)(void *) = callback->func;
233 void *func_arg = callback->arg;
234 PyMem_RawFree(arg);
235
236 func(func_arg);
237 return NULL;
238 }
239
240 unsigned long
PyThread_start_new_thread(void (* func)(void *),void * arg)241 PyThread_start_new_thread(void (*func)(void *), void *arg)
242 {
243 pthread_t th;
244 int status;
245 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
246 pthread_attr_t attrs;
247 #endif
248 #if defined(THREAD_STACK_SIZE)
249 size_t tss;
250 #endif
251
252 dprintf(("PyThread_start_new_thread called\n"));
253 if (!initialized)
254 PyThread_init_thread();
255
256 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
257 if (pthread_attr_init(&attrs) != 0)
258 return PYTHREAD_INVALID_THREAD_ID;
259 #endif
260 #if defined(THREAD_STACK_SIZE)
261 PyThreadState *tstate = _PyThreadState_GET();
262 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
263 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
264 if (tss != 0) {
265 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
266 pthread_attr_destroy(&attrs);
267 return PYTHREAD_INVALID_THREAD_ID;
268 }
269 }
270 #endif
271 #if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
272 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
273 #endif
274
275 pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
276
277 if (callback == NULL) {
278 return PYTHREAD_INVALID_THREAD_ID;
279 }
280
281 callback->func = func;
282 callback->arg = arg;
283
284 status = pthread_create(&th,
285 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
286 &attrs,
287 #else
288 (pthread_attr_t*)NULL,
289 #endif
290 pythread_wrapper, callback);
291
292 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
293 pthread_attr_destroy(&attrs);
294 #endif
295
296 if (status != 0) {
297 PyMem_RawFree(callback);
298 return PYTHREAD_INVALID_THREAD_ID;
299 }
300
301 pthread_detach(th);
302
303 #if SIZEOF_PTHREAD_T <= SIZEOF_LONG
304 return (unsigned long) th;
305 #else
306 return (unsigned long) *(unsigned long *) &th;
307 #endif
308 }
309
310 /* XXX This implementation is considered (to quote Tim Peters) "inherently
311 hosed" because:
312 - It does not guarantee the promise that a non-zero integer is returned.
313 - The cast to unsigned long is inherently unsafe.
314 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
315 */
316 unsigned long
PyThread_get_thread_ident(void)317 PyThread_get_thread_ident(void)
318 {
319 volatile pthread_t threadid;
320 if (!initialized)
321 PyThread_init_thread();
322 threadid = pthread_self();
323 return (unsigned long) threadid;
324 }
325
326 #ifdef PY_HAVE_THREAD_NATIVE_ID
327 unsigned long
PyThread_get_thread_native_id(void)328 PyThread_get_thread_native_id(void)
329 {
330 if (!initialized)
331 PyThread_init_thread();
332 #ifdef __APPLE__
333 uint64_t native_id;
334 (void) pthread_threadid_np(NULL, &native_id);
335 #elif defined(__linux__)
336 pid_t native_id;
337 native_id = syscall(SYS_gettid);
338 #elif defined(__FreeBSD__)
339 int native_id;
340 native_id = pthread_getthreadid_np();
341 #elif defined(__OpenBSD__)
342 pid_t native_id;
343 native_id = getthrid();
344 #elif defined(_AIX)
345 tid_t native_id;
346 native_id = thread_self();
347 #elif defined(__NetBSD__)
348 lwpid_t native_id;
349 native_id = _lwp_self();
350 #endif
351 return (unsigned long) native_id;
352 }
353 #endif
354
355 void _Py_NO_RETURN
PyThread_exit_thread(void)356 PyThread_exit_thread(void)
357 {
358 dprintf(("PyThread_exit_thread called\n"));
359 if (!initialized)
360 exit(0);
361 pthread_exit(0);
362 }
363
364 #ifdef USE_SEMAPHORES
365
366 /*
367 * Lock support.
368 */
369
370 PyThread_type_lock
PyThread_allocate_lock(void)371 PyThread_allocate_lock(void)
372 {
373 sem_t *lock;
374 int status, error = 0;
375
376 dprintf(("PyThread_allocate_lock called\n"));
377 if (!initialized)
378 PyThread_init_thread();
379
380 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
381
382 if (lock) {
383 status = sem_init(lock,0,1);
384 CHECK_STATUS("sem_init");
385
386 if (error) {
387 PyMem_RawFree((void *)lock);
388 lock = NULL;
389 }
390 }
391
392 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
393 return (PyThread_type_lock)lock;
394 }
395
396 void
PyThread_free_lock(PyThread_type_lock lock)397 PyThread_free_lock(PyThread_type_lock lock)
398 {
399 sem_t *thelock = (sem_t *)lock;
400 int status, error = 0;
401
402 (void) error; /* silence unused-but-set-variable warning */
403 dprintf(("PyThread_free_lock(%p) called\n", lock));
404
405 if (!thelock)
406 return;
407
408 status = sem_destroy(thelock);
409 CHECK_STATUS("sem_destroy");
410
411 PyMem_RawFree((void *)thelock);
412 }
413
414 /*
415 * As of February 2002, Cygwin thread implementations mistakenly report error
416 * codes in the return value of the sem_ calls (like the pthread_ functions).
417 * Correct implementations return -1 and put the code in errno. This supports
418 * either.
419 */
420 static int
fix_status(int status)421 fix_status(int status)
422 {
423 return (status == -1) ? errno : status;
424 }
425
426 PyLockStatus
PyThread_acquire_lock_timed(PyThread_type_lock lock,PY_TIMEOUT_T microseconds,int intr_flag)427 PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
428 int intr_flag)
429 {
430 PyLockStatus success;
431 sem_t *thelock = (sem_t *)lock;
432 int status, error = 0;
433 struct timespec ts;
434 _PyTime_t deadline = 0;
435
436 (void) error; /* silence unused-but-set-variable warning */
437 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
438 lock, microseconds, intr_flag));
439
440 if (microseconds > PY_TIMEOUT_MAX) {
441 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
442 }
443
444 if (microseconds > 0) {
445 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
446
447 if (!intr_flag) {
448 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
449 check done above */
450 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
451 deadline = _PyTime_GetMonotonicClock() + timeout;
452 }
453 }
454
455 while (1) {
456 if (microseconds > 0) {
457 status = fix_status(sem_timedwait(thelock, &ts));
458 }
459 else if (microseconds == 0) {
460 status = fix_status(sem_trywait(thelock));
461 }
462 else {
463 status = fix_status(sem_wait(thelock));
464 }
465
466 /* Retry if interrupted by a signal, unless the caller wants to be
467 notified. */
468 if (intr_flag || status != EINTR) {
469 break;
470 }
471
472 if (microseconds > 0) {
473 /* wait interrupted by a signal (EINTR): recompute the timeout */
474 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
475 if (dt < 0) {
476 status = ETIMEDOUT;
477 break;
478 }
479 else if (dt > 0) {
480 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
481 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
482 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
483 check done above */
484 Py_UNREACHABLE();
485 }
486 /* no need to update microseconds value, the code only care
487 if (microseconds > 0 or (microseconds == 0). */
488 }
489 else {
490 microseconds = 0;
491 }
492 }
493 }
494
495 /* Don't check the status if we're stopping because of an interrupt. */
496 if (!(intr_flag && status == EINTR)) {
497 if (microseconds > 0) {
498 if (status != ETIMEDOUT)
499 CHECK_STATUS("sem_timedwait");
500 }
501 else if (microseconds == 0) {
502 if (status != EAGAIN)
503 CHECK_STATUS("sem_trywait");
504 }
505 else {
506 CHECK_STATUS("sem_wait");
507 }
508 }
509
510 if (status == 0) {
511 success = PY_LOCK_ACQUIRED;
512 } else if (intr_flag && status == EINTR) {
513 success = PY_LOCK_INTR;
514 } else {
515 success = PY_LOCK_FAILURE;
516 }
517
518 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
519 lock, microseconds, intr_flag, success));
520 return success;
521 }
522
523 void
PyThread_release_lock(PyThread_type_lock lock)524 PyThread_release_lock(PyThread_type_lock lock)
525 {
526 sem_t *thelock = (sem_t *)lock;
527 int status, error = 0;
528
529 (void) error; /* silence unused-but-set-variable warning */
530 dprintf(("PyThread_release_lock(%p) called\n", lock));
531
532 status = sem_post(thelock);
533 CHECK_STATUS("sem_post");
534 }
535
536 #else /* USE_SEMAPHORES */
537
538 /*
539 * Lock support.
540 */
541 PyThread_type_lock
PyThread_allocate_lock(void)542 PyThread_allocate_lock(void)
543 {
544 pthread_lock *lock;
545 int status, error = 0;
546
547 dprintf(("PyThread_allocate_lock called\n"));
548 if (!initialized)
549 PyThread_init_thread();
550
551 lock = (pthread_lock *) PyMem_RawCalloc(1, sizeof(pthread_lock));
552 if (lock) {
553 lock->locked = 0;
554
555 status = pthread_mutex_init(&lock->mut, NULL);
556 CHECK_STATUS_PTHREAD("pthread_mutex_init");
557 /* Mark the pthread mutex underlying a Python mutex as
558 pure happens-before. We can't simply mark the
559 Python-level mutex as a mutex because it can be
560 acquired and released in different threads, which
561 will cause errors. */
562 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
563
564 status = _PyThread_cond_init(&lock->lock_released);
565 CHECK_STATUS_PTHREAD("pthread_cond_init");
566
567 if (error) {
568 PyMem_RawFree((void *)lock);
569 lock = 0;
570 }
571 }
572
573 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
574 return (PyThread_type_lock) lock;
575 }
576
577 void
PyThread_free_lock(PyThread_type_lock lock)578 PyThread_free_lock(PyThread_type_lock lock)
579 {
580 pthread_lock *thelock = (pthread_lock *)lock;
581 int status, error = 0;
582
583 (void) error; /* silence unused-but-set-variable warning */
584 dprintf(("PyThread_free_lock(%p) called\n", lock));
585
586 /* some pthread-like implementations tie the mutex to the cond
587 * and must have the cond destroyed first.
588 */
589 status = pthread_cond_destroy( &thelock->lock_released );
590 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
591
592 status = pthread_mutex_destroy( &thelock->mut );
593 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
594
595 PyMem_RawFree((void *)thelock);
596 }
597
598 PyLockStatus
PyThread_acquire_lock_timed(PyThread_type_lock lock,PY_TIMEOUT_T microseconds,int intr_flag)599 PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
600 int intr_flag)
601 {
602 PyLockStatus success = PY_LOCK_FAILURE;
603 pthread_lock *thelock = (pthread_lock *)lock;
604 int status, error = 0;
605
606 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
607 lock, microseconds, intr_flag));
608
609 if (microseconds == 0) {
610 status = pthread_mutex_trylock( &thelock->mut );
611 if (status != EBUSY)
612 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
613 }
614 else {
615 status = pthread_mutex_lock( &thelock->mut );
616 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
617 }
618 if (status == 0) {
619 if (thelock->locked == 0) {
620 success = PY_LOCK_ACQUIRED;
621 }
622 else if (microseconds != 0) {
623 struct timespec abs;
624 if (microseconds > 0) {
625 _PyThread_cond_after(microseconds, &abs);
626 }
627 /* continue trying until we get the lock */
628
629 /* mut must be locked by me -- part of the condition
630 * protocol */
631 while (success == PY_LOCK_FAILURE) {
632 if (microseconds > 0) {
633 status = pthread_cond_timedwait(
634 &thelock->lock_released,
635 &thelock->mut, &abs);
636 if (status == 1) {
637 break;
638 }
639 if (status == ETIMEDOUT)
640 break;
641 CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
642 }
643 else {
644 status = pthread_cond_wait(
645 &thelock->lock_released,
646 &thelock->mut);
647 CHECK_STATUS_PTHREAD("pthread_cond_wait");
648 }
649
650 if (intr_flag && status == 0 && thelock->locked) {
651 /* We were woken up, but didn't get the lock. We probably received
652 * a signal. Return PY_LOCK_INTR to allow the caller to handle
653 * it and retry. */
654 success = PY_LOCK_INTR;
655 break;
656 }
657 else if (status == 0 && !thelock->locked) {
658 success = PY_LOCK_ACQUIRED;
659 }
660 }
661 }
662 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
663 status = pthread_mutex_unlock( &thelock->mut );
664 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
665 }
666
667 if (error) success = PY_LOCK_FAILURE;
668 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
669 lock, microseconds, intr_flag, success));
670 return success;
671 }
672
673 void
PyThread_release_lock(PyThread_type_lock lock)674 PyThread_release_lock(PyThread_type_lock lock)
675 {
676 pthread_lock *thelock = (pthread_lock *)lock;
677 int status, error = 0;
678
679 (void) error; /* silence unused-but-set-variable warning */
680 dprintf(("PyThread_release_lock(%p) called\n", lock));
681
682 status = pthread_mutex_lock( &thelock->mut );
683 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
684
685 thelock->locked = 0;
686
687 /* wake up someone (anyone, if any) waiting on the lock */
688 status = pthread_cond_signal( &thelock->lock_released );
689 CHECK_STATUS_PTHREAD("pthread_cond_signal");
690
691 status = pthread_mutex_unlock( &thelock->mut );
692 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
693 }
694
695 #endif /* USE_SEMAPHORES */
696
697 int
_PyThread_at_fork_reinit(PyThread_type_lock * lock)698 _PyThread_at_fork_reinit(PyThread_type_lock *lock)
699 {
700 PyThread_type_lock new_lock = PyThread_allocate_lock();
701 if (new_lock == NULL) {
702 return -1;
703 }
704
705 /* bpo-6721, bpo-40089: The old lock can be in an inconsistent state.
706 fork() can be called in the middle of an operation on the lock done by
707 another thread. So don't call PyThread_free_lock(*lock).
708
709 Leak memory on purpose. Don't release the memory either since the
710 address of a mutex is relevant. Putting two mutexes at the same address
711 can lead to problems. */
712
713 *lock = new_lock;
714 return 0;
715 }
716
717 int
PyThread_acquire_lock(PyThread_type_lock lock,int waitflag)718 PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
719 {
720 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
721 }
722
723 /* set the thread stack size.
724 * Return 0 if size is valid, -1 if size is invalid,
725 * -2 if setting stack size is not supported.
726 */
727 static int
_pythread_pthread_set_stacksize(size_t size)728 _pythread_pthread_set_stacksize(size_t size)
729 {
730 #if defined(THREAD_STACK_SIZE)
731 pthread_attr_t attrs;
732 size_t tss_min;
733 int rc = 0;
734 #endif
735
736 /* set to default */
737 if (size == 0) {
738 _PyInterpreterState_GET()->pythread_stacksize = 0;
739 return 0;
740 }
741
742 #if defined(THREAD_STACK_SIZE)
743 #if defined(PTHREAD_STACK_MIN)
744 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
745 : THREAD_STACK_MIN;
746 #else
747 tss_min = THREAD_STACK_MIN;
748 #endif
749 if (size >= tss_min) {
750 /* validate stack size by setting thread attribute */
751 if (pthread_attr_init(&attrs) == 0) {
752 rc = pthread_attr_setstacksize(&attrs, size);
753 pthread_attr_destroy(&attrs);
754 if (rc == 0) {
755 _PyInterpreterState_GET()->pythread_stacksize = size;
756 return 0;
757 }
758 }
759 }
760 return -1;
761 #else
762 return -2;
763 #endif
764 }
765
766 #define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
767
768
769 /* Thread Local Storage (TLS) API
770
771 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
772 */
773
774 /* Issue #25658: On platforms where native TLS key is defined in a way that
775 cannot be safely cast to int, PyThread_create_key returns immediately a
776 failure status and other TLS functions all are no-ops. This indicates
777 clearly that the old API is not supported on platforms where it cannot be
778 used reliably, and that no effort will be made to add such support.
779
780 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
781 removing this API.
782 */
783
784 int
PyThread_create_key(void)785 PyThread_create_key(void)
786 {
787 #ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
788 pthread_key_t key;
789 int fail = pthread_key_create(&key, NULL);
790 if (fail)
791 return -1;
792 if (key > INT_MAX) {
793 /* Issue #22206: handle integer overflow */
794 pthread_key_delete(key);
795 errno = ENOMEM;
796 return -1;
797 }
798 return (int)key;
799 #else
800 return -1; /* never return valid key value. */
801 #endif
802 }
803
804 void
PyThread_delete_key(int key)805 PyThread_delete_key(int key)
806 {
807 #ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
808 pthread_key_delete(key);
809 #endif
810 }
811
812 void
PyThread_delete_key_value(int key)813 PyThread_delete_key_value(int key)
814 {
815 #ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
816 pthread_setspecific(key, NULL);
817 #endif
818 }
819
820 int
PyThread_set_key_value(int key,void * value)821 PyThread_set_key_value(int key, void *value)
822 {
823 #ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
824 int fail = pthread_setspecific(key, value);
825 return fail ? -1 : 0;
826 #else
827 return -1;
828 #endif
829 }
830
831 void *
PyThread_get_key_value(int key)832 PyThread_get_key_value(int key)
833 {
834 #ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
835 return pthread_getspecific(key);
836 #else
837 return NULL;
838 #endif
839 }
840
841
842 void
PyThread_ReInitTLS(void)843 PyThread_ReInitTLS(void)
844 {
845 }
846
847
848 /* Thread Specific Storage (TSS) API
849
850 Platform-specific components of TSS API implementation.
851 */
852
853 int
PyThread_tss_create(Py_tss_t * key)854 PyThread_tss_create(Py_tss_t *key)
855 {
856 assert(key != NULL);
857 /* If the key has been created, function is silently skipped. */
858 if (key->_is_initialized) {
859 return 0;
860 }
861
862 int fail = pthread_key_create(&(key->_key), NULL);
863 if (fail) {
864 return -1;
865 }
866 key->_is_initialized = 1;
867 return 0;
868 }
869
870 void
PyThread_tss_delete(Py_tss_t * key)871 PyThread_tss_delete(Py_tss_t *key)
872 {
873 assert(key != NULL);
874 /* If the key has not been created, function is silently skipped. */
875 if (!key->_is_initialized) {
876 return;
877 }
878
879 pthread_key_delete(key->_key);
880 /* pthread has not provided the defined invalid value for the key. */
881 key->_is_initialized = 0;
882 }
883
884 int
PyThread_tss_set(Py_tss_t * key,void * value)885 PyThread_tss_set(Py_tss_t *key, void *value)
886 {
887 assert(key != NULL);
888 int fail = pthread_setspecific(key->_key, value);
889 return fail ? -1 : 0;
890 }
891
892 void *
PyThread_tss_get(Py_tss_t * key)893 PyThread_tss_get(Py_tss_t *key)
894 {
895 assert(key != NULL);
896 return pthread_getspecific(key->_key);
897 }
898