1 /* Thread module */
2 /* Interface to Sjoerd's portable C thread library */
3
4 #include "Python.h"
5 #include "pycore_interp.h" // _PyInterpreterState.threads.count
6 #include "pycore_lock.h"
7 #include "pycore_moduleobject.h" // _PyModule_GetState()
8 #include "pycore_modsupport.h" // _PyArg_NoKeywords()
9 #include "pycore_pylifecycle.h"
10 #include "pycore_pystate.h" // _PyThreadState_SetCurrent()
11 #include "pycore_sysmodule.h" // _PySys_GetAttr()
12 #include "pycore_time.h" // _PyTime_FromSeconds()
13 #include "pycore_weakref.h" // _PyWeakref_GET_REF()
14
15 #include <stddef.h> // offsetof()
16 #ifdef HAVE_SIGNAL_H
17 # include <signal.h> // SIGINT
18 #endif
19
20 // ThreadError is just an alias to PyExc_RuntimeError
21 #define ThreadError PyExc_RuntimeError
22
23 // Forward declarations
24 static struct PyModuleDef thread_module;
25
26 // Module state
27 typedef struct {
28 PyTypeObject *excepthook_type;
29 PyTypeObject *lock_type;
30 PyTypeObject *local_type;
31 PyTypeObject *local_dummy_type;
32 PyTypeObject *thread_handle_type;
33
34 // Linked list of handles to all non-daemon threads created by the
35 // threading module. We wait for these to finish at shutdown.
36 struct llist_node shutdown_handles;
37 } thread_module_state;
38
39 static inline thread_module_state*
get_thread_state(PyObject * module)40 get_thread_state(PyObject *module)
41 {
42 void *state = _PyModule_GetState(module);
43 assert(state != NULL);
44 return (thread_module_state *)state;
45 }
46
47 // _ThreadHandle type
48
49 // Handles state transitions according to the following diagram:
50 //
51 // NOT_STARTED -> STARTING -> RUNNING -> DONE
52 // | ^
53 // | |
54 // +----- error --------+
55 typedef enum {
56 THREAD_HANDLE_NOT_STARTED = 1,
57 THREAD_HANDLE_STARTING = 2,
58 THREAD_HANDLE_RUNNING = 3,
59 THREAD_HANDLE_DONE = 4,
60 } ThreadHandleState;
61
62 // A handle to wait for thread completion.
63 //
64 // This may be used to wait for threads that were spawned by the threading
65 // module as well as for the "main" thread of the threading module. In the
66 // former case an OS thread, identified by the `os_handle` field, will be
67 // associated with the handle. The handle "owns" this thread and ensures that
68 // the thread is either joined or detached after the handle is destroyed.
69 //
70 // Joining the handle is idempotent; the underlying OS thread, if any, is
71 // joined or detached only once. Concurrent join operations are serialized
72 // until it is their turn to execute or an earlier operation completes
73 // successfully. Once a join has completed successfully all future joins
74 // complete immediately.
75 //
76 // This must be separately reference counted because it may be destroyed
77 // in `thread_run()` after the PyThreadState has been destroyed.
78 typedef struct {
79 struct llist_node node; // linked list node (see _pythread_runtime_state)
80
81 // linked list node (see thread_module_state)
82 struct llist_node shutdown_node;
83
84 // The `ident`, `os_handle`, `has_os_handle`, and `state` fields are
85 // protected by `mutex`.
86 PyThread_ident_t ident;
87 PyThread_handle_t os_handle;
88 int has_os_handle;
89
90 // Holds a value from the `ThreadHandleState` enum.
91 int state;
92
93 PyMutex mutex;
94
95 // Set immediately before `thread_run` returns to indicate that the OS
96 // thread is about to exit. This is used to avoid false positives when
97 // detecting self-join attempts. See the comment in `ThreadHandle_join()`
98 // for a more detailed explanation.
99 PyEvent thread_is_exiting;
100
101 // Serializes calls to `join` and `set_done`.
102 _PyOnceFlag once;
103
104 Py_ssize_t refcount;
105 } ThreadHandle;
106
107 static inline int
get_thread_handle_state(ThreadHandle * handle)108 get_thread_handle_state(ThreadHandle *handle)
109 {
110 PyMutex_Lock(&handle->mutex);
111 int state = handle->state;
112 PyMutex_Unlock(&handle->mutex);
113 return state;
114 }
115
116 static inline void
set_thread_handle_state(ThreadHandle * handle,ThreadHandleState state)117 set_thread_handle_state(ThreadHandle *handle, ThreadHandleState state)
118 {
119 PyMutex_Lock(&handle->mutex);
120 handle->state = state;
121 PyMutex_Unlock(&handle->mutex);
122 }
123
124 static PyThread_ident_t
ThreadHandle_ident(ThreadHandle * handle)125 ThreadHandle_ident(ThreadHandle *handle)
126 {
127 PyMutex_Lock(&handle->mutex);
128 PyThread_ident_t ident = handle->ident;
129 PyMutex_Unlock(&handle->mutex);
130 return ident;
131 }
132
133 static int
ThreadHandle_get_os_handle(ThreadHandle * handle,PyThread_handle_t * os_handle)134 ThreadHandle_get_os_handle(ThreadHandle *handle, PyThread_handle_t *os_handle)
135 {
136 PyMutex_Lock(&handle->mutex);
137 int has_os_handle = handle->has_os_handle;
138 if (has_os_handle) {
139 *os_handle = handle->os_handle;
140 }
141 PyMutex_Unlock(&handle->mutex);
142 return has_os_handle;
143 }
144
145 static void
add_to_shutdown_handles(thread_module_state * state,ThreadHandle * handle)146 add_to_shutdown_handles(thread_module_state *state, ThreadHandle *handle)
147 {
148 HEAD_LOCK(&_PyRuntime);
149 llist_insert_tail(&state->shutdown_handles, &handle->shutdown_node);
150 HEAD_UNLOCK(&_PyRuntime);
151 }
152
153 static void
clear_shutdown_handles(thread_module_state * state)154 clear_shutdown_handles(thread_module_state *state)
155 {
156 HEAD_LOCK(&_PyRuntime);
157 struct llist_node *node;
158 llist_for_each_safe(node, &state->shutdown_handles) {
159 llist_remove(node);
160 }
161 HEAD_UNLOCK(&_PyRuntime);
162 }
163
164 static void
remove_from_shutdown_handles(ThreadHandle * handle)165 remove_from_shutdown_handles(ThreadHandle *handle)
166 {
167 HEAD_LOCK(&_PyRuntime);
168 if (handle->shutdown_node.next != NULL) {
169 llist_remove(&handle->shutdown_node);
170 }
171 HEAD_UNLOCK(&_PyRuntime);
172 }
173
174 static ThreadHandle *
ThreadHandle_new(void)175 ThreadHandle_new(void)
176 {
177 ThreadHandle *self =
178 (ThreadHandle *)PyMem_RawCalloc(1, sizeof(ThreadHandle));
179 if (self == NULL) {
180 PyErr_NoMemory();
181 return NULL;
182 }
183 self->ident = 0;
184 self->os_handle = 0;
185 self->has_os_handle = 0;
186 self->thread_is_exiting = (PyEvent){0};
187 self->mutex = (PyMutex){_Py_UNLOCKED};
188 self->once = (_PyOnceFlag){0};
189 self->state = THREAD_HANDLE_NOT_STARTED;
190 self->refcount = 1;
191
192 HEAD_LOCK(&_PyRuntime);
193 llist_insert_tail(&_PyRuntime.threads.handles, &self->node);
194 HEAD_UNLOCK(&_PyRuntime);
195
196 return self;
197 }
198
199 static void
ThreadHandle_incref(ThreadHandle * self)200 ThreadHandle_incref(ThreadHandle *self)
201 {
202 _Py_atomic_add_ssize(&self->refcount, 1);
203 }
204
205 static int
detach_thread(ThreadHandle * self)206 detach_thread(ThreadHandle *self)
207 {
208 if (!self->has_os_handle) {
209 return 0;
210 }
211 // This is typically short so no need to release the GIL
212 if (PyThread_detach_thread(self->os_handle)) {
213 fprintf(stderr, "detach_thread: failed detaching thread\n");
214 return -1;
215 }
216 return 0;
217 }
218
219 // NB: This may be called after the PyThreadState in `thread_run` has been
220 // deleted; it cannot call anything that relies on a valid PyThreadState
221 // existing.
222 static void
ThreadHandle_decref(ThreadHandle * self)223 ThreadHandle_decref(ThreadHandle *self)
224 {
225 if (_Py_atomic_add_ssize(&self->refcount, -1) > 1) {
226 return;
227 }
228
229 // Remove ourself from the global list of handles
230 HEAD_LOCK(&_PyRuntime);
231 if (self->node.next != NULL) {
232 llist_remove(&self->node);
233 }
234 HEAD_UNLOCK(&_PyRuntime);
235
236 assert(self->shutdown_node.next == NULL);
237
238 // It's safe to access state non-atomically:
239 // 1. This is the destructor; nothing else holds a reference.
240 // 2. The refcount going to zero is a "synchronizes-with" event; all
241 // changes from other threads are visible.
242 if (self->state == THREAD_HANDLE_RUNNING && !detach_thread(self)) {
243 self->state = THREAD_HANDLE_DONE;
244 }
245
246 PyMem_RawFree(self);
247 }
248
249 void
_PyThread_AfterFork(struct _pythread_runtime_state * state)250 _PyThread_AfterFork(struct _pythread_runtime_state *state)
251 {
252 // gh-115035: We mark ThreadHandles as not joinable early in the child's
253 // after-fork handler. We do this before calling any Python code to ensure
254 // that it happens before any ThreadHandles are deallocated, such as by a
255 // GC cycle.
256 PyThread_ident_t current = PyThread_get_thread_ident_ex();
257
258 struct llist_node *node;
259 llist_for_each_safe(node, &state->handles) {
260 ThreadHandle *handle = llist_data(node, ThreadHandle, node);
261 if (handle->ident == current) {
262 continue;
263 }
264
265 // Mark all threads as done. Any attempts to join or detach the
266 // underlying OS thread (if any) could crash. We are the only thread;
267 // it's safe to set this non-atomically.
268 handle->state = THREAD_HANDLE_DONE;
269 handle->once = (_PyOnceFlag){_Py_ONCE_INITIALIZED};
270 handle->mutex = (PyMutex){_Py_UNLOCKED};
271 _PyEvent_Notify(&handle->thread_is_exiting);
272 llist_remove(node);
273 remove_from_shutdown_handles(handle);
274 }
275 }
276
277 // bootstate is used to "bootstrap" new threads. Any arguments needed by
278 // `thread_run()`, which can only take a single argument due to platform
279 // limitations, are contained in bootstate.
280 struct bootstate {
281 PyThreadState *tstate;
282 PyObject *func;
283 PyObject *args;
284 PyObject *kwargs;
285 ThreadHandle *handle;
286 PyEvent handle_ready;
287 };
288
289 static void
thread_bootstate_free(struct bootstate * boot,int decref)290 thread_bootstate_free(struct bootstate *boot, int decref)
291 {
292 if (decref) {
293 Py_DECREF(boot->func);
294 Py_DECREF(boot->args);
295 Py_XDECREF(boot->kwargs);
296 }
297 ThreadHandle_decref(boot->handle);
298 PyMem_RawFree(boot);
299 }
300
301 static void
thread_run(void * boot_raw)302 thread_run(void *boot_raw)
303 {
304 struct bootstate *boot = (struct bootstate *) boot_raw;
305 PyThreadState *tstate = boot->tstate;
306
307 // Wait until the handle is marked as running
308 PyEvent_Wait(&boot->handle_ready);
309
310 // `handle` needs to be manipulated after bootstate has been freed
311 ThreadHandle *handle = boot->handle;
312 ThreadHandle_incref(handle);
313
314 // gh-108987: If _thread.start_new_thread() is called before or while
315 // Python is being finalized, thread_run() can called *after*.
316 // _PyRuntimeState_SetFinalizing() is called. At this point, all Python
317 // threads must exit, except of the thread calling Py_Finalize() which
318 // holds the GIL and must not exit.
319 //
320 // At this stage, tstate can be a dangling pointer (point to freed memory),
321 // it's ok to call _PyThreadState_MustExit() with a dangling pointer.
322 if (_PyThreadState_MustExit(tstate)) {
323 // Don't call PyThreadState_Clear() nor _PyThreadState_DeleteCurrent().
324 // These functions are called on tstate indirectly by Py_Finalize()
325 // which calls _PyInterpreterState_Clear().
326 //
327 // Py_DECREF() cannot be called because the GIL is not held: leak
328 // references on purpose. Python is being finalized anyway.
329 thread_bootstate_free(boot, 0);
330 goto exit;
331 }
332
333 _PyThreadState_Bind(tstate);
334 PyEval_AcquireThread(tstate);
335 _Py_atomic_add_ssize(&tstate->interp->threads.count, 1);
336
337 PyObject *res = PyObject_Call(boot->func, boot->args, boot->kwargs);
338 if (res == NULL) {
339 if (PyErr_ExceptionMatches(PyExc_SystemExit))
340 /* SystemExit is ignored silently */
341 PyErr_Clear();
342 else {
343 PyErr_FormatUnraisable(
344 "Exception ignored in thread started by %R", boot->func);
345 }
346 }
347 else {
348 Py_DECREF(res);
349 }
350
351 thread_bootstate_free(boot, 1);
352
353 _Py_atomic_add_ssize(&tstate->interp->threads.count, -1);
354 PyThreadState_Clear(tstate);
355 _PyThreadState_DeleteCurrent(tstate);
356
357 exit:
358 // Don't need to wait for this thread anymore
359 remove_from_shutdown_handles(handle);
360
361 _PyEvent_Notify(&handle->thread_is_exiting);
362 ThreadHandle_decref(handle);
363
364 // bpo-44434: Don't call explicitly PyThread_exit_thread(). On Linux with
365 // the glibc, pthread_exit() can abort the whole process if dlopen() fails
366 // to open the libgcc_s.so library (ex: EMFILE error).
367 return;
368 }
369
370 static int
force_done(ThreadHandle * handle)371 force_done(ThreadHandle *handle)
372 {
373 assert(get_thread_handle_state(handle) == THREAD_HANDLE_STARTING);
374 _PyEvent_Notify(&handle->thread_is_exiting);
375 set_thread_handle_state(handle, THREAD_HANDLE_DONE);
376 return 0;
377 }
378
379 static int
ThreadHandle_start(ThreadHandle * self,PyObject * func,PyObject * args,PyObject * kwargs)380 ThreadHandle_start(ThreadHandle *self, PyObject *func, PyObject *args,
381 PyObject *kwargs)
382 {
383 // Mark the handle as starting to prevent any other threads from doing so
384 PyMutex_Lock(&self->mutex);
385 if (self->state != THREAD_HANDLE_NOT_STARTED) {
386 PyMutex_Unlock(&self->mutex);
387 PyErr_SetString(ThreadError, "thread already started");
388 return -1;
389 }
390 self->state = THREAD_HANDLE_STARTING;
391 PyMutex_Unlock(&self->mutex);
392
393 // Do all the heavy lifting outside of the mutex. All other operations on
394 // the handle should fail since the handle is in the starting state.
395
396 // gh-109795: Use PyMem_RawMalloc() instead of PyMem_Malloc(),
397 // because it should be possible to call thread_bootstate_free()
398 // without holding the GIL.
399 struct bootstate *boot = PyMem_RawMalloc(sizeof(struct bootstate));
400 if (boot == NULL) {
401 PyErr_NoMemory();
402 goto start_failed;
403 }
404 PyInterpreterState *interp = _PyInterpreterState_GET();
405 boot->tstate = _PyThreadState_New(interp, _PyThreadState_WHENCE_THREADING);
406 if (boot->tstate == NULL) {
407 PyMem_RawFree(boot);
408 if (!PyErr_Occurred()) {
409 PyErr_NoMemory();
410 }
411 goto start_failed;
412 }
413 boot->func = Py_NewRef(func);
414 boot->args = Py_NewRef(args);
415 boot->kwargs = Py_XNewRef(kwargs);
416 boot->handle = self;
417 ThreadHandle_incref(self);
418 boot->handle_ready = (PyEvent){0};
419
420 PyThread_ident_t ident;
421 PyThread_handle_t os_handle;
422 if (PyThread_start_joinable_thread(thread_run, boot, &ident, &os_handle)) {
423 PyThreadState_Clear(boot->tstate);
424 PyThreadState_Delete(boot->tstate);
425 thread_bootstate_free(boot, 1);
426 PyErr_SetString(ThreadError, "can't start new thread");
427 goto start_failed;
428 }
429
430 // Mark the handle running
431 PyMutex_Lock(&self->mutex);
432 assert(self->state == THREAD_HANDLE_STARTING);
433 self->ident = ident;
434 self->has_os_handle = 1;
435 self->os_handle = os_handle;
436 self->state = THREAD_HANDLE_RUNNING;
437 PyMutex_Unlock(&self->mutex);
438
439 // Unblock the thread
440 _PyEvent_Notify(&boot->handle_ready);
441
442 return 0;
443
444 start_failed:
445 _PyOnceFlag_CallOnce(&self->once, (_Py_once_fn_t *)force_done, self);
446 return -1;
447 }
448
449 static int
join_thread(ThreadHandle * handle)450 join_thread(ThreadHandle *handle)
451 {
452 assert(get_thread_handle_state(handle) == THREAD_HANDLE_RUNNING);
453 PyThread_handle_t os_handle;
454 if (ThreadHandle_get_os_handle(handle, &os_handle)) {
455 int err = 0;
456 Py_BEGIN_ALLOW_THREADS
457 err = PyThread_join_thread(os_handle);
458 Py_END_ALLOW_THREADS
459 if (err) {
460 PyErr_SetString(ThreadError, "Failed joining thread");
461 return -1;
462 }
463 }
464 set_thread_handle_state(handle, THREAD_HANDLE_DONE);
465 return 0;
466 }
467
468 static int
check_started(ThreadHandle * self)469 check_started(ThreadHandle *self)
470 {
471 ThreadHandleState state = get_thread_handle_state(self);
472 if (state < THREAD_HANDLE_RUNNING) {
473 PyErr_SetString(ThreadError, "thread not started");
474 return -1;
475 }
476 return 0;
477 }
478
479 static int
ThreadHandle_join(ThreadHandle * self,PyTime_t timeout_ns)480 ThreadHandle_join(ThreadHandle *self, PyTime_t timeout_ns)
481 {
482 if (check_started(self) < 0) {
483 return -1;
484 }
485
486 // We want to perform this check outside of the `_PyOnceFlag` to prevent
487 // deadlock in the scenario where another thread joins us and we then
488 // attempt to join ourselves. However, it's not safe to check thread
489 // identity once the handle's os thread has finished. We may end up reusing
490 // the identity stored in the handle and erroneously think we are
491 // attempting to join ourselves.
492 //
493 // To work around this, we set `thread_is_exiting` immediately before
494 // `thread_run` returns. We can be sure that we are not attempting to join
495 // ourselves if the handle's thread is about to exit.
496 if (!_PyEvent_IsSet(&self->thread_is_exiting) &&
497 ThreadHandle_ident(self) == PyThread_get_thread_ident_ex()) {
498 // PyThread_join_thread() would deadlock or error out.
499 PyErr_SetString(ThreadError, "Cannot join current thread");
500 return -1;
501 }
502
503 // Wait until the deadline for the thread to exit.
504 PyTime_t deadline = timeout_ns != -1 ? _PyDeadline_Init(timeout_ns) : 0;
505 int detach = 1;
506 while (!PyEvent_WaitTimed(&self->thread_is_exiting, timeout_ns, detach)) {
507 if (deadline) {
508 // _PyDeadline_Get will return a negative value if the deadline has
509 // been exceeded.
510 timeout_ns = Py_MAX(_PyDeadline_Get(deadline), 0);
511 }
512
513 if (timeout_ns) {
514 // Interrupted
515 if (Py_MakePendingCalls() < 0) {
516 return -1;
517 }
518 }
519 else {
520 // Timed out
521 return 0;
522 }
523 }
524
525 if (_PyOnceFlag_CallOnce(&self->once, (_Py_once_fn_t *)join_thread,
526 self) == -1) {
527 return -1;
528 }
529 assert(get_thread_handle_state(self) == THREAD_HANDLE_DONE);
530 return 0;
531 }
532
533 static int
set_done(ThreadHandle * handle)534 set_done(ThreadHandle *handle)
535 {
536 assert(get_thread_handle_state(handle) == THREAD_HANDLE_RUNNING);
537 if (detach_thread(handle) < 0) {
538 PyErr_SetString(ThreadError, "failed detaching handle");
539 return -1;
540 }
541 _PyEvent_Notify(&handle->thread_is_exiting);
542 set_thread_handle_state(handle, THREAD_HANDLE_DONE);
543 return 0;
544 }
545
546 static int
ThreadHandle_set_done(ThreadHandle * self)547 ThreadHandle_set_done(ThreadHandle *self)
548 {
549 if (check_started(self) < 0) {
550 return -1;
551 }
552
553 if (_PyOnceFlag_CallOnce(&self->once, (_Py_once_fn_t *)set_done, self) ==
554 -1) {
555 return -1;
556 }
557 assert(get_thread_handle_state(self) == THREAD_HANDLE_DONE);
558 return 0;
559 }
560
561 // A wrapper around a ThreadHandle.
562 typedef struct {
563 PyObject_HEAD
564
565 ThreadHandle *handle;
566 } PyThreadHandleObject;
567
568 static PyThreadHandleObject *
PyThreadHandleObject_new(PyTypeObject * type)569 PyThreadHandleObject_new(PyTypeObject *type)
570 {
571 ThreadHandle *handle = ThreadHandle_new();
572 if (handle == NULL) {
573 return NULL;
574 }
575
576 PyThreadHandleObject *self =
577 (PyThreadHandleObject *)type->tp_alloc(type, 0);
578 if (self == NULL) {
579 ThreadHandle_decref(handle);
580 return NULL;
581 }
582
583 self->handle = handle;
584
585 return self;
586 }
587
588 static PyObject *
PyThreadHandleObject_tp_new(PyTypeObject * type,PyObject * args,PyObject * kwds)589 PyThreadHandleObject_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
590 {
591 return (PyObject *)PyThreadHandleObject_new(type);
592 }
593
594 static int
PyThreadHandleObject_traverse(PyThreadHandleObject * self,visitproc visit,void * arg)595 PyThreadHandleObject_traverse(PyThreadHandleObject *self, visitproc visit,
596 void *arg)
597 {
598 Py_VISIT(Py_TYPE(self));
599 return 0;
600 }
601
602 static void
PyThreadHandleObject_dealloc(PyThreadHandleObject * self)603 PyThreadHandleObject_dealloc(PyThreadHandleObject *self)
604 {
605 PyObject_GC_UnTrack(self);
606 PyTypeObject *tp = Py_TYPE(self);
607 ThreadHandle_decref(self->handle);
608 tp->tp_free(self);
609 Py_DECREF(tp);
610 }
611
612 static PyObject *
PyThreadHandleObject_repr(PyThreadHandleObject * self)613 PyThreadHandleObject_repr(PyThreadHandleObject *self)
614 {
615 PyThread_ident_t ident = ThreadHandle_ident(self->handle);
616 return PyUnicode_FromFormat("<%s object: ident=%" PY_FORMAT_THREAD_IDENT_T ">",
617 Py_TYPE(self)->tp_name, ident);
618 }
619
620 static PyObject *
PyThreadHandleObject_get_ident(PyThreadHandleObject * self,PyObject * Py_UNUSED (ignored))621 PyThreadHandleObject_get_ident(PyThreadHandleObject *self,
622 PyObject *Py_UNUSED(ignored))
623 {
624 return PyLong_FromUnsignedLongLong(ThreadHandle_ident(self->handle));
625 }
626
627 static PyObject *
PyThreadHandleObject_join(PyThreadHandleObject * self,PyObject * args)628 PyThreadHandleObject_join(PyThreadHandleObject *self, PyObject *args)
629 {
630 PyObject *timeout_obj = NULL;
631 if (!PyArg_ParseTuple(args, "|O:join", &timeout_obj)) {
632 return NULL;
633 }
634
635 PyTime_t timeout_ns = -1;
636 if (timeout_obj != NULL && timeout_obj != Py_None) {
637 if (_PyTime_FromSecondsObject(&timeout_ns, timeout_obj,
638 _PyTime_ROUND_TIMEOUT) < 0) {
639 return NULL;
640 }
641 }
642
643 if (ThreadHandle_join(self->handle, timeout_ns) < 0) {
644 return NULL;
645 }
646 Py_RETURN_NONE;
647 }
648
649 static PyObject *
PyThreadHandleObject_is_done(PyThreadHandleObject * self,PyObject * Py_UNUSED (ignored))650 PyThreadHandleObject_is_done(PyThreadHandleObject *self,
651 PyObject *Py_UNUSED(ignored))
652 {
653 if (_PyEvent_IsSet(&self->handle->thread_is_exiting)) {
654 Py_RETURN_TRUE;
655 }
656 else {
657 Py_RETURN_FALSE;
658 }
659 }
660
661 static PyObject *
PyThreadHandleObject_set_done(PyThreadHandleObject * self,PyObject * Py_UNUSED (ignored))662 PyThreadHandleObject_set_done(PyThreadHandleObject *self,
663 PyObject *Py_UNUSED(ignored))
664 {
665 if (ThreadHandle_set_done(self->handle) < 0) {
666 return NULL;
667 }
668 Py_RETURN_NONE;
669 }
670
671 static PyGetSetDef ThreadHandle_getsetlist[] = {
672 {"ident", (getter)PyThreadHandleObject_get_ident, NULL, NULL},
673 {0},
674 };
675
676 static PyMethodDef ThreadHandle_methods[] = {
677 {"join", (PyCFunction)PyThreadHandleObject_join, METH_VARARGS, NULL},
678 {"_set_done", (PyCFunction)PyThreadHandleObject_set_done, METH_NOARGS, NULL},
679 {"is_done", (PyCFunction)PyThreadHandleObject_is_done, METH_NOARGS, NULL},
680 {0, 0}
681 };
682
683 static PyType_Slot ThreadHandle_Type_slots[] = {
684 {Py_tp_dealloc, (destructor)PyThreadHandleObject_dealloc},
685 {Py_tp_repr, (reprfunc)PyThreadHandleObject_repr},
686 {Py_tp_getset, ThreadHandle_getsetlist},
687 {Py_tp_traverse, PyThreadHandleObject_traverse},
688 {Py_tp_methods, ThreadHandle_methods},
689 {Py_tp_new, PyThreadHandleObject_tp_new},
690 {0, 0}
691 };
692
693 static PyType_Spec ThreadHandle_Type_spec = {
694 "_thread._ThreadHandle",
695 sizeof(PyThreadHandleObject),
696 0,
697 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC,
698 ThreadHandle_Type_slots,
699 };
700
701 /* Lock objects */
702
703 typedef struct {
704 PyObject_HEAD
705 PyMutex lock;
706 } lockobject;
707
708 static int
lock_traverse(lockobject * self,visitproc visit,void * arg)709 lock_traverse(lockobject *self, visitproc visit, void *arg)
710 {
711 Py_VISIT(Py_TYPE(self));
712 return 0;
713 }
714
715 static void
lock_dealloc(lockobject * self)716 lock_dealloc(lockobject *self)
717 {
718 PyObject_GC_UnTrack(self);
719 PyObject_ClearWeakRefs((PyObject *) self);
720 PyTypeObject *tp = Py_TYPE(self);
721 tp->tp_free((PyObject*)self);
722 Py_DECREF(tp);
723 }
724
725 static inline PyLockStatus
acquire_timed(PyThread_type_lock lock,PyTime_t timeout)726 acquire_timed(PyThread_type_lock lock, PyTime_t timeout)
727 {
728 return PyThread_acquire_lock_timed_with_retries(lock, timeout);
729 }
730
731 static int
lock_acquire_parse_args(PyObject * args,PyObject * kwds,PyTime_t * timeout)732 lock_acquire_parse_args(PyObject *args, PyObject *kwds,
733 PyTime_t *timeout)
734 {
735 char *kwlist[] = {"blocking", "timeout", NULL};
736 int blocking = 1;
737 PyObject *timeout_obj = NULL;
738 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|pO:acquire", kwlist,
739 &blocking, &timeout_obj))
740 return -1;
741
742 // XXX Use PyThread_ParseTimeoutArg().
743
744 const PyTime_t unset_timeout = _PyTime_FromSeconds(-1);
745 *timeout = unset_timeout;
746
747 if (timeout_obj
748 && _PyTime_FromSecondsObject(timeout,
749 timeout_obj, _PyTime_ROUND_TIMEOUT) < 0)
750 return -1;
751
752 if (!blocking && *timeout != unset_timeout ) {
753 PyErr_SetString(PyExc_ValueError,
754 "can't specify a timeout for a non-blocking call");
755 return -1;
756 }
757 if (*timeout < 0 && *timeout != unset_timeout) {
758 PyErr_SetString(PyExc_ValueError,
759 "timeout value must be a non-negative number");
760 return -1;
761 }
762 if (!blocking)
763 *timeout = 0;
764 else if (*timeout != unset_timeout) {
765 PyTime_t microseconds;
766
767 microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_TIMEOUT);
768 if (microseconds > PY_TIMEOUT_MAX) {
769 PyErr_SetString(PyExc_OverflowError,
770 "timeout value is too large");
771 return -1;
772 }
773 }
774 return 0;
775 }
776
777 static PyObject *
lock_PyThread_acquire_lock(lockobject * self,PyObject * args,PyObject * kwds)778 lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
779 {
780 PyTime_t timeout;
781 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
782 return NULL;
783
784 PyLockStatus r = _PyMutex_LockTimed(&self->lock, timeout,
785 _PY_LOCK_HANDLE_SIGNALS | _PY_LOCK_DETACH);
786 if (r == PY_LOCK_INTR) {
787 return NULL;
788 }
789
790 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
791 }
792
793 PyDoc_STRVAR(acquire_doc,
794 "acquire($self, /, blocking=True, timeout=-1)\n\
795 --\n\
796 \n\
797 Lock the lock. Without argument, this blocks if the lock is already\n\
798 locked (even by the same thread), waiting for another thread to release\n\
799 the lock, and return True once the lock is acquired.\n\
800 With an argument, this will only block if the argument is true,\n\
801 and the return value reflects whether the lock is acquired.\n\
802 The blocking operation is interruptible.");
803
804 PyDoc_STRVAR(acquire_lock_doc,
805 "acquire_lock($self, /, blocking=True, timeout=-1)\n\
806 --\n\
807 \n\
808 An obsolete synonym of acquire().");
809
810 PyDoc_STRVAR(enter_doc,
811 "__enter__($self, /)\n\
812 --\n\
813 \n\
814 Lock the lock.");
815
816 static PyObject *
lock_PyThread_release_lock(lockobject * self,PyObject * Py_UNUSED (ignored))817 lock_PyThread_release_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
818 {
819 /* Sanity check: the lock must be locked */
820 if (_PyMutex_TryUnlock(&self->lock) < 0) {
821 PyErr_SetString(ThreadError, "release unlocked lock");
822 return NULL;
823 }
824
825 Py_RETURN_NONE;
826 }
827
828 PyDoc_STRVAR(release_doc,
829 "release($self, /)\n\
830 --\n\
831 \n\
832 Release the lock, allowing another thread that is blocked waiting for\n\
833 the lock to acquire the lock. The lock must be in the locked state,\n\
834 but it needn't be locked by the same thread that unlocks it.");
835
836 PyDoc_STRVAR(release_lock_doc,
837 "release_lock($self, /)\n\
838 --\n\
839 \n\
840 An obsolete synonym of release().");
841
842 PyDoc_STRVAR(lock_exit_doc,
843 "__exit__($self, /, *exc_info)\n\
844 --\n\
845 \n\
846 Release the lock.");
847
848 static PyObject *
lock_locked_lock(lockobject * self,PyObject * Py_UNUSED (ignored))849 lock_locked_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
850 {
851 return PyBool_FromLong(PyMutex_IsLocked(&self->lock));
852 }
853
854 PyDoc_STRVAR(locked_doc,
855 "locked($self, /)\n\
856 --\n\
857 \n\
858 Return whether the lock is in the locked state.");
859
860 PyDoc_STRVAR(locked_lock_doc,
861 "locked_lock($self, /)\n\
862 --\n\
863 \n\
864 An obsolete synonym of locked().");
865
866 static PyObject *
lock_repr(lockobject * self)867 lock_repr(lockobject *self)
868 {
869 return PyUnicode_FromFormat("<%s %s object at %p>",
870 PyMutex_IsLocked(&self->lock) ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
871 }
872
873 #ifdef HAVE_FORK
874 static PyObject *
lock__at_fork_reinit(lockobject * self,PyObject * Py_UNUSED (args))875 lock__at_fork_reinit(lockobject *self, PyObject *Py_UNUSED(args))
876 {
877 _PyMutex_at_fork_reinit(&self->lock);
878 Py_RETURN_NONE;
879 }
880 #endif /* HAVE_FORK */
881
882 static lockobject *newlockobject(PyObject *module);
883
884 static PyObject *
lock_new(PyTypeObject * type,PyObject * args,PyObject * kwargs)885 lock_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
886 {
887 // convert to AC?
888 if (!_PyArg_NoKeywords("lock", kwargs)) {
889 goto error;
890 }
891 if (!_PyArg_CheckPositional("lock", PyTuple_GET_SIZE(args), 0, 0)) {
892 goto error;
893 }
894
895 PyObject *module = PyType_GetModuleByDef(type, &thread_module);
896 assert(module != NULL);
897 return (PyObject *)newlockobject(module);
898
899 error:
900 return NULL;
901 }
902
903
904 static PyMethodDef lock_methods[] = {
905 {"acquire_lock", _PyCFunction_CAST(lock_PyThread_acquire_lock),
906 METH_VARARGS | METH_KEYWORDS, acquire_lock_doc},
907 {"acquire", _PyCFunction_CAST(lock_PyThread_acquire_lock),
908 METH_VARARGS | METH_KEYWORDS, acquire_doc},
909 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
910 METH_NOARGS, release_lock_doc},
911 {"release", (PyCFunction)lock_PyThread_release_lock,
912 METH_NOARGS, release_doc},
913 {"locked_lock", (PyCFunction)lock_locked_lock,
914 METH_NOARGS, locked_lock_doc},
915 {"locked", (PyCFunction)lock_locked_lock,
916 METH_NOARGS, locked_doc},
917 {"__enter__", _PyCFunction_CAST(lock_PyThread_acquire_lock),
918 METH_VARARGS | METH_KEYWORDS, enter_doc},
919 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
920 METH_VARARGS, lock_exit_doc},
921 #ifdef HAVE_FORK
922 {"_at_fork_reinit", (PyCFunction)lock__at_fork_reinit,
923 METH_NOARGS, NULL},
924 #endif
925 {NULL, NULL} /* sentinel */
926 };
927
928 PyDoc_STRVAR(lock_doc,
929 "lock()\n\
930 --\n\
931 \n\
932 A lock object is a synchronization primitive. To create a lock,\n\
933 call threading.Lock(). Methods are:\n\
934 \n\
935 acquire() -- lock the lock, possibly blocking until it can be obtained\n\
936 release() -- unlock of the lock\n\
937 locked() -- test whether the lock is currently locked\n\
938 \n\
939 A lock is not owned by the thread that locked it; another thread may\n\
940 unlock it. A thread attempting to lock a lock that it has already locked\n\
941 will block until another thread unlocks it. Deadlocks may ensue.");
942
943 static PyType_Slot lock_type_slots[] = {
944 {Py_tp_dealloc, (destructor)lock_dealloc},
945 {Py_tp_repr, (reprfunc)lock_repr},
946 {Py_tp_doc, (void *)lock_doc},
947 {Py_tp_methods, lock_methods},
948 {Py_tp_traverse, lock_traverse},
949 {Py_tp_new, lock_new},
950 {0, 0}
951 };
952
953 static PyType_Spec lock_type_spec = {
954 .name = "_thread.lock",
955 .basicsize = sizeof(lockobject),
956 .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
957 Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_MANAGED_WEAKREF),
958 .slots = lock_type_slots,
959 };
960
961 /* Recursive lock objects */
962
963 typedef struct {
964 PyObject_HEAD
965 PyThread_type_lock rlock_lock;
966 PyThread_ident_t rlock_owner;
967 unsigned long rlock_count;
968 PyObject *in_weakreflist;
969 } rlockobject;
970
971 static int
rlock_traverse(rlockobject * self,visitproc visit,void * arg)972 rlock_traverse(rlockobject *self, visitproc visit, void *arg)
973 {
974 Py_VISIT(Py_TYPE(self));
975 return 0;
976 }
977
978
979 static void
rlock_dealloc(rlockobject * self)980 rlock_dealloc(rlockobject *self)
981 {
982 PyObject_GC_UnTrack(self);
983 if (self->in_weakreflist != NULL)
984 PyObject_ClearWeakRefs((PyObject *) self);
985 /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed
986 in rlock_new() */
987 if (self->rlock_lock != NULL) {
988 /* Unlock the lock so it's safe to free it */
989 if (self->rlock_count > 0)
990 PyThread_release_lock(self->rlock_lock);
991
992 PyThread_free_lock(self->rlock_lock);
993 }
994 PyTypeObject *tp = Py_TYPE(self);
995 tp->tp_free(self);
996 Py_DECREF(tp);
997 }
998
999 static bool
rlock_is_owned_by(rlockobject * self,PyThread_ident_t tid)1000 rlock_is_owned_by(rlockobject *self, PyThread_ident_t tid)
1001 {
1002 PyThread_ident_t owner_tid =
1003 _Py_atomic_load_ullong_relaxed(&self->rlock_owner);
1004 return owner_tid == tid && self->rlock_count > 0;
1005 }
1006
1007 static PyObject *
rlock_acquire(rlockobject * self,PyObject * args,PyObject * kwds)1008 rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
1009 {
1010 PyTime_t timeout;
1011 PyThread_ident_t tid;
1012 PyLockStatus r = PY_LOCK_ACQUIRED;
1013
1014 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
1015 return NULL;
1016
1017 tid = PyThread_get_thread_ident_ex();
1018 if (rlock_is_owned_by(self, tid)) {
1019 unsigned long count = self->rlock_count + 1;
1020 if (count <= self->rlock_count) {
1021 PyErr_SetString(PyExc_OverflowError,
1022 "Internal lock count overflowed");
1023 return NULL;
1024 }
1025 self->rlock_count = count;
1026 Py_RETURN_TRUE;
1027 }
1028 r = acquire_timed(self->rlock_lock, timeout);
1029 if (r == PY_LOCK_ACQUIRED) {
1030 assert(self->rlock_count == 0);
1031 _Py_atomic_store_ullong_relaxed(&self->rlock_owner, tid);
1032 self->rlock_count = 1;
1033 }
1034 else if (r == PY_LOCK_INTR) {
1035 return NULL;
1036 }
1037
1038 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
1039 }
1040
1041 PyDoc_STRVAR(rlock_acquire_doc,
1042 "acquire($self, /, blocking=True, timeout=-1)\n\
1043 --\n\
1044 \n\
1045 Lock the lock. `blocking` indicates whether we should wait\n\
1046 for the lock to be available or not. If `blocking` is False\n\
1047 and another thread holds the lock, the method will return False\n\
1048 immediately. If `blocking` is True and another thread holds\n\
1049 the lock, the method will wait for the lock to be released,\n\
1050 take it and then return True.\n\
1051 (note: the blocking operation is interruptible.)\n\
1052 \n\
1053 In all other cases, the method will return True immediately.\n\
1054 Precisely, if the current thread already holds the lock, its\n\
1055 internal counter is simply incremented. If nobody holds the lock,\n\
1056 the lock is taken and its internal counter initialized to 1.");
1057
1058 PyDoc_STRVAR(rlock_enter_doc,
1059 "__enter__($self, /)\n\
1060 --\n\
1061 \n\
1062 Lock the lock.");
1063
1064 static PyObject *
rlock_release(rlockobject * self,PyObject * Py_UNUSED (ignored))1065 rlock_release(rlockobject *self, PyObject *Py_UNUSED(ignored))
1066 {
1067 PyThread_ident_t tid = PyThread_get_thread_ident_ex();
1068
1069 if (!rlock_is_owned_by(self, tid)) {
1070 PyErr_SetString(PyExc_RuntimeError,
1071 "cannot release un-acquired lock");
1072 return NULL;
1073 }
1074 if (--self->rlock_count == 0) {
1075 _Py_atomic_store_ullong_relaxed(&self->rlock_owner, 0);
1076 PyThread_release_lock(self->rlock_lock);
1077 }
1078 Py_RETURN_NONE;
1079 }
1080
1081 PyDoc_STRVAR(rlock_release_doc,
1082 "release($self, /)\n\
1083 --\n\
1084 \n\
1085 Release the lock, allowing another thread that is blocked waiting for\n\
1086 the lock to acquire the lock. The lock must be in the locked state,\n\
1087 and must be locked by the same thread that unlocks it; otherwise a\n\
1088 `RuntimeError` is raised.\n\
1089 \n\
1090 Do note that if the lock was acquire()d several times in a row by the\n\
1091 current thread, release() needs to be called as many times for the lock\n\
1092 to be available for other threads.");
1093
1094 PyDoc_STRVAR(rlock_exit_doc,
1095 "__exit__($self, /, *exc_info)\n\
1096 --\n\
1097 \n\
1098 Release the lock.");
1099
1100 static PyObject *
rlock_acquire_restore(rlockobject * self,PyObject * args)1101 rlock_acquire_restore(rlockobject *self, PyObject *args)
1102 {
1103 PyThread_ident_t owner;
1104 unsigned long count;
1105 int r = 1;
1106
1107 if (!PyArg_ParseTuple(args, "(k" Py_PARSE_THREAD_IDENT_T "):_acquire_restore",
1108 &count, &owner))
1109 return NULL;
1110
1111 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
1112 Py_BEGIN_ALLOW_THREADS
1113 r = PyThread_acquire_lock(self->rlock_lock, 1);
1114 Py_END_ALLOW_THREADS
1115 }
1116 if (!r) {
1117 PyErr_SetString(ThreadError, "couldn't acquire lock");
1118 return NULL;
1119 }
1120 assert(self->rlock_count == 0);
1121 _Py_atomic_store_ullong_relaxed(&self->rlock_owner, owner);
1122 self->rlock_count = count;
1123 Py_RETURN_NONE;
1124 }
1125
1126 PyDoc_STRVAR(rlock_acquire_restore_doc,
1127 "_acquire_restore($self, state, /)\n\
1128 --\n\
1129 \n\
1130 For internal use by `threading.Condition`.");
1131
1132 static PyObject *
rlock_release_save(rlockobject * self,PyObject * Py_UNUSED (ignored))1133 rlock_release_save(rlockobject *self, PyObject *Py_UNUSED(ignored))
1134 {
1135 PyThread_ident_t owner;
1136 unsigned long count;
1137
1138 if (self->rlock_count == 0) {
1139 PyErr_SetString(PyExc_RuntimeError,
1140 "cannot release un-acquired lock");
1141 return NULL;
1142 }
1143
1144 owner = self->rlock_owner;
1145 count = self->rlock_count;
1146 self->rlock_count = 0;
1147 _Py_atomic_store_ullong_relaxed(&self->rlock_owner, 0);
1148 PyThread_release_lock(self->rlock_lock);
1149 return Py_BuildValue("k" Py_PARSE_THREAD_IDENT_T, count, owner);
1150 }
1151
1152 PyDoc_STRVAR(rlock_release_save_doc,
1153 "_release_save($self, /)\n\
1154 --\n\
1155 \n\
1156 For internal use by `threading.Condition`.");
1157
1158 static PyObject *
rlock_recursion_count(rlockobject * self,PyObject * Py_UNUSED (ignored))1159 rlock_recursion_count(rlockobject *self, PyObject *Py_UNUSED(ignored))
1160 {
1161 PyThread_ident_t tid = PyThread_get_thread_ident_ex();
1162 PyThread_ident_t owner =
1163 _Py_atomic_load_ullong_relaxed(&self->rlock_owner);
1164 return PyLong_FromUnsignedLong(owner == tid ? self->rlock_count : 0UL);
1165 }
1166
1167 PyDoc_STRVAR(rlock_recursion_count_doc,
1168 "_recursion_count($self, /)\n\
1169 --\n\
1170 \n\
1171 For internal use by reentrancy checks.");
1172
1173 static PyObject *
rlock_is_owned(rlockobject * self,PyObject * Py_UNUSED (ignored))1174 rlock_is_owned(rlockobject *self, PyObject *Py_UNUSED(ignored))
1175 {
1176 PyThread_ident_t tid = PyThread_get_thread_ident_ex();
1177
1178 if (rlock_is_owned_by(self, tid)) {
1179 Py_RETURN_TRUE;
1180 }
1181 Py_RETURN_FALSE;
1182 }
1183
1184 PyDoc_STRVAR(rlock_is_owned_doc,
1185 "_is_owned($self, /)\n\
1186 --\n\
1187 \n\
1188 For internal use by `threading.Condition`.");
1189
1190 static PyObject *
rlock_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1191 rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1192 {
1193 rlockobject *self = (rlockobject *) type->tp_alloc(type, 0);
1194 if (self == NULL) {
1195 return NULL;
1196 }
1197 self->in_weakreflist = NULL;
1198 self->rlock_owner = 0;
1199 self->rlock_count = 0;
1200
1201 self->rlock_lock = PyThread_allocate_lock();
1202 if (self->rlock_lock == NULL) {
1203 Py_DECREF(self);
1204 PyErr_SetString(ThreadError, "can't allocate lock");
1205 return NULL;
1206 }
1207 return (PyObject *) self;
1208 }
1209
1210 static PyObject *
rlock_repr(rlockobject * self)1211 rlock_repr(rlockobject *self)
1212 {
1213 PyThread_ident_t owner =
1214 _Py_atomic_load_ullong_relaxed(&self->rlock_owner);
1215 return PyUnicode_FromFormat(
1216 "<%s %s object owner=%" PY_FORMAT_THREAD_IDENT_T " count=%lu at %p>",
1217 self->rlock_count ? "locked" : "unlocked",
1218 Py_TYPE(self)->tp_name, owner,
1219 self->rlock_count, self);
1220 }
1221
1222
1223 #ifdef HAVE_FORK
1224 static PyObject *
rlock__at_fork_reinit(rlockobject * self,PyObject * Py_UNUSED (args))1225 rlock__at_fork_reinit(rlockobject *self, PyObject *Py_UNUSED(args))
1226 {
1227 if (_PyThread_at_fork_reinit(&self->rlock_lock) < 0) {
1228 PyErr_SetString(ThreadError, "failed to reinitialize lock at fork");
1229 return NULL;
1230 }
1231
1232 self->rlock_owner = 0;
1233 self->rlock_count = 0;
1234
1235 Py_RETURN_NONE;
1236 }
1237 #endif /* HAVE_FORK */
1238
1239
1240 static PyMethodDef rlock_methods[] = {
1241 {"acquire", _PyCFunction_CAST(rlock_acquire),
1242 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
1243 {"release", (PyCFunction)rlock_release,
1244 METH_NOARGS, rlock_release_doc},
1245 {"_is_owned", (PyCFunction)rlock_is_owned,
1246 METH_NOARGS, rlock_is_owned_doc},
1247 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
1248 METH_VARARGS, rlock_acquire_restore_doc},
1249 {"_release_save", (PyCFunction)rlock_release_save,
1250 METH_NOARGS, rlock_release_save_doc},
1251 {"_recursion_count", (PyCFunction)rlock_recursion_count,
1252 METH_NOARGS, rlock_recursion_count_doc},
1253 {"__enter__", _PyCFunction_CAST(rlock_acquire),
1254 METH_VARARGS | METH_KEYWORDS, rlock_enter_doc},
1255 {"__exit__", (PyCFunction)rlock_release,
1256 METH_VARARGS, rlock_exit_doc},
1257 #ifdef HAVE_FORK
1258 {"_at_fork_reinit", (PyCFunction)rlock__at_fork_reinit,
1259 METH_NOARGS, NULL},
1260 #endif
1261 {NULL, NULL} /* sentinel */
1262 };
1263
1264
1265 static PyMemberDef rlock_type_members[] = {
1266 {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(rlockobject, in_weakreflist), Py_READONLY},
1267 {NULL},
1268 };
1269
1270 static PyType_Slot rlock_type_slots[] = {
1271 {Py_tp_dealloc, (destructor)rlock_dealloc},
1272 {Py_tp_repr, (reprfunc)rlock_repr},
1273 {Py_tp_methods, rlock_methods},
1274 {Py_tp_alloc, PyType_GenericAlloc},
1275 {Py_tp_new, rlock_new},
1276 {Py_tp_members, rlock_type_members},
1277 {Py_tp_traverse, rlock_traverse},
1278 {0, 0},
1279 };
1280
1281 static PyType_Spec rlock_type_spec = {
1282 .name = "_thread.RLock",
1283 .basicsize = sizeof(rlockobject),
1284 .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1285 Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE),
1286 .slots = rlock_type_slots,
1287 };
1288
1289 static lockobject *
newlockobject(PyObject * module)1290 newlockobject(PyObject *module)
1291 {
1292 thread_module_state *state = get_thread_state(module);
1293
1294 PyTypeObject *type = state->lock_type;
1295 lockobject *self = (lockobject *)type->tp_alloc(type, 0);
1296 if (self == NULL) {
1297 return NULL;
1298 }
1299 self->lock = (PyMutex){0};
1300 return self;
1301 }
1302
1303 /* Thread-local objects */
1304
1305 /* Quick overview:
1306
1307 We need to be able to reclaim reference cycles as soon as possible
1308 (both when a thread is being terminated, or a thread-local object
1309 becomes unreachable from user data). Constraints:
1310 - it must not be possible for thread-state dicts to be involved in
1311 reference cycles (otherwise the cyclic GC will refuse to consider
1312 objects referenced from a reachable thread-state dict, even though
1313 local_dealloc would clear them)
1314 - the death of a thread-state dict must still imply destruction of the
1315 corresponding local dicts in all thread-local objects.
1316
1317 Our implementation uses small "localdummy" objects in order to break
1318 the reference chain. These trivial objects are hashable (using the
1319 default scheme of identity hashing) and weakrefable.
1320
1321 Each thread-state holds two separate localdummy objects:
1322
1323 - `threading_local_key` is used as a key to retrieve the locals dictionary
1324 for the thread in any `threading.local` object.
1325 - `threading_local_sentinel` is used to signal when a thread is being
1326 destroyed. Consequently, the associated thread-state must hold the only
1327 reference.
1328
1329 Each `threading.local` object contains a dict mapping localdummy keys to
1330 locals dicts and a set containing weak references to localdummy
1331 sentinels. Each sentinel weak reference has a callback that removes itself
1332 and the locals dict for the key from the `threading.local` object when
1333 called.
1334
1335 Therefore:
1336 - The thread-state only holds strong references to localdummy objects, which
1337 cannot participate in cycles.
1338 - Only outside objects (application- or library-level) hold strong
1339 references to the thread-local objects.
1340 - As soon as thread-state's sentinel dummy is destroyed the callbacks for
1341 all weakrefs attached to the sentinel are called, and destroy the
1342 corresponding local dicts from thread-local objects.
1343 - As soon as a thread-local object is destroyed, its local dicts are
1344 destroyed.
1345 - The GC can do its work correctly when a thread-local object is dangling,
1346 without any interference from the thread-state dicts.
1347
1348 This dual key arrangement is necessary to ensure that `threading.local`
1349 values can be retrieved from finalizers. If we were to only keep a mapping
1350 of localdummy weakrefs to locals dicts it's possible that the weakrefs would
1351 be cleared before finalizers were called (GC currently clears weakrefs that
1352 are garbage before invoking finalizers), causing lookups in finalizers to
1353 fail.
1354 */
1355
1356 typedef struct {
1357 PyObject_HEAD
1358 PyObject *weakreflist; /* List of weak references to self */
1359 } localdummyobject;
1360
1361 static void
localdummy_dealloc(localdummyobject * self)1362 localdummy_dealloc(localdummyobject *self)
1363 {
1364 if (self->weakreflist != NULL)
1365 PyObject_ClearWeakRefs((PyObject *) self);
1366 PyTypeObject *tp = Py_TYPE(self);
1367 tp->tp_free((PyObject*)self);
1368 Py_DECREF(tp);
1369 }
1370
1371 static PyMemberDef local_dummy_type_members[] = {
1372 {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(localdummyobject, weakreflist), Py_READONLY},
1373 {NULL},
1374 };
1375
1376 static PyType_Slot local_dummy_type_slots[] = {
1377 {Py_tp_dealloc, (destructor)localdummy_dealloc},
1378 {Py_tp_doc, "Thread-local dummy"},
1379 {Py_tp_members, local_dummy_type_members},
1380 {0, 0}
1381 };
1382
1383 static PyType_Spec local_dummy_type_spec = {
1384 .name = "_thread._localdummy",
1385 .basicsize = sizeof(localdummyobject),
1386 .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
1387 Py_TPFLAGS_IMMUTABLETYPE),
1388 .slots = local_dummy_type_slots,
1389 };
1390
1391
1392 typedef struct {
1393 PyObject_HEAD
1394 PyObject *args;
1395 PyObject *kw;
1396 PyObject *weakreflist; /* List of weak references to self */
1397 /* A {localdummy -> localdict} dict */
1398 PyObject *localdicts;
1399 /* A set of weakrefs to thread sentinels localdummies*/
1400 PyObject *thread_watchdogs;
1401 } localobject;
1402
1403 /* Forward declaration */
1404 static int create_localsdict(localobject *self, thread_module_state *state,
1405 PyObject **localsdict, PyObject **sentinel_wr);
1406 static PyObject *clear_locals(PyObject *meth_self, PyObject *dummyweakref);
1407
1408 /* Create a weakref to the sentinel localdummy for the current thread */
1409 static PyObject *
create_sentinel_wr(localobject * self)1410 create_sentinel_wr(localobject *self)
1411 {
1412 static PyMethodDef wr_callback_def = {
1413 "clear_locals", (PyCFunction) clear_locals, METH_O
1414 };
1415
1416 PyThreadState *tstate = PyThreadState_Get();
1417
1418 /* We use a weak reference to self in the callback closure
1419 in order to avoid spurious reference cycles */
1420 PyObject *self_wr = PyWeakref_NewRef((PyObject *) self, NULL);
1421 if (self_wr == NULL) {
1422 return NULL;
1423 }
1424
1425 PyObject *args = PyTuple_New(2);
1426 if (args == NULL) {
1427 Py_DECREF(self_wr);
1428 return NULL;
1429 }
1430 PyTuple_SET_ITEM(args, 0, self_wr);
1431 PyTuple_SET_ITEM(args, 1, Py_NewRef(tstate->threading_local_key));
1432
1433 PyObject *cb = PyCFunction_New(&wr_callback_def, args);
1434 Py_DECREF(args);
1435 if (cb == NULL) {
1436 return NULL;
1437 }
1438
1439 PyObject *wr = PyWeakref_NewRef(tstate->threading_local_sentinel, cb);
1440 Py_DECREF(cb);
1441
1442 return wr;
1443 }
1444
1445 static PyObject *
local_new(PyTypeObject * type,PyObject * args,PyObject * kw)1446 local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1447 {
1448 if (type->tp_init == PyBaseObject_Type.tp_init) {
1449 int rc = 0;
1450 if (args != NULL)
1451 rc = PyObject_IsTrue(args);
1452 if (rc == 0 && kw != NULL)
1453 rc = PyObject_IsTrue(kw);
1454 if (rc != 0) {
1455 if (rc > 0) {
1456 PyErr_SetString(PyExc_TypeError,
1457 "Initialization arguments are not supported");
1458 }
1459 return NULL;
1460 }
1461 }
1462
1463 PyObject *module = PyType_GetModuleByDef(type, &thread_module);
1464 assert(module != NULL);
1465 thread_module_state *state = get_thread_state(module);
1466
1467 localobject *self = (localobject *)type->tp_alloc(type, 0);
1468 if (self == NULL) {
1469 return NULL;
1470 }
1471
1472 self->args = Py_XNewRef(args);
1473 self->kw = Py_XNewRef(kw);
1474
1475 self->localdicts = PyDict_New();
1476 if (self->localdicts == NULL) {
1477 goto err;
1478 }
1479
1480 self->thread_watchdogs = PySet_New(NULL);
1481 if (self->thread_watchdogs == NULL) {
1482 goto err;
1483 }
1484
1485 PyObject *localsdict = NULL;
1486 PyObject *sentinel_wr = NULL;
1487 if (create_localsdict(self, state, &localsdict, &sentinel_wr) < 0) {
1488 goto err;
1489 }
1490 Py_DECREF(localsdict);
1491 Py_DECREF(sentinel_wr);
1492
1493 return (PyObject *)self;
1494
1495 err:
1496 Py_DECREF(self);
1497 return NULL;
1498 }
1499
1500 static int
local_traverse(localobject * self,visitproc visit,void * arg)1501 local_traverse(localobject *self, visitproc visit, void *arg)
1502 {
1503 Py_VISIT(Py_TYPE(self));
1504 Py_VISIT(self->args);
1505 Py_VISIT(self->kw);
1506 Py_VISIT(self->localdicts);
1507 Py_VISIT(self->thread_watchdogs);
1508 return 0;
1509 }
1510
1511 static int
local_clear(localobject * self)1512 local_clear(localobject *self)
1513 {
1514 Py_CLEAR(self->args);
1515 Py_CLEAR(self->kw);
1516 Py_CLEAR(self->localdicts);
1517 Py_CLEAR(self->thread_watchdogs);
1518 return 0;
1519 }
1520
1521 static void
local_dealloc(localobject * self)1522 local_dealloc(localobject *self)
1523 {
1524 /* Weakrefs must be invalidated right now, otherwise they can be used
1525 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
1526 if (self->weakreflist != NULL) {
1527 PyObject_ClearWeakRefs((PyObject *) self);
1528 }
1529
1530 PyObject_GC_UnTrack(self);
1531
1532 local_clear(self);
1533
1534 PyTypeObject *tp = Py_TYPE(self);
1535 tp->tp_free((PyObject*)self);
1536 Py_DECREF(tp);
1537 }
1538
1539 /* Create the TLS key and sentinel if they don't exist */
1540 static int
create_localdummies(thread_module_state * state)1541 create_localdummies(thread_module_state *state)
1542 {
1543 PyThreadState *tstate = _PyThreadState_GET();
1544
1545 if (tstate->threading_local_key != NULL) {
1546 return 0;
1547 }
1548
1549 PyTypeObject *ld_type = state->local_dummy_type;
1550 tstate->threading_local_key = ld_type->tp_alloc(ld_type, 0);
1551 if (tstate->threading_local_key == NULL) {
1552 return -1;
1553 }
1554
1555 tstate->threading_local_sentinel = ld_type->tp_alloc(ld_type, 0);
1556 if (tstate->threading_local_sentinel == NULL) {
1557 Py_CLEAR(tstate->threading_local_key);
1558 return -1;
1559 }
1560
1561 return 0;
1562 }
1563
1564 /* Insert a localsdict and sentinel weakref for the current thread, placing
1565 strong references in localsdict and sentinel_wr, respectively.
1566 */
1567 static int
create_localsdict(localobject * self,thread_module_state * state,PyObject ** localsdict,PyObject ** sentinel_wr)1568 create_localsdict(localobject *self, thread_module_state *state,
1569 PyObject **localsdict, PyObject **sentinel_wr)
1570 {
1571 PyThreadState *tstate = _PyThreadState_GET();
1572 PyObject *ldict = NULL;
1573 PyObject *wr = NULL;
1574
1575 if (create_localdummies(state) < 0) {
1576 goto err;
1577 }
1578
1579 /* Create and insert the locals dict and sentinel weakref */
1580 ldict = PyDict_New();
1581 if (ldict == NULL) {
1582 goto err;
1583 }
1584
1585 if (PyDict_SetItem(self->localdicts, tstate->threading_local_key, ldict) <
1586 0) {
1587 goto err;
1588 }
1589
1590 wr = create_sentinel_wr(self);
1591 if (wr == NULL) {
1592 PyObject *exc = PyErr_GetRaisedException();
1593 if (PyDict_DelItem(self->localdicts, tstate->threading_local_key) <
1594 0) {
1595 PyErr_WriteUnraisable((PyObject *)self);
1596 }
1597 PyErr_SetRaisedException(exc);
1598 goto err;
1599 }
1600
1601 if (PySet_Add(self->thread_watchdogs, wr) < 0) {
1602 PyObject *exc = PyErr_GetRaisedException();
1603 if (PyDict_DelItem(self->localdicts, tstate->threading_local_key) <
1604 0) {
1605 PyErr_WriteUnraisable((PyObject *)self);
1606 }
1607 PyErr_SetRaisedException(exc);
1608 goto err;
1609 }
1610
1611 *localsdict = ldict;
1612 *sentinel_wr = wr;
1613 return 0;
1614
1615 err:
1616 Py_XDECREF(ldict);
1617 Py_XDECREF(wr);
1618 return -1;
1619 }
1620
1621 /* Return a strong reference to the locals dict for the current thread,
1622 creating it if necessary.
1623 */
1624 static PyObject *
_ldict(localobject * self,thread_module_state * state)1625 _ldict(localobject *self, thread_module_state *state)
1626 {
1627 if (create_localdummies(state) < 0) {
1628 return NULL;
1629 }
1630
1631 /* Check if a localsdict already exists */
1632 PyObject *ldict;
1633 PyThreadState *tstate = _PyThreadState_GET();
1634 if (PyDict_GetItemRef(self->localdicts, tstate->threading_local_key,
1635 &ldict) < 0) {
1636 return NULL;
1637 }
1638 if (ldict != NULL) {
1639 return ldict;
1640 }
1641
1642 /* threading.local hasn't been instantiated for this thread */
1643 PyObject *wr;
1644 if (create_localsdict(self, state, &ldict, &wr) < 0) {
1645 return NULL;
1646 }
1647
1648 /* run __init__ if we're a subtype of `threading.local` */
1649 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
1650 Py_TYPE(self)->tp_init((PyObject *)self, self->args, self->kw) < 0) {
1651 /* we need to get rid of ldict from thread so
1652 we create a new one the next time we do an attr
1653 access */
1654 PyObject *exc = PyErr_GetRaisedException();
1655 if (PyDict_DelItem(self->localdicts, tstate->threading_local_key) <
1656 0) {
1657 PyErr_WriteUnraisable((PyObject *)self);
1658 PyErr_Clear();
1659 }
1660 if (PySet_Discard(self->thread_watchdogs, wr) < 0) {
1661 PyErr_WriteUnraisable((PyObject *)self);
1662 }
1663 PyErr_SetRaisedException(exc);
1664 Py_DECREF(ldict);
1665 Py_DECREF(wr);
1666 return NULL;
1667 }
1668 Py_DECREF(wr);
1669
1670 return ldict;
1671 }
1672
1673 static int
local_setattro(localobject * self,PyObject * name,PyObject * v)1674 local_setattro(localobject *self, PyObject *name, PyObject *v)
1675 {
1676 PyObject *module = PyType_GetModuleByDef(Py_TYPE(self), &thread_module);
1677 assert(module != NULL);
1678 thread_module_state *state = get_thread_state(module);
1679
1680 PyObject *ldict = _ldict(self, state);
1681 if (ldict == NULL) {
1682 goto err;
1683 }
1684
1685 int r = PyObject_RichCompareBool(name, &_Py_ID(__dict__), Py_EQ);
1686 if (r == -1) {
1687 goto err;
1688 }
1689 if (r == 1) {
1690 PyErr_Format(PyExc_AttributeError,
1691 "'%.100s' object attribute %R is read-only",
1692 Py_TYPE(self)->tp_name, name);
1693 goto err;
1694 }
1695
1696 int st =
1697 _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
1698 Py_DECREF(ldict);
1699 return st;
1700
1701 err:
1702 Py_XDECREF(ldict);
1703 return -1;
1704 }
1705
1706 static PyObject *local_getattro(localobject *, PyObject *);
1707
1708 static PyMemberDef local_type_members[] = {
1709 {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(localobject, weakreflist), Py_READONLY},
1710 {NULL},
1711 };
1712
1713 static PyType_Slot local_type_slots[] = {
1714 {Py_tp_dealloc, (destructor)local_dealloc},
1715 {Py_tp_getattro, (getattrofunc)local_getattro},
1716 {Py_tp_setattro, (setattrofunc)local_setattro},
1717 {Py_tp_doc, "_local()\n--\n\nThread-local data"},
1718 {Py_tp_traverse, (traverseproc)local_traverse},
1719 {Py_tp_clear, (inquiry)local_clear},
1720 {Py_tp_new, local_new},
1721 {Py_tp_members, local_type_members},
1722 {0, 0}
1723 };
1724
1725 static PyType_Spec local_type_spec = {
1726 .name = "_thread._local",
1727 .basicsize = sizeof(localobject),
1728 .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
1729 Py_TPFLAGS_IMMUTABLETYPE),
1730 .slots = local_type_slots,
1731 };
1732
1733 static PyObject *
local_getattro(localobject * self,PyObject * name)1734 local_getattro(localobject *self, PyObject *name)
1735 {
1736 PyObject *module = PyType_GetModuleByDef(Py_TYPE(self), &thread_module);
1737 assert(module != NULL);
1738 thread_module_state *state = get_thread_state(module);
1739
1740 PyObject *ldict = _ldict(self, state);
1741 if (ldict == NULL)
1742 return NULL;
1743
1744 int r = PyObject_RichCompareBool(name, &_Py_ID(__dict__), Py_EQ);
1745 if (r == 1) {
1746 return ldict;
1747 }
1748 if (r == -1) {
1749 Py_DECREF(ldict);
1750 return NULL;
1751 }
1752
1753 if (!Py_IS_TYPE(self, state->local_type)) {
1754 /* use generic lookup for subtypes */
1755 PyObject *res =
1756 _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict, 0);
1757 Py_DECREF(ldict);
1758 return res;
1759 }
1760
1761 /* Optimization: just look in dict ourselves */
1762 PyObject *value;
1763 if (PyDict_GetItemRef(ldict, name, &value) != 0) {
1764 // found or error
1765 Py_DECREF(ldict);
1766 return value;
1767 }
1768
1769 /* Fall back on generic to get __class__ and __dict__ */
1770 PyObject *res =
1771 _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict, 0);
1772 Py_DECREF(ldict);
1773 return res;
1774 }
1775
1776 /* Called when a dummy is destroyed, indicating that the owning thread is being
1777 * cleared. */
1778 static PyObject *
clear_locals(PyObject * locals_and_key,PyObject * dummyweakref)1779 clear_locals(PyObject *locals_and_key, PyObject *dummyweakref)
1780 {
1781 PyObject *localweakref = PyTuple_GetItem(locals_and_key, 0);
1782 localobject *self = (localobject *)_PyWeakref_GET_REF(localweakref);
1783 if (self == NULL) {
1784 Py_RETURN_NONE;
1785 }
1786
1787 /* If the thread-local object is still alive and not being cleared,
1788 remove the corresponding local dict */
1789 if (self->localdicts != NULL) {
1790 PyObject *key = PyTuple_GetItem(locals_and_key, 1);
1791 if (PyDict_Pop(self->localdicts, key, NULL) < 0) {
1792 PyErr_WriteUnraisable((PyObject*)self);
1793 }
1794 }
1795 if (self->thread_watchdogs != NULL) {
1796 if (PySet_Discard(self->thread_watchdogs, dummyweakref) < 0) {
1797 PyErr_WriteUnraisable((PyObject *)self);
1798 }
1799 }
1800
1801 Py_DECREF(self);
1802 Py_RETURN_NONE;
1803 }
1804
1805 /* Module functions */
1806
1807 static PyObject *
thread_daemon_threads_allowed(PyObject * module,PyObject * Py_UNUSED (ignored))1808 thread_daemon_threads_allowed(PyObject *module, PyObject *Py_UNUSED(ignored))
1809 {
1810 PyInterpreterState *interp = _PyInterpreterState_GET();
1811 if (interp->feature_flags & Py_RTFLAGS_DAEMON_THREADS) {
1812 Py_RETURN_TRUE;
1813 }
1814 else {
1815 Py_RETURN_FALSE;
1816 }
1817 }
1818
1819 PyDoc_STRVAR(daemon_threads_allowed_doc,
1820 "daemon_threads_allowed($module, /)\n\
1821 --\n\
1822 \n\
1823 Return True if daemon threads are allowed in the current interpreter,\n\
1824 and False otherwise.\n");
1825
1826 static int
do_start_new_thread(thread_module_state * state,PyObject * func,PyObject * args,PyObject * kwargs,ThreadHandle * handle,int daemon)1827 do_start_new_thread(thread_module_state *state, PyObject *func, PyObject *args,
1828 PyObject *kwargs, ThreadHandle *handle, int daemon)
1829 {
1830 PyInterpreterState *interp = _PyInterpreterState_GET();
1831 if (!_PyInterpreterState_HasFeature(interp, Py_RTFLAGS_THREADS)) {
1832 PyErr_SetString(PyExc_RuntimeError,
1833 "thread is not supported for isolated subinterpreters");
1834 return -1;
1835 }
1836 if (_PyInterpreterState_GetFinalizing(interp) != NULL) {
1837 PyErr_SetString(PyExc_PythonFinalizationError,
1838 "can't create new thread at interpreter shutdown");
1839 return -1;
1840 }
1841
1842 if (!daemon) {
1843 // Add the handle before starting the thread to avoid adding a handle
1844 // to a thread that has already finished (i.e. if the thread finishes
1845 // before the call to `ThreadHandle_start()` below returns).
1846 add_to_shutdown_handles(state, handle);
1847 }
1848
1849 if (ThreadHandle_start(handle, func, args, kwargs) < 0) {
1850 if (!daemon) {
1851 remove_from_shutdown_handles(handle);
1852 }
1853 return -1;
1854 }
1855
1856 return 0;
1857 }
1858
1859 static PyObject *
thread_PyThread_start_new_thread(PyObject * module,PyObject * fargs)1860 thread_PyThread_start_new_thread(PyObject *module, PyObject *fargs)
1861 {
1862 PyObject *func, *args, *kwargs = NULL;
1863 thread_module_state *state = get_thread_state(module);
1864
1865 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
1866 &func, &args, &kwargs))
1867 return NULL;
1868 if (!PyCallable_Check(func)) {
1869 PyErr_SetString(PyExc_TypeError,
1870 "first arg must be callable");
1871 return NULL;
1872 }
1873 if (!PyTuple_Check(args)) {
1874 PyErr_SetString(PyExc_TypeError,
1875 "2nd arg must be a tuple");
1876 return NULL;
1877 }
1878 if (kwargs != NULL && !PyDict_Check(kwargs)) {
1879 PyErr_SetString(PyExc_TypeError,
1880 "optional 3rd arg must be a dictionary");
1881 return NULL;
1882 }
1883
1884 if (PySys_Audit("_thread.start_new_thread", "OOO",
1885 func, args, kwargs ? kwargs : Py_None) < 0) {
1886 return NULL;
1887 }
1888
1889 ThreadHandle *handle = ThreadHandle_new();
1890 if (handle == NULL) {
1891 return NULL;
1892 }
1893
1894 int st =
1895 do_start_new_thread(state, func, args, kwargs, handle, /*daemon=*/1);
1896 if (st < 0) {
1897 ThreadHandle_decref(handle);
1898 return NULL;
1899 }
1900 PyThread_ident_t ident = ThreadHandle_ident(handle);
1901 ThreadHandle_decref(handle);
1902 return PyLong_FromUnsignedLongLong(ident);
1903 }
1904
1905 PyDoc_STRVAR(start_new_thread_doc,
1906 "start_new_thread($module, function, args, kwargs={}, /)\n\
1907 --\n\
1908 \n\
1909 Start a new thread and return its identifier.\n\
1910 \n\
1911 The thread will call the function with positional arguments from the\n\
1912 tuple args and keyword arguments taken from the optional dictionary\n\
1913 kwargs. The thread exits when the function returns; the return value\n\
1914 is ignored. The thread will also exit when the function raises an\n\
1915 unhandled exception; a stack trace will be printed unless the exception\n\
1916 is SystemExit.");
1917
1918 PyDoc_STRVAR(start_new_doc,
1919 "start_new($module, function, args, kwargs={}, /)\n\
1920 --\n\
1921 \n\
1922 An obsolete synonym of start_new_thread().");
1923
1924 static PyObject *
thread_PyThread_start_joinable_thread(PyObject * module,PyObject * fargs,PyObject * fkwargs)1925 thread_PyThread_start_joinable_thread(PyObject *module, PyObject *fargs,
1926 PyObject *fkwargs)
1927 {
1928 static char *keywords[] = {"function", "handle", "daemon", NULL};
1929 PyObject *func = NULL;
1930 int daemon = 1;
1931 thread_module_state *state = get_thread_state(module);
1932 PyObject *hobj = NULL;
1933 if (!PyArg_ParseTupleAndKeywords(fargs, fkwargs,
1934 "O|Op:start_joinable_thread", keywords,
1935 &func, &hobj, &daemon)) {
1936 return NULL;
1937 }
1938
1939 if (!PyCallable_Check(func)) {
1940 PyErr_SetString(PyExc_TypeError,
1941 "thread function must be callable");
1942 return NULL;
1943 }
1944
1945 if (hobj == NULL) {
1946 hobj = Py_None;
1947 }
1948 else if (hobj != Py_None && !Py_IS_TYPE(hobj, state->thread_handle_type)) {
1949 PyErr_SetString(PyExc_TypeError, "'handle' must be a _ThreadHandle");
1950 return NULL;
1951 }
1952
1953 if (PySys_Audit("_thread.start_joinable_thread", "OiO", func, daemon,
1954 hobj) < 0) {
1955 return NULL;
1956 }
1957
1958 if (hobj == Py_None) {
1959 hobj = (PyObject *)PyThreadHandleObject_new(state->thread_handle_type);
1960 if (hobj == NULL) {
1961 return NULL;
1962 }
1963 }
1964 else {
1965 Py_INCREF(hobj);
1966 }
1967
1968 PyObject* args = PyTuple_New(0);
1969 if (args == NULL) {
1970 return NULL;
1971 }
1972 int st = do_start_new_thread(state, func, args,
1973 /*kwargs=*/ NULL, ((PyThreadHandleObject*)hobj)->handle, daemon);
1974 Py_DECREF(args);
1975 if (st < 0) {
1976 Py_DECREF(hobj);
1977 return NULL;
1978 }
1979 return (PyObject *) hobj;
1980 }
1981
1982 PyDoc_STRVAR(start_joinable_doc,
1983 "start_joinable_thread($module, /, function, handle=None, daemon=True)\n\
1984 --\n\
1985 \n\
1986 *For internal use only*: start a new thread.\n\
1987 \n\
1988 Like start_new_thread(), this starts a new thread calling the given function.\n\
1989 Unlike start_new_thread(), this returns a handle object with methods to join\n\
1990 or detach the given thread.\n\
1991 This function is not for third-party code, please use the\n\
1992 `threading` module instead. During finalization the runtime will not wait for\n\
1993 the thread to exit if daemon is True. If handle is provided it must be a\n\
1994 newly created thread._ThreadHandle instance.");
1995
1996 static PyObject *
thread_PyThread_exit_thread(PyObject * self,PyObject * Py_UNUSED (ignored))1997 thread_PyThread_exit_thread(PyObject *self, PyObject *Py_UNUSED(ignored))
1998 {
1999 PyErr_SetNone(PyExc_SystemExit);
2000 return NULL;
2001 }
2002
2003 PyDoc_STRVAR(exit_doc,
2004 "exit($module, /)\n\
2005 --\n\
2006 \n\
2007 This is synonymous to ``raise SystemExit''. It will cause the current\n\
2008 thread to exit silently unless the exception is caught.");
2009
2010 PyDoc_STRVAR(exit_thread_doc,
2011 "exit_thread($module, /)\n\
2012 --\n\
2013 \n\
2014 An obsolete synonym of exit().");
2015
2016 static PyObject *
thread_PyThread_interrupt_main(PyObject * self,PyObject * args)2017 thread_PyThread_interrupt_main(PyObject *self, PyObject *args)
2018 {
2019 int signum = SIGINT;
2020 if (!PyArg_ParseTuple(args, "|i:signum", &signum)) {
2021 return NULL;
2022 }
2023
2024 if (PyErr_SetInterruptEx(signum)) {
2025 PyErr_SetString(PyExc_ValueError, "signal number out of range");
2026 return NULL;
2027 }
2028 Py_RETURN_NONE;
2029 }
2030
2031 PyDoc_STRVAR(interrupt_doc,
2032 "interrupt_main($module, signum=signal.SIGINT, /)\n\
2033 --\n\
2034 \n\
2035 Simulate the arrival of the given signal in the main thread,\n\
2036 where the corresponding signal handler will be executed.\n\
2037 If *signum* is omitted, SIGINT is assumed.\n\
2038 A subthread can use this function to interrupt the main thread.\n\
2039 \n\
2040 Note: the default signal handler for SIGINT raises ``KeyboardInterrupt``."
2041 );
2042
2043 static PyObject *
thread_PyThread_allocate_lock(PyObject * module,PyObject * Py_UNUSED (ignored))2044 thread_PyThread_allocate_lock(PyObject *module, PyObject *Py_UNUSED(ignored))
2045 {
2046 return (PyObject *) newlockobject(module);
2047 }
2048
2049 PyDoc_STRVAR(allocate_lock_doc,
2050 "allocate_lock($module, /)\n\
2051 --\n\
2052 \n\
2053 Create a new lock object. See help(type(threading.Lock())) for\n\
2054 information about locks.");
2055
2056 PyDoc_STRVAR(allocate_doc,
2057 "allocate($module, /)\n\
2058 --\n\
2059 \n\
2060 An obsolete synonym of allocate_lock().");
2061
2062 static PyObject *
thread_get_ident(PyObject * self,PyObject * Py_UNUSED (ignored))2063 thread_get_ident(PyObject *self, PyObject *Py_UNUSED(ignored))
2064 {
2065 PyThread_ident_t ident = PyThread_get_thread_ident_ex();
2066 if (ident == PYTHREAD_INVALID_THREAD_ID) {
2067 PyErr_SetString(ThreadError, "no current thread ident");
2068 return NULL;
2069 }
2070 return PyLong_FromUnsignedLongLong(ident);
2071 }
2072
2073 PyDoc_STRVAR(get_ident_doc,
2074 "get_ident($module, /)\n\
2075 --\n\
2076 \n\
2077 Return a non-zero integer that uniquely identifies the current thread\n\
2078 amongst other threads that exist simultaneously.\n\
2079 This may be used to identify per-thread resources.\n\
2080 Even though on some platforms threads identities may appear to be\n\
2081 allocated consecutive numbers starting at 1, this behavior should not\n\
2082 be relied upon, and the number should be seen purely as a magic cookie.\n\
2083 A thread's identity may be reused for another thread after it exits.");
2084
2085 #ifdef PY_HAVE_THREAD_NATIVE_ID
2086 static PyObject *
thread_get_native_id(PyObject * self,PyObject * Py_UNUSED (ignored))2087 thread_get_native_id(PyObject *self, PyObject *Py_UNUSED(ignored))
2088 {
2089 unsigned long native_id = PyThread_get_thread_native_id();
2090 return PyLong_FromUnsignedLong(native_id);
2091 }
2092
2093 PyDoc_STRVAR(get_native_id_doc,
2094 "get_native_id($module, /)\n\
2095 --\n\
2096 \n\
2097 Return a non-negative integer identifying the thread as reported\n\
2098 by the OS (kernel). This may be used to uniquely identify a\n\
2099 particular thread within a system.");
2100 #endif
2101
2102 static PyObject *
thread__count(PyObject * self,PyObject * Py_UNUSED (ignored))2103 thread__count(PyObject *self, PyObject *Py_UNUSED(ignored))
2104 {
2105 PyInterpreterState *interp = _PyInterpreterState_GET();
2106 return PyLong_FromSsize_t(_Py_atomic_load_ssize(&interp->threads.count));
2107 }
2108
2109 PyDoc_STRVAR(_count_doc,
2110 "_count($module, /)\n\
2111 --\n\
2112 \n\
2113 Return the number of currently running Python threads, excluding\n\
2114 the main thread. The returned number comprises all threads created\n\
2115 through `start_new_thread()` as well as `threading.Thread`, and not\n\
2116 yet finished.\n\
2117 \n\
2118 This function is meant for internal and specialized purposes only.\n\
2119 In most applications `threading.enumerate()` should be used instead.");
2120
2121 static PyObject *
thread_stack_size(PyObject * self,PyObject * args)2122 thread_stack_size(PyObject *self, PyObject *args)
2123 {
2124 size_t old_size;
2125 Py_ssize_t new_size = 0;
2126 int rc;
2127
2128 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
2129 return NULL;
2130
2131 if (new_size < 0) {
2132 PyErr_SetString(PyExc_ValueError,
2133 "size must be 0 or a positive value");
2134 return NULL;
2135 }
2136
2137 old_size = PyThread_get_stacksize();
2138
2139 rc = PyThread_set_stacksize((size_t) new_size);
2140 if (rc == -1) {
2141 PyErr_Format(PyExc_ValueError,
2142 "size not valid: %zd bytes",
2143 new_size);
2144 return NULL;
2145 }
2146 if (rc == -2) {
2147 PyErr_SetString(ThreadError,
2148 "setting stack size not supported");
2149 return NULL;
2150 }
2151
2152 return PyLong_FromSsize_t((Py_ssize_t) old_size);
2153 }
2154
2155 PyDoc_STRVAR(stack_size_doc,
2156 "stack_size($module, size=0, /)\n\
2157 --\n\
2158 \n\
2159 Return the thread stack size used when creating new threads. The\n\
2160 optional size argument specifies the stack size (in bytes) to be used\n\
2161 for subsequently created threads, and must be 0 (use platform or\n\
2162 configured default) or a positive integer value of at least 32,768 (32k).\n\
2163 If changing the thread stack size is unsupported, a ThreadError\n\
2164 exception is raised. If the specified size is invalid, a ValueError\n\
2165 exception is raised, and the stack size is unmodified. 32k bytes\n\
2166 currently the minimum supported stack size value to guarantee\n\
2167 sufficient stack space for the interpreter itself.\n\
2168 \n\
2169 Note that some platforms may have particular restrictions on values for\n\
2170 the stack size, such as requiring a minimum stack size larger than 32 KiB or\n\
2171 requiring allocation in multiples of the system memory page size\n\
2172 - platform documentation should be referred to for more information\n\
2173 (4 KiB pages are common; using multiples of 4096 for the stack size is\n\
2174 the suggested approach in the absence of more specific information).");
2175
2176 static int
thread_excepthook_file(PyObject * file,PyObject * exc_type,PyObject * exc_value,PyObject * exc_traceback,PyObject * thread)2177 thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value,
2178 PyObject *exc_traceback, PyObject *thread)
2179 {
2180 /* print(f"Exception in thread {thread.name}:", file=file) */
2181 if (PyFile_WriteString("Exception in thread ", file) < 0) {
2182 return -1;
2183 }
2184
2185 PyObject *name = NULL;
2186 if (thread != Py_None) {
2187 if (PyObject_GetOptionalAttr(thread, &_Py_ID(name), &name) < 0) {
2188 return -1;
2189 }
2190 }
2191 if (name != NULL) {
2192 if (PyFile_WriteObject(name, file, Py_PRINT_RAW) < 0) {
2193 Py_DECREF(name);
2194 return -1;
2195 }
2196 Py_DECREF(name);
2197 }
2198 else {
2199 PyThread_ident_t ident = PyThread_get_thread_ident_ex();
2200 PyObject *str = PyUnicode_FromFormat("%" PY_FORMAT_THREAD_IDENT_T, ident);
2201 if (str != NULL) {
2202 if (PyFile_WriteObject(str, file, Py_PRINT_RAW) < 0) {
2203 Py_DECREF(str);
2204 return -1;
2205 }
2206 Py_DECREF(str);
2207 }
2208 else {
2209 PyErr_Clear();
2210
2211 if (PyFile_WriteString("<failed to get thread name>", file) < 0) {
2212 return -1;
2213 }
2214 }
2215 }
2216
2217 if (PyFile_WriteString(":\n", file) < 0) {
2218 return -1;
2219 }
2220
2221 /* Display the traceback */
2222 _PyErr_Display(file, exc_type, exc_value, exc_traceback);
2223
2224 /* Call file.flush() */
2225 if (_PyFile_Flush(file) < 0) {
2226 return -1;
2227 }
2228
2229 return 0;
2230 }
2231
2232
2233 PyDoc_STRVAR(ExceptHookArgs__doc__,
2234 "ExceptHookArgs\n\
2235 \n\
2236 Type used to pass arguments to threading.excepthook.");
2237
2238 static PyStructSequence_Field ExceptHookArgs_fields[] = {
2239 {"exc_type", "Exception type"},
2240 {"exc_value", "Exception value"},
2241 {"exc_traceback", "Exception traceback"},
2242 {"thread", "Thread"},
2243 {0}
2244 };
2245
2246 static PyStructSequence_Desc ExceptHookArgs_desc = {
2247 .name = "_thread._ExceptHookArgs",
2248 .doc = ExceptHookArgs__doc__,
2249 .fields = ExceptHookArgs_fields,
2250 .n_in_sequence = 4
2251 };
2252
2253
2254 static PyObject *
thread_excepthook(PyObject * module,PyObject * args)2255 thread_excepthook(PyObject *module, PyObject *args)
2256 {
2257 thread_module_state *state = get_thread_state(module);
2258
2259 if (!Py_IS_TYPE(args, state->excepthook_type)) {
2260 PyErr_SetString(PyExc_TypeError,
2261 "_thread.excepthook argument type "
2262 "must be ExceptHookArgs");
2263 return NULL;
2264 }
2265
2266 /* Borrowed reference */
2267 PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0);
2268 if (exc_type == PyExc_SystemExit) {
2269 /* silently ignore SystemExit */
2270 Py_RETURN_NONE;
2271 }
2272
2273 /* Borrowed references */
2274 PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1);
2275 PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
2276 PyObject *thread = PyStructSequence_GET_ITEM(args, 3);
2277
2278 PyThreadState *tstate = _PyThreadState_GET();
2279 PyObject *file = _PySys_GetAttr(tstate, &_Py_ID(stderr));
2280 if (file == NULL || file == Py_None) {
2281 if (thread == Py_None) {
2282 /* do nothing if sys.stderr is None and thread is None */
2283 Py_RETURN_NONE;
2284 }
2285
2286 file = PyObject_GetAttrString(thread, "_stderr");
2287 if (file == NULL) {
2288 return NULL;
2289 }
2290 if (file == Py_None) {
2291 Py_DECREF(file);
2292 /* do nothing if sys.stderr is None and sys.stderr was None
2293 when the thread was created */
2294 Py_RETURN_NONE;
2295 }
2296 }
2297 else {
2298 Py_INCREF(file);
2299 }
2300
2301 int res = thread_excepthook_file(file, exc_type, exc_value, exc_tb,
2302 thread);
2303 Py_DECREF(file);
2304 if (res < 0) {
2305 return NULL;
2306 }
2307
2308 Py_RETURN_NONE;
2309 }
2310
2311 PyDoc_STRVAR(excepthook_doc,
2312 "_excepthook($module, (exc_type, exc_value, exc_traceback, thread), /)\n\
2313 --\n\
2314 \n\
2315 Handle uncaught Thread.run() exception.");
2316
2317 static PyObject *
thread__is_main_interpreter(PyObject * module,PyObject * Py_UNUSED (ignored))2318 thread__is_main_interpreter(PyObject *module, PyObject *Py_UNUSED(ignored))
2319 {
2320 PyInterpreterState *interp = _PyInterpreterState_GET();
2321 return PyBool_FromLong(_Py_IsMainInterpreter(interp));
2322 }
2323
2324 PyDoc_STRVAR(thread__is_main_interpreter_doc,
2325 "_is_main_interpreter($module, /)\n\
2326 --\n\
2327 \n\
2328 Return True if the current interpreter is the main Python interpreter.");
2329
2330 static PyObject *
thread_shutdown(PyObject * self,PyObject * args)2331 thread_shutdown(PyObject *self, PyObject *args)
2332 {
2333 PyThread_ident_t ident = PyThread_get_thread_ident_ex();
2334 thread_module_state *state = get_thread_state(self);
2335
2336 for (;;) {
2337 ThreadHandle *handle = NULL;
2338
2339 // Find a thread that's not yet finished.
2340 HEAD_LOCK(&_PyRuntime);
2341 struct llist_node *node;
2342 llist_for_each_safe(node, &state->shutdown_handles) {
2343 ThreadHandle *cur = llist_data(node, ThreadHandle, shutdown_node);
2344 if (cur->ident != ident) {
2345 ThreadHandle_incref(cur);
2346 handle = cur;
2347 break;
2348 }
2349 }
2350 HEAD_UNLOCK(&_PyRuntime);
2351
2352 if (!handle) {
2353 // No more threads to wait on!
2354 break;
2355 }
2356
2357 // Wait for the thread to finish. If we're interrupted, such
2358 // as by a ctrl-c we print the error and exit early.
2359 if (ThreadHandle_join(handle, -1) < 0) {
2360 PyErr_WriteUnraisable(NULL);
2361 ThreadHandle_decref(handle);
2362 Py_RETURN_NONE;
2363 }
2364
2365 ThreadHandle_decref(handle);
2366 }
2367
2368 Py_RETURN_NONE;
2369 }
2370
2371 PyDoc_STRVAR(shutdown_doc,
2372 "_shutdown($module, /)\n\
2373 --\n\
2374 \n\
2375 Wait for all non-daemon threads (other than the calling thread) to stop.");
2376
2377 static PyObject *
thread__make_thread_handle(PyObject * module,PyObject * identobj)2378 thread__make_thread_handle(PyObject *module, PyObject *identobj)
2379 {
2380 thread_module_state *state = get_thread_state(module);
2381 if (!PyLong_Check(identobj)) {
2382 PyErr_SetString(PyExc_TypeError, "ident must be an integer");
2383 return NULL;
2384 }
2385 PyThread_ident_t ident = PyLong_AsUnsignedLongLong(identobj);
2386 if (PyErr_Occurred()) {
2387 return NULL;
2388 }
2389 PyThreadHandleObject *hobj =
2390 PyThreadHandleObject_new(state->thread_handle_type);
2391 if (hobj == NULL) {
2392 return NULL;
2393 }
2394 PyMutex_Lock(&hobj->handle->mutex);
2395 hobj->handle->ident = ident;
2396 hobj->handle->state = THREAD_HANDLE_RUNNING;
2397 PyMutex_Unlock(&hobj->handle->mutex);
2398 return (PyObject*) hobj;
2399 }
2400
2401 PyDoc_STRVAR(thread__make_thread_handle_doc,
2402 "_make_thread_handle($module, ident, /)\n\
2403 --\n\
2404 \n\
2405 Internal only. Make a thread handle for threads not spawned\n\
2406 by the _thread or threading module.");
2407
2408 static PyObject *
thread__get_main_thread_ident(PyObject * module,PyObject * Py_UNUSED (ignored))2409 thread__get_main_thread_ident(PyObject *module, PyObject *Py_UNUSED(ignored))
2410 {
2411 return PyLong_FromUnsignedLongLong(_PyRuntime.main_thread);
2412 }
2413
2414 PyDoc_STRVAR(thread__get_main_thread_ident_doc,
2415 "_get_main_thread_ident($module, /)\n\
2416 --\n\
2417 \n\
2418 Internal only. Return a non-zero integer that uniquely identifies the main thread\n\
2419 of the main interpreter.");
2420
2421 static PyMethodDef thread_methods[] = {
2422 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
2423 METH_VARARGS, start_new_thread_doc},
2424 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
2425 METH_VARARGS, start_new_doc},
2426 {"start_joinable_thread", _PyCFunction_CAST(thread_PyThread_start_joinable_thread),
2427 METH_VARARGS | METH_KEYWORDS, start_joinable_doc},
2428 {"daemon_threads_allowed", (PyCFunction)thread_daemon_threads_allowed,
2429 METH_NOARGS, daemon_threads_allowed_doc},
2430 {"allocate_lock", thread_PyThread_allocate_lock,
2431 METH_NOARGS, allocate_lock_doc},
2432 {"allocate", thread_PyThread_allocate_lock,
2433 METH_NOARGS, allocate_doc},
2434 {"exit_thread", thread_PyThread_exit_thread,
2435 METH_NOARGS, exit_thread_doc},
2436 {"exit", thread_PyThread_exit_thread,
2437 METH_NOARGS, exit_doc},
2438 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
2439 METH_VARARGS, interrupt_doc},
2440 {"get_ident", thread_get_ident,
2441 METH_NOARGS, get_ident_doc},
2442 #ifdef PY_HAVE_THREAD_NATIVE_ID
2443 {"get_native_id", thread_get_native_id,
2444 METH_NOARGS, get_native_id_doc},
2445 #endif
2446 {"_count", thread__count,
2447 METH_NOARGS, _count_doc},
2448 {"stack_size", (PyCFunction)thread_stack_size,
2449 METH_VARARGS, stack_size_doc},
2450 {"_excepthook", thread_excepthook,
2451 METH_O, excepthook_doc},
2452 {"_is_main_interpreter", thread__is_main_interpreter,
2453 METH_NOARGS, thread__is_main_interpreter_doc},
2454 {"_shutdown", thread_shutdown,
2455 METH_NOARGS, shutdown_doc},
2456 {"_make_thread_handle", thread__make_thread_handle,
2457 METH_O, thread__make_thread_handle_doc},
2458 {"_get_main_thread_ident", thread__get_main_thread_ident,
2459 METH_NOARGS, thread__get_main_thread_ident_doc},
2460 {NULL, NULL} /* sentinel */
2461 };
2462
2463
2464 /* Initialization function */
2465
2466 static int
thread_module_exec(PyObject * module)2467 thread_module_exec(PyObject *module)
2468 {
2469 thread_module_state *state = get_thread_state(module);
2470 PyObject *d = PyModule_GetDict(module);
2471
2472 // Initialize the C thread library
2473 PyThread_init_thread();
2474
2475 // _ThreadHandle
2476 state->thread_handle_type = (PyTypeObject *)PyType_FromSpec(&ThreadHandle_Type_spec);
2477 if (state->thread_handle_type == NULL) {
2478 return -1;
2479 }
2480 if (PyDict_SetItemString(d, "_ThreadHandle", (PyObject *)state->thread_handle_type) < 0) {
2481 return -1;
2482 }
2483
2484 // Lock
2485 state->lock_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &lock_type_spec, NULL);
2486 if (state->lock_type == NULL) {
2487 return -1;
2488 }
2489 if (PyModule_AddType(module, state->lock_type) < 0) {
2490 return -1;
2491 }
2492 // Old alias: lock -> LockType
2493 if (PyDict_SetItemString(d, "LockType", (PyObject *)state->lock_type) < 0) {
2494 return -1;
2495 }
2496
2497 // RLock
2498 PyTypeObject *rlock_type = (PyTypeObject *)PyType_FromSpec(&rlock_type_spec);
2499 if (rlock_type == NULL) {
2500 return -1;
2501 }
2502 if (PyModule_AddType(module, rlock_type) < 0) {
2503 Py_DECREF(rlock_type);
2504 return -1;
2505 }
2506 Py_DECREF(rlock_type);
2507
2508 // Local dummy
2509 state->local_dummy_type = (PyTypeObject *)PyType_FromSpec(&local_dummy_type_spec);
2510 if (state->local_dummy_type == NULL) {
2511 return -1;
2512 }
2513
2514 // Local
2515 state->local_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &local_type_spec, NULL);
2516 if (state->local_type == NULL) {
2517 return -1;
2518 }
2519 if (PyModule_AddType(module, state->local_type) < 0) {
2520 return -1;
2521 }
2522
2523 // Add module attributes
2524 if (PyDict_SetItemString(d, "error", ThreadError) < 0) {
2525 return -1;
2526 }
2527
2528 // _ExceptHookArgs type
2529 state->excepthook_type = PyStructSequence_NewType(&ExceptHookArgs_desc);
2530 if (state->excepthook_type == NULL) {
2531 return -1;
2532 }
2533 if (PyModule_AddType(module, state->excepthook_type) < 0) {
2534 return -1;
2535 }
2536
2537 // TIMEOUT_MAX
2538 double timeout_max = (double)PY_TIMEOUT_MAX * 1e-6;
2539 double time_max = PyTime_AsSecondsDouble(PyTime_MAX);
2540 timeout_max = Py_MIN(timeout_max, time_max);
2541 // Round towards minus infinity
2542 timeout_max = floor(timeout_max);
2543
2544 if (PyModule_Add(module, "TIMEOUT_MAX",
2545 PyFloat_FromDouble(timeout_max)) < 0) {
2546 return -1;
2547 }
2548
2549 llist_init(&state->shutdown_handles);
2550
2551 return 0;
2552 }
2553
2554
2555 static int
thread_module_traverse(PyObject * module,visitproc visit,void * arg)2556 thread_module_traverse(PyObject *module, visitproc visit, void *arg)
2557 {
2558 thread_module_state *state = get_thread_state(module);
2559 Py_VISIT(state->excepthook_type);
2560 Py_VISIT(state->lock_type);
2561 Py_VISIT(state->local_type);
2562 Py_VISIT(state->local_dummy_type);
2563 Py_VISIT(state->thread_handle_type);
2564 return 0;
2565 }
2566
2567 static int
thread_module_clear(PyObject * module)2568 thread_module_clear(PyObject *module)
2569 {
2570 thread_module_state *state = get_thread_state(module);
2571 Py_CLEAR(state->excepthook_type);
2572 Py_CLEAR(state->lock_type);
2573 Py_CLEAR(state->local_type);
2574 Py_CLEAR(state->local_dummy_type);
2575 Py_CLEAR(state->thread_handle_type);
2576 // Remove any remaining handles (e.g. if shutdown exited early due to
2577 // interrupt) so that attempts to unlink the handle after our module state
2578 // is destroyed do not crash.
2579 clear_shutdown_handles(state);
2580 return 0;
2581 }
2582
2583 static void
thread_module_free(void * module)2584 thread_module_free(void *module)
2585 {
2586 thread_module_clear((PyObject *)module);
2587 }
2588
2589
2590
2591 PyDoc_STRVAR(thread_doc,
2592 "This module provides primitive operations to write multi-threaded programs.\n\
2593 The 'threading' module provides a more convenient interface.");
2594
2595 static PyModuleDef_Slot thread_module_slots[] = {
2596 {Py_mod_exec, thread_module_exec},
2597 {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
2598 {Py_mod_gil, Py_MOD_GIL_NOT_USED},
2599 {0, NULL}
2600 };
2601
2602 static struct PyModuleDef thread_module = {
2603 PyModuleDef_HEAD_INIT,
2604 .m_name = "_thread",
2605 .m_doc = thread_doc,
2606 .m_size = sizeof(thread_module_state),
2607 .m_methods = thread_methods,
2608 .m_traverse = thread_module_traverse,
2609 .m_clear = thread_module_clear,
2610 .m_free = thread_module_free,
2611 .m_slots = thread_module_slots,
2612 };
2613
2614 PyMODINIT_FUNC
PyInit__thread(void)2615 PyInit__thread(void)
2616 {
2617 return PyModuleDef_Init(&thread_module);
2618 }
2619