blob: 7feb0b8a1f1f4d4ee529e562521a1ad40f32390c [file] [log] [blame]
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001
2/* Thread module */
3/* Interface to Sjoerd's portable C thread library */
4
Barry Warsawd0c10421996-12-17 00:05:22 +00005#include "Python.h"
Victor Stinner4a21e572020-04-15 02:35:41 +02006#include "pycore_interp.h" // _PyInterpreterState.num_threads
Victor Stinnercdad2722021-04-22 00:52:52 +02007#include "pycore_moduleobject.h" // _PyModule_GetState()
8#include "pycore_pylifecycle.h"
Victor Stinner4a21e572020-04-15 02:35:41 +02009#include "pycore_pystate.h" // _PyThreadState_Init()
10#include <stddef.h> // offsetof()
Victor Stinner61040132020-12-18 01:39:00 +010011#include "structmember.h" // PyMemberDef
Guido van Rossum1984f1e1992-08-04 12:41:02 +000012
Antoine Pitrouba251c22021-03-11 23:35:45 +010013#ifdef HAVE_SIGNAL_H
14# include <signal.h> // SIGINT
15#endif
16
Victor Stinner8203c732020-12-16 12:20:33 +010017// ThreadError is just an alias to PyExc_RuntimeError
18#define ThreadError PyExc_RuntimeError
19
20_Py_IDENTIFIER(__dict__);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000021
Victor Stinnerbd303c12013-11-07 23:07:29 +010022_Py_IDENTIFIER(stderr);
Victor Stinnercd590a72019-05-28 00:39:52 +020023_Py_IDENTIFIER(flush);
Victor Stinnerbd303c12013-11-07 23:07:29 +010024
Victor Stinner8203c732020-12-16 12:20:33 +010025
Victor Stinner61040132020-12-18 01:39:00 +010026// Forward declarations
27static struct PyModuleDef thread_module;
28
29
30typedef struct {
31 PyTypeObject *lock_type;
32 PyTypeObject *local_type;
33 PyTypeObject *local_dummy_type;
34} thread_module_state;
35
36static inline thread_module_state*
37get_thread_state(PyObject *module)
38{
Victor Stinnercdad2722021-04-22 00:52:52 +020039 void *state = _PyModule_GetState(module);
Victor Stinner61040132020-12-18 01:39:00 +010040 assert(state != NULL);
41 return (thread_module_state *)state;
42}
43
44
Guido van Rossum1984f1e1992-08-04 12:41:02 +000045/* Lock objects */
46
47typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000048 PyObject_HEAD
49 PyThread_type_lock lock_lock;
50 PyObject *in_weakreflist;
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000051 char locked; /* for sanity checking */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000052} lockobject;
53
Victor Stinner61040132020-12-18 01:39:00 +010054static int
55lock_traverse(lockobject *self, visitproc visit, void *arg)
56{
57 Py_VISIT(Py_TYPE(self));
58 return 0;
59}
60
Guido van Rossum1984f1e1992-08-04 12:41:02 +000061static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000062lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000063{
Victor Stinner8203c732020-12-16 12:20:33 +010064 if (self->in_weakreflist != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000065 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner8203c732020-12-16 12:20:33 +010066 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067 if (self->lock_lock != NULL) {
68 /* Unlock the lock so it's safe to free it */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000069 if (self->locked)
70 PyThread_release_lock(self->lock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000071 PyThread_free_lock(self->lock_lock);
72 }
Victor Stinner61040132020-12-18 01:39:00 +010073 PyTypeObject *tp = Py_TYPE(self);
74 tp->tp_free((PyObject*)self);
75 Py_DECREF(tp);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000076}
77
Antoine Pitrou810023d2010-12-15 22:59:16 +000078/* Helper to acquire an interruptible lock with a timeout. If the lock acquire
79 * is interrupted, signal handlers are run, and if they raise an exception,
80 * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE
Raymond Hettinger15f44ab2016-08-30 10:47:49 -070081 * are returned, depending on whether the lock can be acquired within the
Antoine Pitrou810023d2010-12-15 22:59:16 +000082 * timeout.
83 */
84static PyLockStatus
Victor Stinnerf5faad22015-03-28 03:52:05 +010085acquire_timed(PyThread_type_lock lock, _PyTime_t timeout)
Antoine Pitrou810023d2010-12-15 22:59:16 +000086{
87 PyLockStatus r;
Victor Stinnerf5faad22015-03-28 03:52:05 +010088 _PyTime_t endtime = 0;
Antoine Pitrou810023d2010-12-15 22:59:16 +000089
Victor Stinner8203c732020-12-16 12:20:33 +010090 if (timeout > 0) {
Victor Stinnerf5faad22015-03-28 03:52:05 +010091 endtime = _PyTime_GetMonotonicClock() + timeout;
Victor Stinner8203c732020-12-16 12:20:33 +010092 }
Antoine Pitrou810023d2010-12-15 22:59:16 +000093
94 do {
Victor Stinner8203c732020-12-16 12:20:33 +010095 _PyTime_t microseconds;
Victor Stinner869e1772015-03-30 03:49:14 +020096 microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING);
Victor Stinnerf5faad22015-03-28 03:52:05 +010097
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000098 /* first a simple non-blocking try without releasing the GIL */
99 r = PyThread_acquire_lock_timed(lock, 0, 0);
100 if (r == PY_LOCK_FAILURE && microseconds != 0) {
101 Py_BEGIN_ALLOW_THREADS
102 r = PyThread_acquire_lock_timed(lock, microseconds, 1);
103 Py_END_ALLOW_THREADS
Victor Stinner357f5152013-11-05 15:10:19 +0100104 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000105
106 if (r == PY_LOCK_INTR) {
107 /* Run signal handlers if we were interrupted. Propagate
108 * exceptions from signal handlers, such as KeyboardInterrupt, by
109 * passing up PY_LOCK_INTR. */
110 if (Py_MakePendingCalls() < 0) {
111 return PY_LOCK_INTR;
112 }
113
114 /* If we're using a timeout, recompute the timeout after processing
115 * signals, since those can take time. */
Victor Stinnerf5faad22015-03-28 03:52:05 +0100116 if (timeout > 0) {
117 timeout = endtime - _PyTime_GetMonotonicClock();
Antoine Pitrou810023d2010-12-15 22:59:16 +0000118
119 /* Check for negative values, since those mean block forever.
120 */
Victor Stinner6aa446c2015-03-30 21:33:51 +0200121 if (timeout < 0) {
Antoine Pitrou810023d2010-12-15 22:59:16 +0000122 r = PY_LOCK_FAILURE;
123 }
124 }
125 }
126 } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */
127
128 return r;
129}
130
Victor Stinnerf5faad22015-03-28 03:52:05 +0100131static int
132lock_acquire_parse_args(PyObject *args, PyObject *kwds,
133 _PyTime_t *timeout)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 char *kwlist[] = {"blocking", "timeout", NULL};
136 int blocking = 1;
Victor Stinnerf5faad22015-03-28 03:52:05 +0100137 PyObject *timeout_obj = NULL;
Victor Stinner13019fd2015-04-03 13:10:54 +0200138 const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000139
Victor Stinnerf5faad22015-03-28 03:52:05 +0100140 *timeout = unset_timeout ;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000141
Victor Stinnerf5faad22015-03-28 03:52:05 +0100142 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:acquire", kwlist,
143 &blocking, &timeout_obj))
144 return -1;
145
146 if (timeout_obj
Victor Stinner869e1772015-03-30 03:49:14 +0200147 && _PyTime_FromSecondsObject(timeout,
Pablo Galindo59af94f2017-10-18 08:13:09 +0100148 timeout_obj, _PyTime_ROUND_TIMEOUT) < 0)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100149 return -1;
150
151 if (!blocking && *timeout != unset_timeout ) {
152 PyErr_SetString(PyExc_ValueError,
153 "can't specify a timeout for a non-blocking call");
154 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100156 if (*timeout < 0 && *timeout != unset_timeout) {
157 PyErr_SetString(PyExc_ValueError,
158 "timeout value must be positive");
159 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 }
161 if (!blocking)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100162 *timeout = 0;
163 else if (*timeout != unset_timeout) {
164 _PyTime_t microseconds;
165
Pablo Galindo59af94f2017-10-18 08:13:09 +0100166 microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinnerf5faad22015-03-28 03:52:05 +0100167 if (microseconds >= PY_TIMEOUT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 PyErr_SetString(PyExc_OverflowError,
169 "timeout value is too large");
Victor Stinnerf5faad22015-03-28 03:52:05 +0100170 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000172 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100173 return 0;
174}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000175
Victor Stinnerf5faad22015-03-28 03:52:05 +0100176static PyObject *
177lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
178{
179 _PyTime_t timeout;
Victor Stinnerf5faad22015-03-28 03:52:05 +0100180 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
181 return NULL;
182
Victor Stinner8203c732020-12-16 12:20:33 +0100183 PyLockStatus r = acquire_timed(self->lock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000184 if (r == PY_LOCK_INTR) {
185 return NULL;
186 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000188 if (r == PY_LOCK_ACQUIRED)
189 self->locked = 1;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000190 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000191}
192
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000193PyDoc_STRVAR(acquire_doc,
Berker Peksag720e6552016-05-02 12:25:35 +0300194"acquire(blocking=True, timeout=-1) -> bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000195(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000196\n\
197Lock the lock. Without argument, this blocks if the lock is already\n\
198locked (even by the same thread), waiting for another thread to release\n\
R David Murray95b71102013-02-04 10:15:58 -0500199the lock, and return True once the lock is acquired.\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000200With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000201and the return value reflects whether the lock is acquired.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000202The blocking operation is interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000203
Barry Warsawd0c10421996-12-17 00:05:22 +0000204static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530205lock_PyThread_release_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 /* Sanity check: the lock must be locked */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000208 if (!self->locked) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 PyErr_SetString(ThreadError, "release unlocked lock");
210 return NULL;
211 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 PyThread_release_lock(self->lock_lock);
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000214 self->locked = 0;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200215 Py_RETURN_NONE;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000216}
217
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000218PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000219"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000220(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000221\n\
222Release the lock, allowing another thread that is blocked waiting for\n\
223the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000224but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000225
Barry Warsawd0c10421996-12-17 00:05:22 +0000226static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530227lock_locked_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000228{
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000229 return PyBool_FromLong((long)self->locked);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000230}
231
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000232PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000233"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000234(locked_lock() is an obsolete synonym)\n\
235\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000236Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000237
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700238static PyObject *
239lock_repr(lockobject *self)
240{
241 return PyUnicode_FromFormat("<%s %s object at %p>",
242 self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
243}
244
Victor Stinner87255be2020-04-07 23:11:49 +0200245#ifdef HAVE_FORK
246static PyObject *
247lock__at_fork_reinit(lockobject *self, PyObject *Py_UNUSED(args))
248{
249 if (_PyThread_at_fork_reinit(&self->lock_lock) < 0) {
250 PyErr_SetString(ThreadError, "failed to reinitialize lock at fork");
251 return NULL;
252 }
253
254 self->locked = 0;
255
256 Py_RETURN_NONE;
257}
258#endif /* HAVE_FORK */
259
260
Barry Warsawd0c10421996-12-17 00:05:22 +0000261static PyMethodDef lock_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200262 {"acquire_lock", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 METH_VARARGS | METH_KEYWORDS, acquire_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200264 {"acquire", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 METH_VARARGS | METH_KEYWORDS, acquire_doc},
266 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
267 METH_NOARGS, release_doc},
268 {"release", (PyCFunction)lock_PyThread_release_lock,
269 METH_NOARGS, release_doc},
270 {"locked_lock", (PyCFunction)lock_locked_lock,
271 METH_NOARGS, locked_doc},
272 {"locked", (PyCFunction)lock_locked_lock,
273 METH_NOARGS, locked_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200274 {"__enter__", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 METH_VARARGS | METH_KEYWORDS, acquire_doc},
276 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
277 METH_VARARGS, release_doc},
Victor Stinner87255be2020-04-07 23:11:49 +0200278#ifdef HAVE_FORK
279 {"_at_fork_reinit", (PyCFunction)lock__at_fork_reinit,
280 METH_NOARGS, NULL},
281#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000283};
284
Victor Stinner8203c732020-12-16 12:20:33 +0100285PyDoc_STRVAR(lock_doc,
286"A lock object is a synchronization primitive. To create a lock,\n\
287call threading.Lock(). Methods are:\n\
288\n\
289acquire() -- lock the lock, possibly blocking until it can be obtained\n\
290release() -- unlock of the lock\n\
291locked() -- test whether the lock is currently locked\n\
292\n\
293A lock is not owned by the thread that locked it; another thread may\n\
294unlock it. A thread attempting to lock a lock that it has already locked\n\
295will block until another thread unlocks it. Deadlocks may ensue.");
296
Victor Stinner61040132020-12-18 01:39:00 +0100297static PyMemberDef lock_type_members[] = {
298 {"__weaklistoffset__", T_PYSSIZET, offsetof(lockobject, in_weakreflist), READONLY},
299 {NULL},
300};
301
302static PyType_Slot lock_type_slots[] = {
303 {Py_tp_dealloc, (destructor)lock_dealloc},
304 {Py_tp_repr, (reprfunc)lock_repr},
305 {Py_tp_doc, (void *)lock_doc},
306 {Py_tp_methods, lock_methods},
307 {Py_tp_traverse, lock_traverse},
308 {Py_tp_members, lock_type_members},
309 {0, 0}
310};
311
312static PyType_Spec lock_type_spec = {
313 .name = "_thread.lock",
314 .basicsize = sizeof(lockobject),
315 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
316 .slots = lock_type_slots,
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000317};
318
Antoine Pitrou434736a2009-11-10 18:46:01 +0000319/* Recursive lock objects */
320
321typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 PyObject_HEAD
323 PyThread_type_lock rlock_lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200324 unsigned long rlock_owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 unsigned long rlock_count;
326 PyObject *in_weakreflist;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000327} rlockobject;
328
329static void
330rlock_dealloc(rlockobject *self)
331{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 if (self->in_weakreflist != NULL)
333 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner357f5152013-11-05 15:10:19 +0100334 /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed
335 in rlock_new() */
336 if (self->rlock_lock != NULL) {
337 /* Unlock the lock so it's safe to free it */
338 if (self->rlock_count > 0)
339 PyThread_release_lock(self->rlock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340
Victor Stinner357f5152013-11-05 15:10:19 +0100341 PyThread_free_lock(self->rlock_lock);
342 }
Victor Stinner61040132020-12-18 01:39:00 +0100343 PyTypeObject *tp = Py_TYPE(self);
344 tp->tp_free(self);
345 Py_DECREF(tp);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000346}
347
348static PyObject *
349rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
350{
Victor Stinnerf5faad22015-03-28 03:52:05 +0100351 _PyTime_t timeout;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200352 unsigned long tid;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000353 PyLockStatus r = PY_LOCK_ACQUIRED;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000354
Victor Stinnerf5faad22015-03-28 03:52:05 +0100355 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 tid = PyThread_get_thread_ident();
359 if (self->rlock_count > 0 && tid == self->rlock_owner) {
360 unsigned long count = self->rlock_count + 1;
361 if (count <= self->rlock_count) {
362 PyErr_SetString(PyExc_OverflowError,
363 "Internal lock count overflowed");
364 return NULL;
365 }
366 self->rlock_count = count;
367 Py_RETURN_TRUE;
368 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100369 r = acquire_timed(self->rlock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000370 if (r == PY_LOCK_ACQUIRED) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 assert(self->rlock_count == 0);
372 self->rlock_owner = tid;
373 self->rlock_count = 1;
374 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000375 else if (r == PY_LOCK_INTR) {
376 return NULL;
377 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378
Antoine Pitrou810023d2010-12-15 22:59:16 +0000379 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000380}
381
382PyDoc_STRVAR(rlock_acquire_doc,
383"acquire(blocking=True) -> bool\n\
384\n\
385Lock the lock. `blocking` indicates whether we should wait\n\
386for the lock to be available or not. If `blocking` is False\n\
387and another thread holds the lock, the method will return False\n\
388immediately. If `blocking` is True and another thread holds\n\
389the lock, the method will wait for the lock to be released,\n\
390take it and then return True.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000391(note: the blocking operation is interruptible.)\n\
Antoine Pitrou434736a2009-11-10 18:46:01 +0000392\n\
393In all other cases, the method will return True immediately.\n\
394Precisely, if the current thread already holds the lock, its\n\
395internal counter is simply incremented. If nobody holds the lock,\n\
396the lock is taken and its internal counter initialized to 1.");
397
398static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530399rlock_release(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000400{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200401 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrou434736a2009-11-10 18:46:01 +0000402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 if (self->rlock_count == 0 || self->rlock_owner != tid) {
404 PyErr_SetString(PyExc_RuntimeError,
405 "cannot release un-acquired lock");
406 return NULL;
407 }
408 if (--self->rlock_count == 0) {
409 self->rlock_owner = 0;
410 PyThread_release_lock(self->rlock_lock);
411 }
412 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000413}
414
415PyDoc_STRVAR(rlock_release_doc,
416"release()\n\
417\n\
418Release the lock, allowing another thread that is blocked waiting for\n\
419the lock to acquire the lock. The lock must be in the locked state,\n\
420and must be locked by the same thread that unlocks it; otherwise a\n\
421`RuntimeError` is raised.\n\
422\n\
423Do note that if the lock was acquire()d several times in a row by the\n\
424current thread, release() needs to be called as many times for the lock\n\
425to be available for other threads.");
426
427static PyObject *
Victor Stinnere8794522014-01-02 12:47:24 +0100428rlock_acquire_restore(rlockobject *self, PyObject *args)
Antoine Pitrou434736a2009-11-10 18:46:01 +0000429{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200430 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 unsigned long count;
432 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000433
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200434 if (!PyArg_ParseTuple(args, "(kk):_acquire_restore", &count, &owner))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
438 Py_BEGIN_ALLOW_THREADS
439 r = PyThread_acquire_lock(self->rlock_lock, 1);
440 Py_END_ALLOW_THREADS
441 }
442 if (!r) {
443 PyErr_SetString(ThreadError, "couldn't acquire lock");
444 return NULL;
445 }
446 assert(self->rlock_count == 0);
447 self->rlock_owner = owner;
448 self->rlock_count = count;
449 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000450}
451
452PyDoc_STRVAR(rlock_acquire_restore_doc,
453"_acquire_restore(state) -> None\n\
454\n\
455For internal use by `threading.Condition`.");
456
457static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530458rlock_release_save(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000459{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200460 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 unsigned long count;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000462
Victor Stinnerc2824d42011-04-24 23:41:33 +0200463 if (self->rlock_count == 0) {
464 PyErr_SetString(PyExc_RuntimeError,
465 "cannot release un-acquired lock");
466 return NULL;
467 }
468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469 owner = self->rlock_owner;
470 count = self->rlock_count;
471 self->rlock_count = 0;
472 self->rlock_owner = 0;
473 PyThread_release_lock(self->rlock_lock);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200474 return Py_BuildValue("kk", count, owner);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000475}
476
477PyDoc_STRVAR(rlock_release_save_doc,
478"_release_save() -> tuple\n\
479\n\
480For internal use by `threading.Condition`.");
481
482
483static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530484rlock_is_owned(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000485{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200486 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487
488 if (self->rlock_count > 0 && self->rlock_owner == tid) {
489 Py_RETURN_TRUE;
490 }
491 Py_RETURN_FALSE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000492}
493
494PyDoc_STRVAR(rlock_is_owned_doc,
495"_is_owned() -> bool\n\
496\n\
497For internal use by `threading.Condition`.");
498
499static PyObject *
500rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
501{
Victor Stinner87255be2020-04-07 23:11:49 +0200502 rlockobject *self = (rlockobject *) type->tp_alloc(type, 0);
503 if (self == NULL) {
504 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 }
Victor Stinner87255be2020-04-07 23:11:49 +0200506 self->in_weakreflist = NULL;
507 self->rlock_owner = 0;
508 self->rlock_count = 0;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000509
Victor Stinner87255be2020-04-07 23:11:49 +0200510 self->rlock_lock = PyThread_allocate_lock();
511 if (self->rlock_lock == NULL) {
512 Py_DECREF(self);
513 PyErr_SetString(ThreadError, "can't allocate lock");
514 return NULL;
515 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000516 return (PyObject *) self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000517}
518
519static PyObject *
520rlock_repr(rlockobject *self)
521{
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700522 return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>",
523 self->rlock_count ? "locked" : "unlocked",
524 Py_TYPE(self)->tp_name, self->rlock_owner,
525 self->rlock_count, self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000526}
527
528
Victor Stinner87255be2020-04-07 23:11:49 +0200529#ifdef HAVE_FORK
530static PyObject *
531rlock__at_fork_reinit(rlockobject *self, PyObject *Py_UNUSED(args))
532{
533 if (_PyThread_at_fork_reinit(&self->rlock_lock) < 0) {
534 PyErr_SetString(ThreadError, "failed to reinitialize lock at fork");
535 return NULL;
536 }
537
538 self->rlock_owner = 0;
539 self->rlock_count = 0;
540
541 Py_RETURN_NONE;
542}
543#endif /* HAVE_FORK */
544
545
Antoine Pitrou434736a2009-11-10 18:46:01 +0000546static PyMethodDef rlock_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200547 {"acquire", (PyCFunction)(void(*)(void))rlock_acquire,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
549 {"release", (PyCFunction)rlock_release,
550 METH_NOARGS, rlock_release_doc},
551 {"_is_owned", (PyCFunction)rlock_is_owned,
552 METH_NOARGS, rlock_is_owned_doc},
553 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
Victor Stinnere8794522014-01-02 12:47:24 +0100554 METH_VARARGS, rlock_acquire_restore_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 {"_release_save", (PyCFunction)rlock_release_save,
556 METH_NOARGS, rlock_release_save_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200557 {"__enter__", (PyCFunction)(void(*)(void))rlock_acquire,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000558 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
559 {"__exit__", (PyCFunction)rlock_release,
560 METH_VARARGS, rlock_release_doc},
Victor Stinner87255be2020-04-07 23:11:49 +0200561#ifdef HAVE_FORK
562 {"_at_fork_reinit", (PyCFunction)rlock__at_fork_reinit,
563 METH_NOARGS, NULL},
564#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 {NULL, NULL} /* sentinel */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000566};
567
568
Victor Stinner61040132020-12-18 01:39:00 +0100569static PyMemberDef rlock_type_members[] = {
570 {"__weaklistoffset__", T_PYSSIZET, offsetof(rlockobject, in_weakreflist), READONLY},
571 {NULL},
572};
573
574static PyType_Slot rlock_type_slots[] = {
575 {Py_tp_dealloc, (destructor)rlock_dealloc},
576 {Py_tp_repr, (reprfunc)rlock_repr},
577 {Py_tp_methods, rlock_methods},
578 {Py_tp_alloc, PyType_GenericAlloc},
579 {Py_tp_new, rlock_new},
580 {Py_tp_members, rlock_type_members},
581 {0, 0},
582};
583
584static PyType_Spec rlock_type_spec = {
585 .name = "_thread.RLock",
586 .basicsize = sizeof(rlockobject),
587 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
588 .slots = rlock_type_slots,
Antoine Pitrou434736a2009-11-10 18:46:01 +0000589};
590
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000591static lockobject *
Victor Stinner61040132020-12-18 01:39:00 +0100592newlockobject(PyObject *module)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000593{
Victor Stinner61040132020-12-18 01:39:00 +0100594 thread_module_state *state = get_thread_state(module);
595
596 PyTypeObject *type = state->lock_type;
597 lockobject *self = (lockobject *)type->tp_alloc(type, 0);
Victor Stinner8203c732020-12-16 12:20:33 +0100598 if (self == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599 return NULL;
Victor Stinner8203c732020-12-16 12:20:33 +0100600 }
601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 self->lock_lock = PyThread_allocate_lock();
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000603 self->locked = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 self->in_weakreflist = NULL;
Victor Stinner8203c732020-12-16 12:20:33 +0100605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 if (self->lock_lock == NULL) {
607 Py_DECREF(self);
608 PyErr_SetString(ThreadError, "can't allocate lock");
609 return NULL;
610 }
611 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000612}
613
Jim Fultond15dc062004-07-14 19:11:50 +0000614/* Thread-local objects */
615
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000616/* Quick overview:
617
618 We need to be able to reclaim reference cycles as soon as possible
619 (both when a thread is being terminated, or a thread-local object
620 becomes unreachable from user data). Constraints:
621 - it must not be possible for thread-state dicts to be involved in
622 reference cycles (otherwise the cyclic GC will refuse to consider
623 objects referenced from a reachable thread-state dict, even though
624 local_dealloc would clear them)
625 - the death of a thread-state dict must still imply destruction of the
626 corresponding local dicts in all thread-local objects.
627
628 Our implementation uses small "localdummy" objects in order to break
629 the reference chain. These trivial objects are hashable (using the
630 default scheme of identity hashing) and weakrefable.
631 Each thread-state holds a separate localdummy for each local object
632 (as a /strong reference/),
633 and each thread-local object holds a dict mapping /weak references/
634 of localdummies to local dicts.
635
636 Therefore:
637 - only the thread-state dict holds a strong reference to the dummies
638 - only the thread-local object holds a strong reference to the local dicts
639 - only outside objects (application- or library-level) hold strong
640 references to the thread-local objects
641 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
642 dummies attached to that thread are called, and destroy the corresponding
643 local dicts from thread-local objects
644 - as soon as a thread-local object is destroyed, its local dicts are
645 destroyed and its dummies are manually removed from all thread states
646 - the GC can do its work correctly when a thread-local object is dangling,
647 without any interference from the thread-state dicts
648
649 As an additional optimization, each localdummy holds a borrowed reference
650 to the corresponding localdict. This borrowed reference is only used
651 by the thread-local object which has created the localdummy, which should
652 guarantee that the localdict still exists when accessed.
653*/
654
655typedef struct {
656 PyObject_HEAD
657 PyObject *localdict; /* Borrowed reference! */
658 PyObject *weakreflist; /* List of weak references to self */
659} localdummyobject;
660
661static void
662localdummy_dealloc(localdummyobject *self)
663{
664 if (self->weakreflist != NULL)
665 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner61040132020-12-18 01:39:00 +0100666 PyTypeObject *tp = Py_TYPE(self);
667 tp->tp_free((PyObject*)self);
668 Py_DECREF(tp);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000669}
670
Victor Stinner61040132020-12-18 01:39:00 +0100671static PyMemberDef local_dummy_type_members[] = {
672 {"__weaklistoffset__", T_PYSSIZET, offsetof(localdummyobject, weakreflist), READONLY},
673 {NULL},
674};
675
676static PyType_Slot local_dummy_type_slots[] = {
677 {Py_tp_dealloc, (destructor)localdummy_dealloc},
678 {Py_tp_doc, "Thread-local dummy"},
679 {Py_tp_members, local_dummy_type_members},
680 {0, 0}
681};
682
683static PyType_Spec local_dummy_type_spec = {
684 .name = "_thread._localdummy",
685 .basicsize = sizeof(localdummyobject),
686 .flags = Py_TPFLAGS_DEFAULT,
687 .slots = local_dummy_type_slots,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000688};
689
690
Jim Fultond15dc062004-07-14 19:11:50 +0000691typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 PyObject_HEAD
693 PyObject *key;
694 PyObject *args;
695 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000696 PyObject *weakreflist; /* List of weak references to self */
697 /* A {localdummy weakref -> localdict} dict */
698 PyObject *dummies;
699 /* The callback for weakrefs to localdummies */
700 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000701} localobject;
702
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000703/* Forward declaration */
Victor Stinner61040132020-12-18 01:39:00 +0100704static PyObject *_ldict(localobject *self, thread_module_state *state);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000705static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
706
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000707/* Create and register the dummy for the current thread.
708 Returns a borrowed reference of the corresponding local dict */
709static PyObject *
Victor Stinner61040132020-12-18 01:39:00 +0100710_local_create_dummy(localobject *self, thread_module_state *state)
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000711{
Victor Stinner8203c732020-12-16 12:20:33 +0100712 PyObject *ldict = NULL, *wr = NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000713 localdummyobject *dummy = NULL;
Victor Stinner61040132020-12-18 01:39:00 +0100714 PyTypeObject *type = state->local_dummy_type;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000715
Victor Stinner8203c732020-12-16 12:20:33 +0100716 PyObject *tdict = PyThreadState_GetDict();
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000717 if (tdict == NULL) {
718 PyErr_SetString(PyExc_SystemError,
719 "Couldn't get thread-state dictionary");
720 goto err;
721 }
722
723 ldict = PyDict_New();
Victor Stinner8203c732020-12-16 12:20:33 +0100724 if (ldict == NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000725 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100726 }
Victor Stinner61040132020-12-18 01:39:00 +0100727 dummy = (localdummyobject *) type->tp_alloc(type, 0);
Victor Stinner8203c732020-12-16 12:20:33 +0100728 if (dummy == NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000729 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100730 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000731 dummy->localdict = ldict;
732 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
Victor Stinner8203c732020-12-16 12:20:33 +0100733 if (wr == NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000734 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100735 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000736
737 /* As a side-effect, this will cache the weakref's hash before the
738 dummy gets deleted */
Victor Stinner8203c732020-12-16 12:20:33 +0100739 int r = PyDict_SetItem(self->dummies, wr, ldict);
740 if (r < 0) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000741 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100742 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000743 Py_CLEAR(wr);
744 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
Victor Stinner8203c732020-12-16 12:20:33 +0100745 if (r < 0) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000746 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100747 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000748 Py_CLEAR(dummy);
749
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000750 Py_DECREF(ldict);
751 return ldict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000752
753err:
754 Py_XDECREF(ldict);
755 Py_XDECREF(wr);
756 Py_XDECREF(dummy);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000757 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000758}
759
Jim Fultond15dc062004-07-14 19:11:50 +0000760static PyObject *
761local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
762{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000763 static PyMethodDef wr_callback_def = {
764 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
765 };
Jim Fultond15dc062004-07-14 19:11:50 +0000766
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300767 if (type->tp_init == PyBaseObject_Type.tp_init) {
768 int rc = 0;
769 if (args != NULL)
770 rc = PyObject_IsTrue(args);
771 if (rc == 0 && kw != NULL)
772 rc = PyObject_IsTrue(kw);
773 if (rc != 0) {
Victor Stinner8203c732020-12-16 12:20:33 +0100774 if (rc > 0) {
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300775 PyErr_SetString(PyExc_TypeError,
776 "Initialization arguments are not supported");
Victor Stinner8203c732020-12-16 12:20:33 +0100777 }
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300778 return NULL;
779 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000780 }
Jim Fultond15dc062004-07-14 19:11:50 +0000781
Victor Stinner61040132020-12-18 01:39:00 +0100782 PyObject *module = _PyType_GetModuleByDef(type, &thread_module);
783 thread_module_state *state = get_thread_state(module);
784
785 localobject *self = (localobject *)type->tp_alloc(type, 0);
Victor Stinner8203c732020-12-16 12:20:33 +0100786 if (self == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 return NULL;
Victor Stinner8203c732020-12-16 12:20:33 +0100788 }
Jim Fultond15dc062004-07-14 19:11:50 +0000789
Victor Stinner8203c732020-12-16 12:20:33 +0100790 self->args = Py_XNewRef(args);
791 self->kw = Py_XNewRef(kw);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000792 self->key = PyUnicode_FromFormat("thread.local.%p", self);
Victor Stinner8203c732020-12-16 12:20:33 +0100793 if (self->key == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000794 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100795 }
Jim Fultond15dc062004-07-14 19:11:50 +0000796
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000797 self->dummies = PyDict_New();
Victor Stinner8203c732020-12-16 12:20:33 +0100798 if (self->dummies == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000799 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100800 }
Jim Fultond15dc062004-07-14 19:11:50 +0000801
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000802 /* We use a weak reference to self in the callback closure
803 in order to avoid spurious reference cycles */
Victor Stinner8203c732020-12-16 12:20:33 +0100804 PyObject *wr = PyWeakref_NewRef((PyObject *) self, NULL);
805 if (wr == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000806 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100807 }
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200808 self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000809 Py_DECREF(wr);
Victor Stinner8203c732020-12-16 12:20:33 +0100810 if (self->wr_callback == NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000811 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100812 }
Victor Stinner61040132020-12-18 01:39:00 +0100813 if (_local_create_dummy(self, state) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000814 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100815 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000816 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000817
818 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000819 Py_DECREF(self);
820 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000821}
822
823static int
824local_traverse(localobject *self, visitproc visit, void *arg)
825{
Victor Stinner61040132020-12-18 01:39:00 +0100826 Py_VISIT(Py_TYPE(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000827 Py_VISIT(self->args);
828 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000829 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000830 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000831}
832
833static int
834local_clear(localobject *self)
835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000836 Py_CLEAR(self->args);
837 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000838 Py_CLEAR(self->dummies);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000839 Py_CLEAR(self->wr_callback);
840 /* Remove all strong references to dummies from the thread states */
Victor Stinner839184f2021-02-19 15:51:36 +0100841 if (self->key) {
842 PyInterpreterState *interp = _PyInterpreterState_GET();
843 PyThreadState *tstate = PyInterpreterState_ThreadHead(interp);
844 for(; tstate; tstate = PyThreadState_Next(tstate)) {
845 if (tstate->dict == NULL) {
846 continue;
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200847 }
Victor Stinner839184f2021-02-19 15:51:36 +0100848 PyObject *v = _PyDict_Pop(tstate->dict, self->key, Py_None);
849 if (v != NULL) {
850 Py_DECREF(v);
851 }
852 else {
853 PyErr_Clear();
854 }
855 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000856 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000857 return 0;
858}
Jim Fultond15dc062004-07-14 19:11:50 +0000859
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000860static void
861local_dealloc(localobject *self)
862{
863 /* Weakrefs must be invalidated right now, otherwise they can be used
864 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
Victor Stinner8203c732020-12-16 12:20:33 +0100865 if (self->weakreflist != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000866 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner8203c732020-12-16 12:20:33 +0100867 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000868
869 PyObject_GC_UnTrack(self);
870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000871 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000872 Py_XDECREF(self->key);
Victor Stinner61040132020-12-18 01:39:00 +0100873
874 PyTypeObject *tp = Py_TYPE(self);
875 tp->tp_free((PyObject*)self);
876 Py_DECREF(tp);
Jim Fultond15dc062004-07-14 19:11:50 +0000877}
878
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000879/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000880static PyObject *
Victor Stinner61040132020-12-18 01:39:00 +0100881_ldict(localobject *self, thread_module_state *state)
Jim Fultond15dc062004-07-14 19:11:50 +0000882{
Victor Stinner8203c732020-12-16 12:20:33 +0100883 PyObject *tdict = PyThreadState_GetDict();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000884 if (tdict == NULL) {
885 PyErr_SetString(PyExc_SystemError,
886 "Couldn't get thread-state dictionary");
887 return NULL;
888 }
Jim Fultond15dc062004-07-14 19:11:50 +0000889
Victor Stinner8203c732020-12-16 12:20:33 +0100890 PyObject *ldict;
891 PyObject *dummy = PyDict_GetItemWithError(tdict, self->key);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000892 if (dummy == NULL) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200893 if (PyErr_Occurred()) {
894 return NULL;
895 }
Victor Stinner61040132020-12-18 01:39:00 +0100896 ldict = _local_create_dummy(self, state);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000897 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
901 Py_TYPE(self)->tp_init((PyObject*)self,
902 self->args, self->kw) < 0) {
903 /* we need to get rid of ldict from thread so
904 we create a new one the next time we do an attr
Ezio Melotti42da6632011-03-15 05:18:48 +0200905 access */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 PyDict_DelItem(tdict, self->key);
907 return NULL;
908 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000909 }
910 else {
Victor Stinner61040132020-12-18 01:39:00 +0100911 assert(Py_IS_TYPE(dummy, state->local_dummy_type));
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000912 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 }
Jim Fultond15dc062004-07-14 19:11:50 +0000914
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000915 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000916}
917
Jim Fultond15dc062004-07-14 19:11:50 +0000918static int
919local_setattro(localobject *self, PyObject *name, PyObject *v)
920{
Victor Stinner61040132020-12-18 01:39:00 +0100921 PyObject *module = _PyType_GetModuleByDef(Py_TYPE(self), &thread_module);
922 thread_module_state *state = get_thread_state(module);
923
924 PyObject *ldict = _ldict(self, state);
Victor Stinner8203c732020-12-16 12:20:33 +0100925 if (ldict == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 return -1;
Victor Stinner8203c732020-12-16 12:20:33 +0100927 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000928
Victor Stinner8203c732020-12-16 12:20:33 +0100929 PyObject *str_dict = _PyUnicode_FromId(&PyId___dict__); // borrowed ref
930 if (str_dict == NULL) {
931 return -1;
932 }
933
934 int r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
935 if (r == -1) {
936 return -1;
937 }
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000938 if (r == 1) {
939 PyErr_Format(PyExc_AttributeError,
940 "'%.50s' object attribute '%U' is read-only",
941 Py_TYPE(self)->tp_name, name);
942 return -1;
943 }
Jim Fultond15dc062004-07-14 19:11:50 +0000944
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000945 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000946}
947
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000948static PyObject *local_getattro(localobject *, PyObject *);
949
Victor Stinner61040132020-12-18 01:39:00 +0100950static PyMemberDef local_type_members[] = {
951 {"__weaklistoffset__", T_PYSSIZET, offsetof(localobject, weakreflist), READONLY},
952 {NULL},
953};
954
955static PyType_Slot local_type_slots[] = {
956 {Py_tp_dealloc, (destructor)local_dealloc},
957 {Py_tp_getattro, (getattrofunc)local_getattro},
958 {Py_tp_setattro, (setattrofunc)local_setattro},
959 {Py_tp_doc, "Thread-local data"},
960 {Py_tp_traverse, (traverseproc)local_traverse},
961 {Py_tp_clear, (inquiry)local_clear},
962 {Py_tp_new, local_new},
963 {Py_tp_members, local_type_members},
964 {0, 0}
965};
966
967static PyType_Spec local_type_spec = {
968 .name = "_thread._local",
969 .basicsize = sizeof(localobject),
970 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
971 .slots = local_type_slots,
Jim Fultond15dc062004-07-14 19:11:50 +0000972};
973
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000974static PyObject *
975local_getattro(localobject *self, PyObject *name)
976{
Victor Stinner61040132020-12-18 01:39:00 +0100977 PyObject *module = _PyType_GetModuleByDef(Py_TYPE(self), &thread_module);
978 thread_module_state *state = get_thread_state(module);
979
980 PyObject *ldict = _ldict(self, state);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 if (ldict == NULL)
982 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000983
Victor Stinner8203c732020-12-16 12:20:33 +0100984 PyObject *str_dict = _PyUnicode_FromId(&PyId___dict__); // borrowed ref
985 if (str_dict == NULL) {
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000986 return NULL;
Victor Stinner8203c732020-12-16 12:20:33 +0100987 }
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000988
Victor Stinner8203c732020-12-16 12:20:33 +0100989 int r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
990 if (r == 1) {
991 return Py_NewRef(ldict);
992 }
993 if (r == -1) {
994 return NULL;
995 }
996
Victor Stinner61040132020-12-18 01:39:00 +0100997 if (!Py_IS_TYPE(self, state->local_type)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000998 /* use generic lookup for subtypes */
Victor Stinner8203c732020-12-16 12:20:33 +0100999 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name,
1000 ldict, 0);
1001 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 /* Optimization: just look in dict ourselves */
Victor Stinner8203c732020-12-16 12:20:33 +01001004 PyObject *value = PyDict_GetItemWithError(ldict, name);
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001005 if (value != NULL) {
Victor Stinner8203c732020-12-16 12:20:33 +01001006 return Py_NewRef(value);
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001007 }
Victor Stinner8203c732020-12-16 12:20:33 +01001008 if (PyErr_Occurred()) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001009 return NULL;
1010 }
Victor Stinner8203c732020-12-16 12:20:33 +01001011
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001012 /* Fall back on generic to get __class__ and __dict__ */
1013 return _PyObject_GenericGetAttrWithDict(
1014 (PyObject *)self, name, ldict, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001015}
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001016
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001017/* Called when a dummy is destroyed. */
1018static PyObject *
1019_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
1020{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001021 assert(PyWeakref_CheckRef(localweakref));
Victor Stinner8203c732020-12-16 12:20:33 +01001022 PyObject *obj = PyWeakref_GET_OBJECT(localweakref);
1023 if (obj == Py_None) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001024 Py_RETURN_NONE;
Victor Stinner8203c732020-12-16 12:20:33 +01001025 }
1026
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001027 /* If the thread-local object is still alive and not being cleared,
1028 remove the corresponding local dict */
Victor Stinner8203c732020-12-16 12:20:33 +01001029 localobject *self = (localobject *)Py_NewRef(obj);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001030 if (self->dummies != NULL) {
1031 PyObject *ldict;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001032 ldict = PyDict_GetItemWithError(self->dummies, dummyweakref);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001033 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001034 PyDict_DelItem(self->dummies, dummyweakref);
1035 }
1036 if (PyErr_Occurred())
1037 PyErr_WriteUnraisable(obj);
1038 }
1039 Py_DECREF(obj);
1040 Py_RETURN_NONE;
1041}
1042
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001043/* Module functions */
1044
Guido van Rossuma027efa1997-05-05 20:56:21 +00001045struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 PyInterpreterState *interp;
1047 PyObject *func;
1048 PyObject *args;
Victor Stinner8203c732020-12-16 12:20:33 +01001049 PyObject *kwargs;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001050 PyThreadState *tstate;
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001051 _PyRuntimeState *runtime;
Guido van Rossuma027efa1997-05-05 20:56:21 +00001052};
1053
Victor Stinner8203c732020-12-16 12:20:33 +01001054
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001055static void
Victor Stinner8203c732020-12-16 12:20:33 +01001056thread_bootstate_free(struct bootstate *boot)
1057{
1058 Py_DECREF(boot->func);
1059 Py_DECREF(boot->args);
1060 Py_XDECREF(boot->kwargs);
1061 PyMem_Free(boot);
1062}
1063
1064
1065static void
1066thread_run(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001067{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 struct bootstate *boot = (struct bootstate *) boot_raw;
1069 PyThreadState *tstate;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 tstate = boot->tstate;
1072 tstate->thread_id = PyThread_get_thread_ident();
Victor Stinner01b1cc12019-11-20 02:27:56 +01001073 _PyThreadState_Init(tstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 PyEval_AcquireThread(tstate);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001075 tstate->interp->num_threads++;
Victor Stinner8203c732020-12-16 12:20:33 +01001076
1077 PyObject *res = PyObject_Call(boot->func, boot->args, boot->kwargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001078 if (res == NULL) {
1079 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Victor Stinner8b095002019-05-29 02:57:56 +02001080 /* SystemExit is ignored silently */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001081 PyErr_Clear();
1082 else {
Victor Stinner8b095002019-05-29 02:57:56 +02001083 _PyErr_WriteUnraisableMsg("in thread started by", boot->func);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001084 }
1085 }
Victor Stinner8b095002019-05-29 02:57:56 +02001086 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 Py_DECREF(res);
Victor Stinner8b095002019-05-29 02:57:56 +02001088 }
Victor Stinner8203c732020-12-16 12:20:33 +01001089
1090 thread_bootstate_free(boot);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001091 tstate->interp->num_threads--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 PyThreadState_Clear(tstate);
Victor Stinner23ef89d2020-03-18 02:26:04 +01001093 _PyThreadState_DeleteCurrent(tstate);
Victor Stinner8203c732020-12-16 12:20:33 +01001094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001096}
1097
Barry Warsawd0c10421996-12-17 00:05:22 +00001098static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001099thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001100{
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001101 _PyRuntimeState *runtime = &_PyRuntime;
Victor Stinner8203c732020-12-16 12:20:33 +01001102 PyObject *func, *args, *kwargs = NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
Victor Stinner8203c732020-12-16 12:20:33 +01001105 &func, &args, &kwargs))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001106 return NULL;
1107 if (!PyCallable_Check(func)) {
1108 PyErr_SetString(PyExc_TypeError,
1109 "first arg must be callable");
1110 return NULL;
1111 }
1112 if (!PyTuple_Check(args)) {
1113 PyErr_SetString(PyExc_TypeError,
1114 "2nd arg must be a tuple");
1115 return NULL;
1116 }
Victor Stinner8203c732020-12-16 12:20:33 +01001117 if (kwargs != NULL && !PyDict_Check(kwargs)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 PyErr_SetString(PyExc_TypeError,
1119 "optional 3rd arg must be a dictionary");
1120 return NULL;
1121 }
Victor Stinner252346a2020-05-01 11:33:44 +02001122
1123 PyInterpreterState *interp = _PyInterpreterState_GET();
1124 if (interp->config._isolated_interpreter) {
1125 PyErr_SetString(PyExc_RuntimeError,
1126 "thread is not supported for isolated subinterpreters");
1127 return NULL;
1128 }
1129
Victor Stinner8203c732020-12-16 12:20:33 +01001130 struct bootstate *boot = PyMem_NEW(struct bootstate, 1);
1131 if (boot == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001132 return PyErr_NoMemory();
Victor Stinner8203c732020-12-16 12:20:33 +01001133 }
Victor Stinner81a7be32020-04-14 15:14:01 +02001134 boot->interp = _PyInterpreterState_GET();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 boot->tstate = _PyThreadState_Prealloc(boot->interp);
1136 if (boot->tstate == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01001137 PyMem_Free(boot);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 return PyErr_NoMemory();
1139 }
Victor Stinner8203c732020-12-16 12:20:33 +01001140 boot->runtime = runtime;
1141 boot->func = Py_NewRef(func);
1142 boot->args = Py_NewRef(args);
1143 boot->kwargs = Py_XNewRef(kwargs);
Victor Stinner3225b9f2020-03-09 20:56:57 +01001144
Victor Stinner8203c732020-12-16 12:20:33 +01001145 unsigned long ident = PyThread_start_new_thread(thread_run, (void*) boot);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001146 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 PyErr_SetString(ThreadError, "can't start new thread");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 PyThreadState_Clear(boot->tstate);
Victor Stinner8203c732020-12-16 12:20:33 +01001149 thread_bootstate_free(boot);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 return NULL;
1151 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001152 return PyLong_FromUnsignedLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001153}
1154
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001155PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001156"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001157(start_new() is an obsolete synonym)\n\
1158\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001159Start a new thread and return its identifier. The thread will call the\n\
1160function with positional arguments from the tuple args and keyword arguments\n\
1161taken from the optional dictionary kwargs. The thread exits when the\n\
1162function returns; the return value is ignored. The thread will also exit\n\
1163when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001164printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001165
Barry Warsawd0c10421996-12-17 00:05:22 +00001166static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301167thread_PyThread_exit_thread(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001168{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 PyErr_SetNone(PyExc_SystemExit);
1170 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001171}
1172
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001173PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001174"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001175(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001176\n\
1177This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001178thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001179
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001180static PyObject *
Antoine Pitrouba251c22021-03-11 23:35:45 +01001181thread_PyThread_interrupt_main(PyObject *self, PyObject *args)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001182{
Antoine Pitrouba251c22021-03-11 23:35:45 +01001183 int signum = SIGINT;
1184 if (!PyArg_ParseTuple(args, "|i:signum", &signum)) {
1185 return NULL;
1186 }
1187
1188 if (PyErr_SetInterruptEx(signum)) {
1189 PyErr_SetString(PyExc_ValueError, "signal number out of range");
1190 return NULL;
1191 }
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001192 Py_RETURN_NONE;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001193}
1194
1195PyDoc_STRVAR(interrupt_doc,
Antoine Pitrouba251c22021-03-11 23:35:45 +01001196"interrupt_main(signum=signal.SIGINT, /)\n\
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001197\n\
Antoine Pitrouba251c22021-03-11 23:35:45 +01001198Simulate the arrival of the given signal in the main thread,\n\
1199where the corresponding signal handler will be executed.\n\
1200If *signum* is omitted, SIGINT is assumed.\n\
1201A subthread can use this function to interrupt the main thread.\n\
1202\n\
1203Note: the default signal hander for SIGINT raises ``KeyboardInterrupt``."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001204);
1205
Victor Stinner61040132020-12-18 01:39:00 +01001206static lockobject *newlockobject(PyObject *module);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001207
Barry Warsawd0c10421996-12-17 00:05:22 +00001208static PyObject *
Victor Stinner8203c732020-12-16 12:20:33 +01001209thread_PyThread_allocate_lock(PyObject *module, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001210{
Victor Stinner61040132020-12-18 01:39:00 +01001211 return (PyObject *) newlockobject(module);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001212}
1213
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001214PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001215"allocate_lock() -> lock object\n\
1216(allocate() is an obsolete synonym)\n\
1217\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001218Create a new lock object. See help(type(threading.Lock())) for\n\
1219information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001220
Barry Warsawd0c10421996-12-17 00:05:22 +00001221static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301222thread_get_ident(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001223{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001224 unsigned long ident = PyThread_get_thread_ident();
1225 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001226 PyErr_SetString(ThreadError, "no current thread ident");
1227 return NULL;
1228 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001229 return PyLong_FromUnsignedLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001230}
1231
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001232PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001233"get_ident() -> integer\n\
1234\n\
1235Return a non-zero integer that uniquely identifies the current thread\n\
1236amongst other threads that exist simultaneously.\n\
1237This may be used to identify per-thread resources.\n\
1238Even though on some platforms threads identities may appear to be\n\
1239allocated consecutive numbers starting at 1, this behavior should not\n\
1240be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001241A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001242
Jake Teslerb121f632019-05-22 08:43:17 -07001243#ifdef PY_HAVE_THREAD_NATIVE_ID
1244static PyObject *
1245thread_get_native_id(PyObject *self, PyObject *Py_UNUSED(ignored))
1246{
1247 unsigned long native_id = PyThread_get_thread_native_id();
1248 return PyLong_FromUnsignedLong(native_id);
1249}
1250
1251PyDoc_STRVAR(get_native_id_doc,
1252"get_native_id() -> integer\n\
1253\n\
1254Return a non-negative integer identifying the thread as reported\n\
1255by the OS (kernel). This may be used to uniquely identify a\n\
1256particular thread within a system.");
1257#endif
1258
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001259static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301260thread__count(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001261{
Victor Stinner81a7be32020-04-14 15:14:01 +02001262 PyInterpreterState *interp = _PyInterpreterState_GET();
Victor Stinnercaba55b2018-08-03 15:33:52 +02001263 return PyLong_FromLong(interp->num_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001264}
1265
1266PyDoc_STRVAR(_count_doc,
1267"_count() -> integer\n\
1268\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001269\
oldkaa0735f2018-02-02 16:52:55 +08001270Return the number of currently running Python threads, excluding\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001271the main thread. The returned number comprises all threads created\n\
1272through `start_new_thread()` as well as `threading.Thread`, and not\n\
1273yet finished.\n\
1274\n\
1275This function is meant for internal and specialized purposes only.\n\
1276In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001277
Antoine Pitrou7b476992013-09-07 23:38:37 +02001278static void
Victor Stinnera42de742018-11-22 10:25:22 +01001279release_sentinel(void *wr_raw)
Antoine Pitrou7b476992013-09-07 23:38:37 +02001280{
Victor Stinnera42de742018-11-22 10:25:22 +01001281 PyObject *wr = _PyObject_CAST(wr_raw);
Antoine Pitrou7b476992013-09-07 23:38:37 +02001282 /* Tricky: this function is called when the current thread state
1283 is being deleted. Therefore, only simple C code can safely
1284 execute here. */
1285 PyObject *obj = PyWeakref_GET_OBJECT(wr);
1286 lockobject *lock;
1287 if (obj != Py_None) {
Antoine Pitrou7b476992013-09-07 23:38:37 +02001288 lock = (lockobject *) obj;
1289 if (lock->locked) {
1290 PyThread_release_lock(lock->lock_lock);
1291 lock->locked = 0;
1292 }
1293 }
1294 /* Deallocating a weakref with a NULL callback only calls
1295 PyObject_GC_Del(), which can't call any Python code. */
1296 Py_DECREF(wr);
1297}
1298
1299static PyObject *
Victor Stinner8203c732020-12-16 12:20:33 +01001300thread__set_sentinel(PyObject *module, PyObject *Py_UNUSED(ignored))
Antoine Pitrou7b476992013-09-07 23:38:37 +02001301{
1302 PyObject *wr;
1303 PyThreadState *tstate = PyThreadState_Get();
1304 lockobject *lock;
1305
1306 if (tstate->on_delete_data != NULL) {
1307 /* We must support the re-creation of the lock from a
1308 fork()ed child. */
1309 assert(tstate->on_delete == &release_sentinel);
1310 wr = (PyObject *) tstate->on_delete_data;
1311 tstate->on_delete = NULL;
1312 tstate->on_delete_data = NULL;
1313 Py_DECREF(wr);
1314 }
Victor Stinner61040132020-12-18 01:39:00 +01001315 lock = newlockobject(module);
Antoine Pitrou7b476992013-09-07 23:38:37 +02001316 if (lock == NULL)
1317 return NULL;
1318 /* The lock is owned by whoever called _set_sentinel(), but the weakref
1319 hangs to the thread state. */
1320 wr = PyWeakref_NewRef((PyObject *) lock, NULL);
1321 if (wr == NULL) {
1322 Py_DECREF(lock);
1323 return NULL;
1324 }
1325 tstate->on_delete_data = (void *) wr;
1326 tstate->on_delete = &release_sentinel;
1327 return (PyObject *) lock;
1328}
1329
1330PyDoc_STRVAR(_set_sentinel_doc,
1331"_set_sentinel() -> lock\n\
1332\n\
1333Set a sentinel lock that will be released when the current thread\n\
1334state is finalized (after it is untied from the interpreter).\n\
1335\n\
1336This is a private API for the threading module.");
1337
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001338static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001339thread_stack_size(PyObject *self, PyObject *args)
1340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 size_t old_size;
1342 Py_ssize_t new_size = 0;
1343 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1346 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 if (new_size < 0) {
1349 PyErr_SetString(PyExc_ValueError,
1350 "size must be 0 or a positive value");
1351 return NULL;
1352 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 rc = PyThread_set_stacksize((size_t) new_size);
1357 if (rc == -1) {
1358 PyErr_Format(PyExc_ValueError,
1359 "size not valid: %zd bytes",
1360 new_size);
1361 return NULL;
1362 }
1363 if (rc == -2) {
1364 PyErr_SetString(ThreadError,
1365 "setting stack size not supported");
1366 return NULL;
1367 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001370}
1371
1372PyDoc_STRVAR(stack_size_doc,
1373"stack_size([size]) -> size\n\
1374\n\
1375Return the thread stack size used when creating new threads. The\n\
1376optional size argument specifies the stack size (in bytes) to be used\n\
1377for subsequently created threads, and must be 0 (use platform or\n\
1378configured default) or a positive integer value of at least 32,768 (32k).\n\
1379If changing the thread stack size is unsupported, a ThreadError\n\
1380exception is raised. If the specified size is invalid, a ValueError\n\
1381exception is raised, and the stack size is unmodified. 32k bytes\n\
1382 currently the minimum supported stack size value to guarantee\n\
1383sufficient stack space for the interpreter itself.\n\
1384\n\
1385Note that some platforms may have particular restrictions on values for\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001386the stack size, such as requiring a minimum stack size larger than 32 KiB or\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001387requiring allocation in multiples of the system memory page size\n\
1388- platform documentation should be referred to for more information\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001389(4 KiB pages are common; using multiples of 4096 for the stack size is\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001390the suggested approach in the absence of more specific information).");
1391
Victor Stinnercd590a72019-05-28 00:39:52 +02001392static int
1393thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value,
1394 PyObject *exc_traceback, PyObject *thread)
1395{
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001396 _Py_IDENTIFIER(name);
Victor Stinnercd590a72019-05-28 00:39:52 +02001397 /* print(f"Exception in thread {thread.name}:", file=file) */
1398 if (PyFile_WriteString("Exception in thread ", file) < 0) {
1399 return -1;
1400 }
1401
1402 PyObject *name = NULL;
1403 if (thread != Py_None) {
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001404 if (_PyObject_LookupAttrId(thread, &PyId_name, &name) < 0) {
1405 return -1;
1406 }
Victor Stinnercd590a72019-05-28 00:39:52 +02001407 }
1408 if (name != NULL) {
1409 if (PyFile_WriteObject(name, file, Py_PRINT_RAW) < 0) {
1410 Py_DECREF(name);
1411 return -1;
1412 }
1413 Py_DECREF(name);
1414 }
1415 else {
Victor Stinnercd590a72019-05-28 00:39:52 +02001416 unsigned long ident = PyThread_get_thread_ident();
1417 PyObject *str = PyUnicode_FromFormat("%lu", ident);
1418 if (str != NULL) {
1419 if (PyFile_WriteObject(str, file, Py_PRINT_RAW) < 0) {
1420 Py_DECREF(str);
1421 return -1;
1422 }
1423 Py_DECREF(str);
1424 }
1425 else {
1426 PyErr_Clear();
1427
1428 if (PyFile_WriteString("<failed to get thread name>", file) < 0) {
1429 return -1;
1430 }
1431 }
1432 }
1433
1434 if (PyFile_WriteString(":\n", file) < 0) {
1435 return -1;
1436 }
1437
1438 /* Display the traceback */
1439 _PyErr_Display(file, exc_type, exc_value, exc_traceback);
1440
1441 /* Call file.flush() */
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001442 PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
Victor Stinnercd590a72019-05-28 00:39:52 +02001443 if (!res) {
1444 return -1;
1445 }
1446 Py_DECREF(res);
1447
1448 return 0;
1449}
1450
1451
1452PyDoc_STRVAR(ExceptHookArgs__doc__,
1453"ExceptHookArgs\n\
1454\n\
1455Type used to pass arguments to threading.excepthook.");
1456
1457static PyTypeObject ExceptHookArgsType;
1458
1459static PyStructSequence_Field ExceptHookArgs_fields[] = {
1460 {"exc_type", "Exception type"},
1461 {"exc_value", "Exception value"},
1462 {"exc_traceback", "Exception traceback"},
1463 {"thread", "Thread"},
1464 {0}
1465};
1466
1467static PyStructSequence_Desc ExceptHookArgs_desc = {
Victor Stinner8203c732020-12-16 12:20:33 +01001468 .name = "_thread._ExceptHookArgs",
Victor Stinnercd590a72019-05-28 00:39:52 +02001469 .doc = ExceptHookArgs__doc__,
1470 .fields = ExceptHookArgs_fields,
1471 .n_in_sequence = 4
1472};
1473
1474
1475static PyObject *
1476thread_excepthook(PyObject *self, PyObject *args)
1477{
Andy Lester55728702020-03-06 16:53:17 -06001478 if (!Py_IS_TYPE(args, &ExceptHookArgsType)) {
Victor Stinnercd590a72019-05-28 00:39:52 +02001479 PyErr_SetString(PyExc_TypeError,
1480 "_thread.excepthook argument type "
1481 "must be ExceptHookArgs");
1482 return NULL;
1483 }
1484
1485 /* Borrowed reference */
1486 PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0);
1487 if (exc_type == PyExc_SystemExit) {
1488 /* silently ignore SystemExit */
1489 Py_RETURN_NONE;
1490 }
1491
1492 /* Borrowed references */
1493 PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1);
1494 PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
1495 PyObject *thread = PyStructSequence_GET_ITEM(args, 3);
1496
1497 PyObject *file = _PySys_GetObjectId(&PyId_stderr);
1498 if (file == NULL || file == Py_None) {
1499 if (thread == Py_None) {
1500 /* do nothing if sys.stderr is None and thread is None */
1501 Py_RETURN_NONE;
1502 }
1503
1504 file = PyObject_GetAttrString(thread, "_stderr");
1505 if (file == NULL) {
1506 return NULL;
1507 }
1508 if (file == Py_None) {
1509 Py_DECREF(file);
1510 /* do nothing if sys.stderr is None and sys.stderr was None
1511 when the thread was created */
1512 Py_RETURN_NONE;
1513 }
1514 }
1515 else {
1516 Py_INCREF(file);
1517 }
1518
1519 int res = thread_excepthook_file(file, exc_type, exc_value, exc_tb,
1520 thread);
1521 Py_DECREF(file);
1522 if (res < 0) {
1523 return NULL;
1524 }
1525
1526 Py_RETURN_NONE;
1527}
1528
1529PyDoc_STRVAR(excepthook_doc,
1530"excepthook(exc_type, exc_value, exc_traceback, thread)\n\
1531\n\
1532Handle uncaught Thread.run() exception.");
1533
Barry Warsawd0c10421996-12-17 00:05:22 +00001534static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001536 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001538 METH_VARARGS, start_new_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301539 {"allocate_lock", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301541 {"allocate", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301543 {"exit_thread", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301545 {"exit", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 METH_NOARGS, exit_doc},
Antoine Pitrouba251c22021-03-11 23:35:45 +01001547 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
1548 METH_VARARGS, interrupt_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301549 {"get_ident", thread_get_ident,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001550 METH_NOARGS, get_ident_doc},
Jake Teslerb121f632019-05-22 08:43:17 -07001551#ifdef PY_HAVE_THREAD_NATIVE_ID
1552 {"get_native_id", thread_get_native_id,
1553 METH_NOARGS, get_native_id_doc},
1554#endif
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301555 {"_count", thread__count,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 METH_NOARGS, _count_doc},
1557 {"stack_size", (PyCFunction)thread_stack_size,
Victor Stinner754851f2011-04-19 23:58:51 +02001558 METH_VARARGS, stack_size_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301559 {"_set_sentinel", thread__set_sentinel,
Antoine Pitrou7b476992013-09-07 23:38:37 +02001560 METH_NOARGS, _set_sentinel_doc},
Victor Stinnercd590a72019-05-28 00:39:52 +02001561 {"_excepthook", thread_excepthook,
1562 METH_O, excepthook_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001563 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001564};
1565
1566
1567/* Initialization function */
1568
Victor Stinner8203c732020-12-16 12:20:33 +01001569static int
Victor Stinner61040132020-12-18 01:39:00 +01001570thread_module_exec(PyObject *module)
Victor Stinner8203c732020-12-16 12:20:33 +01001571{
Victor Stinner61040132020-12-18 01:39:00 +01001572 thread_module_state *state = get_thread_state(module);
1573 PyObject *d = PyModule_GetDict(module);
1574
Victor Stinner8203c732020-12-16 12:20:33 +01001575 // Initialize the C thread library
1576 PyThread_init_thread();
1577
Victor Stinner61040132020-12-18 01:39:00 +01001578 // Lock
1579 state->lock_type = (PyTypeObject *)PyType_FromSpec(&lock_type_spec);
1580 if (state->lock_type == NULL) {
Victor Stinner8203c732020-12-16 12:20:33 +01001581 return -1;
1582 }
Victor Stinner61040132020-12-18 01:39:00 +01001583 if (PyDict_SetItemString(d, "LockType", (PyObject *)state->lock_type) < 0) {
Victor Stinner8203c732020-12-16 12:20:33 +01001584 return -1;
1585 }
Victor Stinner61040132020-12-18 01:39:00 +01001586
1587 // RLock
1588 PyTypeObject *rlock_type = (PyTypeObject *)PyType_FromSpec(&rlock_type_spec);
1589 if (rlock_type == NULL) {
Victor Stinner8203c732020-12-16 12:20:33 +01001590 return -1;
1591 }
Victor Stinner61040132020-12-18 01:39:00 +01001592 if (PyModule_AddType(module, rlock_type) < 0) {
1593 Py_DECREF(rlock_type);
1594 return -1;
1595 }
1596 Py_DECREF(rlock_type);
1597
1598 // Local dummy
1599 state->local_dummy_type = (PyTypeObject *)PyType_FromSpec(&local_dummy_type_spec);
1600 if (state->local_dummy_type == NULL) {
1601 return -1;
1602 }
1603
1604 // Local
1605 state->local_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &local_type_spec, NULL);
1606 if (state->local_type == NULL) {
1607 return -1;
1608 }
1609 if (PyModule_AddType(module, state->local_type) < 0) {
1610 return -1;
1611 }
1612
Victor Stinner8203c732020-12-16 12:20:33 +01001613 if (ExceptHookArgsType.tp_name == NULL) {
1614 if (PyStructSequence_InitType2(&ExceptHookArgsType,
1615 &ExceptHookArgs_desc) < 0) {
1616 return -1;
1617 }
1618 }
1619
1620 // Add module attributes
Victor Stinner8203c732020-12-16 12:20:33 +01001621 if (PyDict_SetItemString(d, "error", ThreadError) < 0) {
1622 return -1;
1623 }
Victor Stinner8203c732020-12-16 12:20:33 +01001624 if (PyModule_AddType(module, &ExceptHookArgsType) < 0) {
1625 return -1;
1626 }
1627
1628 // TIMEOUT_MAX
1629 double timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6;
1630 double time_max = _PyTime_AsSecondsDouble(_PyTime_MAX);
1631 timeout_max = Py_MIN(timeout_max, time_max);
1632 // Round towards minus infinity
1633 timeout_max = floor(timeout_max);
1634
1635 if (PyModule_AddObject(module, "TIMEOUT_MAX",
1636 PyFloat_FromDouble(timeout_max)) < 0) {
1637 return -1;
1638 }
1639
1640 return 0;
1641}
1642
1643
Victor Stinner61040132020-12-18 01:39:00 +01001644static int
1645thread_module_traverse(PyObject *module, visitproc visit, void *arg)
1646{
1647 thread_module_state *state = get_thread_state(module);
1648 Py_VISIT(state->lock_type);
1649 Py_VISIT(state->local_type);
1650 Py_VISIT(state->local_dummy_type);
1651 return 0;
1652}
1653
1654static int
1655thread_module_clear(PyObject *module)
1656{
1657 thread_module_state *state = get_thread_state(module);
1658 Py_CLEAR(state->lock_type);
1659 Py_CLEAR(state->local_type);
1660 Py_CLEAR(state->local_dummy_type);
1661 return 0;
1662}
1663
1664static void
1665thread_module_free(void *module)
1666{
1667 thread_module_clear((PyObject *)module);
1668}
1669
1670
1671
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001672PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001673"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001674The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001675
Victor Stinner61040132020-12-18 01:39:00 +01001676static PyModuleDef_Slot thread_module_slots[] = {
1677 {Py_mod_exec, thread_module_exec},
1678 {0, NULL}
1679};
1680
1681static struct PyModuleDef thread_module = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001682 PyModuleDef_HEAD_INIT,
Victor Stinner8203c732020-12-16 12:20:33 +01001683 .m_name = "_thread",
1684 .m_doc = thread_doc,
Victor Stinner61040132020-12-18 01:39:00 +01001685 .m_size = sizeof(thread_module_state),
Victor Stinner8203c732020-12-16 12:20:33 +01001686 .m_methods = thread_methods,
Victor Stinner61040132020-12-18 01:39:00 +01001687 .m_traverse = thread_module_traverse,
1688 .m_clear = thread_module_clear,
1689 .m_free = thread_module_free,
1690 .m_slots = thread_module_slots,
Martin v. Löwis1a214512008-06-11 05:26:20 +00001691};
1692
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001693PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001694PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001695{
Victor Stinner61040132020-12-18 01:39:00 +01001696 return PyModuleDef_Init(&thread_module);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001697}