blob: 9b8757715a0b9b1ddd09433af927fc323125c2d8 [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 Stinnercd590a72019-05-28 00:39:52 +02006#include "pycore_pylifecycle.h"
Victor Stinner4a21e572020-04-15 02:35:41 +02007#include "pycore_interp.h" // _PyInterpreterState.num_threads
8#include "pycore_pystate.h" // _PyThreadState_Init()
9#include <stddef.h> // offsetof()
Victor Stinner61040132020-12-18 01:39:00 +010010#include "structmember.h" // PyMemberDef
Guido van Rossum1984f1e1992-08-04 12:41:02 +000011
Victor Stinner8203c732020-12-16 12:20:33 +010012// ThreadError is just an alias to PyExc_RuntimeError
13#define ThreadError PyExc_RuntimeError
14
15_Py_IDENTIFIER(__dict__);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000016
Victor Stinnerbd303c12013-11-07 23:07:29 +010017_Py_IDENTIFIER(stderr);
Victor Stinnercd590a72019-05-28 00:39:52 +020018_Py_IDENTIFIER(flush);
Victor Stinnerbd303c12013-11-07 23:07:29 +010019
Victor Stinner8203c732020-12-16 12:20:33 +010020
Victor Stinner61040132020-12-18 01:39:00 +010021// Forward declarations
22static struct PyModuleDef thread_module;
23
24
25typedef struct {
26 PyTypeObject *lock_type;
27 PyTypeObject *local_type;
28 PyTypeObject *local_dummy_type;
29} thread_module_state;
30
31static inline thread_module_state*
32get_thread_state(PyObject *module)
33{
34 void *state = PyModule_GetState(module);
35 assert(state != NULL);
36 return (thread_module_state *)state;
37}
38
39
Guido van Rossum1984f1e1992-08-04 12:41:02 +000040/* Lock objects */
41
42typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000043 PyObject_HEAD
44 PyThread_type_lock lock_lock;
45 PyObject *in_weakreflist;
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000046 char locked; /* for sanity checking */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000047} lockobject;
48
Victor Stinner61040132020-12-18 01:39:00 +010049static int
50lock_traverse(lockobject *self, visitproc visit, void *arg)
51{
52 Py_VISIT(Py_TYPE(self));
53 return 0;
54}
55
Guido van Rossum1984f1e1992-08-04 12:41:02 +000056static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000057lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000058{
Victor Stinner8203c732020-12-16 12:20:33 +010059 if (self->in_weakreflist != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner8203c732020-12-16 12:20:33 +010061 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062 if (self->lock_lock != NULL) {
63 /* Unlock the lock so it's safe to free it */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000064 if (self->locked)
65 PyThread_release_lock(self->lock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066 PyThread_free_lock(self->lock_lock);
67 }
Victor Stinner61040132020-12-18 01:39:00 +010068 PyTypeObject *tp = Py_TYPE(self);
69 tp->tp_free((PyObject*)self);
70 Py_DECREF(tp);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000071}
72
Antoine Pitrou810023d2010-12-15 22:59:16 +000073/* Helper to acquire an interruptible lock with a timeout. If the lock acquire
74 * is interrupted, signal handlers are run, and if they raise an exception,
75 * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE
Raymond Hettinger15f44ab2016-08-30 10:47:49 -070076 * are returned, depending on whether the lock can be acquired within the
Antoine Pitrou810023d2010-12-15 22:59:16 +000077 * timeout.
78 */
79static PyLockStatus
Victor Stinnerf5faad22015-03-28 03:52:05 +010080acquire_timed(PyThread_type_lock lock, _PyTime_t timeout)
Antoine Pitrou810023d2010-12-15 22:59:16 +000081{
82 PyLockStatus r;
Victor Stinnerf5faad22015-03-28 03:52:05 +010083 _PyTime_t endtime = 0;
Antoine Pitrou810023d2010-12-15 22:59:16 +000084
Victor Stinner8203c732020-12-16 12:20:33 +010085 if (timeout > 0) {
Victor Stinnerf5faad22015-03-28 03:52:05 +010086 endtime = _PyTime_GetMonotonicClock() + timeout;
Victor Stinner8203c732020-12-16 12:20:33 +010087 }
Antoine Pitrou810023d2010-12-15 22:59:16 +000088
89 do {
Victor Stinner8203c732020-12-16 12:20:33 +010090 _PyTime_t microseconds;
Victor Stinner869e1772015-03-30 03:49:14 +020091 microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING);
Victor Stinnerf5faad22015-03-28 03:52:05 +010092
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000093 /* first a simple non-blocking try without releasing the GIL */
94 r = PyThread_acquire_lock_timed(lock, 0, 0);
95 if (r == PY_LOCK_FAILURE && microseconds != 0) {
96 Py_BEGIN_ALLOW_THREADS
97 r = PyThread_acquire_lock_timed(lock, microseconds, 1);
98 Py_END_ALLOW_THREADS
Victor Stinner357f5152013-11-05 15:10:19 +010099 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000100
101 if (r == PY_LOCK_INTR) {
102 /* Run signal handlers if we were interrupted. Propagate
103 * exceptions from signal handlers, such as KeyboardInterrupt, by
104 * passing up PY_LOCK_INTR. */
105 if (Py_MakePendingCalls() < 0) {
106 return PY_LOCK_INTR;
107 }
108
109 /* If we're using a timeout, recompute the timeout after processing
110 * signals, since those can take time. */
Victor Stinnerf5faad22015-03-28 03:52:05 +0100111 if (timeout > 0) {
112 timeout = endtime - _PyTime_GetMonotonicClock();
Antoine Pitrou810023d2010-12-15 22:59:16 +0000113
114 /* Check for negative values, since those mean block forever.
115 */
Victor Stinner6aa446c2015-03-30 21:33:51 +0200116 if (timeout < 0) {
Antoine Pitrou810023d2010-12-15 22:59:16 +0000117 r = PY_LOCK_FAILURE;
118 }
119 }
120 }
121 } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */
122
123 return r;
124}
125
Victor Stinnerf5faad22015-03-28 03:52:05 +0100126static int
127lock_acquire_parse_args(PyObject *args, PyObject *kwds,
128 _PyTime_t *timeout)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000129{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 char *kwlist[] = {"blocking", "timeout", NULL};
131 int blocking = 1;
Victor Stinnerf5faad22015-03-28 03:52:05 +0100132 PyObject *timeout_obj = NULL;
Victor Stinner13019fd2015-04-03 13:10:54 +0200133 const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000134
Victor Stinnerf5faad22015-03-28 03:52:05 +0100135 *timeout = unset_timeout ;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000136
Victor Stinnerf5faad22015-03-28 03:52:05 +0100137 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:acquire", kwlist,
138 &blocking, &timeout_obj))
139 return -1;
140
141 if (timeout_obj
Victor Stinner869e1772015-03-30 03:49:14 +0200142 && _PyTime_FromSecondsObject(timeout,
Pablo Galindo59af94f2017-10-18 08:13:09 +0100143 timeout_obj, _PyTime_ROUND_TIMEOUT) < 0)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100144 return -1;
145
146 if (!blocking && *timeout != unset_timeout ) {
147 PyErr_SetString(PyExc_ValueError,
148 "can't specify a timeout for a non-blocking call");
149 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100151 if (*timeout < 0 && *timeout != unset_timeout) {
152 PyErr_SetString(PyExc_ValueError,
153 "timeout value must be positive");
154 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 }
156 if (!blocking)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100157 *timeout = 0;
158 else if (*timeout != unset_timeout) {
159 _PyTime_t microseconds;
160
Pablo Galindo59af94f2017-10-18 08:13:09 +0100161 microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinnerf5faad22015-03-28 03:52:05 +0100162 if (microseconds >= PY_TIMEOUT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 PyErr_SetString(PyExc_OverflowError,
164 "timeout value is too large");
Victor Stinnerf5faad22015-03-28 03:52:05 +0100165 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000166 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100168 return 0;
169}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000170
Victor Stinnerf5faad22015-03-28 03:52:05 +0100171static PyObject *
172lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
173{
174 _PyTime_t timeout;
Victor Stinnerf5faad22015-03-28 03:52:05 +0100175 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
176 return NULL;
177
Victor Stinner8203c732020-12-16 12:20:33 +0100178 PyLockStatus r = acquire_timed(self->lock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000179 if (r == PY_LOCK_INTR) {
180 return NULL;
181 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000183 if (r == PY_LOCK_ACQUIRED)
184 self->locked = 1;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000185 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000186}
187
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000188PyDoc_STRVAR(acquire_doc,
Berker Peksag720e6552016-05-02 12:25:35 +0300189"acquire(blocking=True, timeout=-1) -> bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000190(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000191\n\
192Lock the lock. Without argument, this blocks if the lock is already\n\
193locked (even by the same thread), waiting for another thread to release\n\
R David Murray95b71102013-02-04 10:15:58 -0500194the lock, and return True once the lock is acquired.\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000195With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000196and the return value reflects whether the lock is acquired.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000197The blocking operation is interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000198
Barry Warsawd0c10421996-12-17 00:05:22 +0000199static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530200lock_PyThread_release_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000201{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000202 /* Sanity check: the lock must be locked */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000203 if (!self->locked) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000204 PyErr_SetString(ThreadError, "release unlocked lock");
205 return NULL;
206 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208 PyThread_release_lock(self->lock_lock);
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000209 self->locked = 0;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200210 Py_RETURN_NONE;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000211}
212
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000213PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000214"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000215(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000216\n\
217Release the lock, allowing another thread that is blocked waiting for\n\
218the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000219but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000220
Barry Warsawd0c10421996-12-17 00:05:22 +0000221static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530222lock_locked_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000223{
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000224 return PyBool_FromLong((long)self->locked);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000225}
226
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000227PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000228"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000229(locked_lock() is an obsolete synonym)\n\
230\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000231Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000232
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700233static PyObject *
234lock_repr(lockobject *self)
235{
236 return PyUnicode_FromFormat("<%s %s object at %p>",
237 self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
238}
239
Victor Stinner87255be2020-04-07 23:11:49 +0200240#ifdef HAVE_FORK
241static PyObject *
242lock__at_fork_reinit(lockobject *self, PyObject *Py_UNUSED(args))
243{
244 if (_PyThread_at_fork_reinit(&self->lock_lock) < 0) {
245 PyErr_SetString(ThreadError, "failed to reinitialize lock at fork");
246 return NULL;
247 }
248
249 self->locked = 0;
250
251 Py_RETURN_NONE;
252}
253#endif /* HAVE_FORK */
254
255
Barry Warsawd0c10421996-12-17 00:05:22 +0000256static PyMethodDef lock_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200257 {"acquire_lock", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258 METH_VARARGS | METH_KEYWORDS, acquire_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200259 {"acquire", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 METH_VARARGS | METH_KEYWORDS, acquire_doc},
261 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
262 METH_NOARGS, release_doc},
263 {"release", (PyCFunction)lock_PyThread_release_lock,
264 METH_NOARGS, release_doc},
265 {"locked_lock", (PyCFunction)lock_locked_lock,
266 METH_NOARGS, locked_doc},
267 {"locked", (PyCFunction)lock_locked_lock,
268 METH_NOARGS, locked_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200269 {"__enter__", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 METH_VARARGS | METH_KEYWORDS, acquire_doc},
271 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
272 METH_VARARGS, release_doc},
Victor Stinner87255be2020-04-07 23:11:49 +0200273#ifdef HAVE_FORK
274 {"_at_fork_reinit", (PyCFunction)lock__at_fork_reinit,
275 METH_NOARGS, NULL},
276#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000278};
279
Victor Stinner8203c732020-12-16 12:20:33 +0100280PyDoc_STRVAR(lock_doc,
281"A lock object is a synchronization primitive. To create a lock,\n\
282call threading.Lock(). Methods are:\n\
283\n\
284acquire() -- lock the lock, possibly blocking until it can be obtained\n\
285release() -- unlock of the lock\n\
286locked() -- test whether the lock is currently locked\n\
287\n\
288A lock is not owned by the thread that locked it; another thread may\n\
289unlock it. A thread attempting to lock a lock that it has already locked\n\
290will block until another thread unlocks it. Deadlocks may ensue.");
291
Victor Stinner61040132020-12-18 01:39:00 +0100292static PyMemberDef lock_type_members[] = {
293 {"__weaklistoffset__", T_PYSSIZET, offsetof(lockobject, in_weakreflist), READONLY},
294 {NULL},
295};
296
297static PyType_Slot lock_type_slots[] = {
298 {Py_tp_dealloc, (destructor)lock_dealloc},
299 {Py_tp_repr, (reprfunc)lock_repr},
300 {Py_tp_doc, (void *)lock_doc},
301 {Py_tp_methods, lock_methods},
302 {Py_tp_traverse, lock_traverse},
303 {Py_tp_members, lock_type_members},
304 {0, 0}
305};
306
307static PyType_Spec lock_type_spec = {
308 .name = "_thread.lock",
309 .basicsize = sizeof(lockobject),
310 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
311 .slots = lock_type_slots,
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000312};
313
Antoine Pitrou434736a2009-11-10 18:46:01 +0000314/* Recursive lock objects */
315
316typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 PyObject_HEAD
318 PyThread_type_lock rlock_lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200319 unsigned long rlock_owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 unsigned long rlock_count;
321 PyObject *in_weakreflist;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000322} rlockobject;
323
324static void
325rlock_dealloc(rlockobject *self)
326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327 if (self->in_weakreflist != NULL)
328 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner357f5152013-11-05 15:10:19 +0100329 /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed
330 in rlock_new() */
331 if (self->rlock_lock != NULL) {
332 /* Unlock the lock so it's safe to free it */
333 if (self->rlock_count > 0)
334 PyThread_release_lock(self->rlock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335
Victor Stinner357f5152013-11-05 15:10:19 +0100336 PyThread_free_lock(self->rlock_lock);
337 }
Victor Stinner61040132020-12-18 01:39:00 +0100338 PyTypeObject *tp = Py_TYPE(self);
339 tp->tp_free(self);
340 Py_DECREF(tp);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000341}
342
343static PyObject *
344rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
345{
Victor Stinnerf5faad22015-03-28 03:52:05 +0100346 _PyTime_t timeout;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200347 unsigned long tid;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000348 PyLockStatus r = PY_LOCK_ACQUIRED;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000349
Victor Stinnerf5faad22015-03-28 03:52:05 +0100350 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 tid = PyThread_get_thread_ident();
354 if (self->rlock_count > 0 && tid == self->rlock_owner) {
355 unsigned long count = self->rlock_count + 1;
356 if (count <= self->rlock_count) {
357 PyErr_SetString(PyExc_OverflowError,
358 "Internal lock count overflowed");
359 return NULL;
360 }
361 self->rlock_count = count;
362 Py_RETURN_TRUE;
363 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100364 r = acquire_timed(self->rlock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000365 if (r == PY_LOCK_ACQUIRED) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366 assert(self->rlock_count == 0);
367 self->rlock_owner = tid;
368 self->rlock_count = 1;
369 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000370 else if (r == PY_LOCK_INTR) {
371 return NULL;
372 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373
Antoine Pitrou810023d2010-12-15 22:59:16 +0000374 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000375}
376
377PyDoc_STRVAR(rlock_acquire_doc,
378"acquire(blocking=True) -> bool\n\
379\n\
380Lock the lock. `blocking` indicates whether we should wait\n\
381for the lock to be available or not. If `blocking` is False\n\
382and another thread holds the lock, the method will return False\n\
383immediately. If `blocking` is True and another thread holds\n\
384the lock, the method will wait for the lock to be released,\n\
385take it and then return True.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000386(note: the blocking operation is interruptible.)\n\
Antoine Pitrou434736a2009-11-10 18:46:01 +0000387\n\
388In all other cases, the method will return True immediately.\n\
389Precisely, if the current thread already holds the lock, its\n\
390internal counter is simply incremented. If nobody holds the lock,\n\
391the lock is taken and its internal counter initialized to 1.");
392
393static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530394rlock_release(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000395{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200396 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrou434736a2009-11-10 18:46:01 +0000397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 if (self->rlock_count == 0 || self->rlock_owner != tid) {
399 PyErr_SetString(PyExc_RuntimeError,
400 "cannot release un-acquired lock");
401 return NULL;
402 }
403 if (--self->rlock_count == 0) {
404 self->rlock_owner = 0;
405 PyThread_release_lock(self->rlock_lock);
406 }
407 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000408}
409
410PyDoc_STRVAR(rlock_release_doc,
411"release()\n\
412\n\
413Release the lock, allowing another thread that is blocked waiting for\n\
414the lock to acquire the lock. The lock must be in the locked state,\n\
415and must be locked by the same thread that unlocks it; otherwise a\n\
416`RuntimeError` is raised.\n\
417\n\
418Do note that if the lock was acquire()d several times in a row by the\n\
419current thread, release() needs to be called as many times for the lock\n\
420to be available for other threads.");
421
422static PyObject *
Victor Stinnere8794522014-01-02 12:47:24 +0100423rlock_acquire_restore(rlockobject *self, PyObject *args)
Antoine Pitrou434736a2009-11-10 18:46:01 +0000424{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200425 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 unsigned long count;
427 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000428
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200429 if (!PyArg_ParseTuple(args, "(kk):_acquire_restore", &count, &owner))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000430 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
433 Py_BEGIN_ALLOW_THREADS
434 r = PyThread_acquire_lock(self->rlock_lock, 1);
435 Py_END_ALLOW_THREADS
436 }
437 if (!r) {
438 PyErr_SetString(ThreadError, "couldn't acquire lock");
439 return NULL;
440 }
441 assert(self->rlock_count == 0);
442 self->rlock_owner = owner;
443 self->rlock_count = count;
444 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000445}
446
447PyDoc_STRVAR(rlock_acquire_restore_doc,
448"_acquire_restore(state) -> None\n\
449\n\
450For internal use by `threading.Condition`.");
451
452static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530453rlock_release_save(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000454{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200455 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 unsigned long count;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000457
Victor Stinnerc2824d42011-04-24 23:41:33 +0200458 if (self->rlock_count == 0) {
459 PyErr_SetString(PyExc_RuntimeError,
460 "cannot release un-acquired lock");
461 return NULL;
462 }
463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 owner = self->rlock_owner;
465 count = self->rlock_count;
466 self->rlock_count = 0;
467 self->rlock_owner = 0;
468 PyThread_release_lock(self->rlock_lock);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200469 return Py_BuildValue("kk", count, owner);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000470}
471
472PyDoc_STRVAR(rlock_release_save_doc,
473"_release_save() -> tuple\n\
474\n\
475For internal use by `threading.Condition`.");
476
477
478static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530479rlock_is_owned(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000480{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200481 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482
483 if (self->rlock_count > 0 && self->rlock_owner == tid) {
484 Py_RETURN_TRUE;
485 }
486 Py_RETURN_FALSE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000487}
488
489PyDoc_STRVAR(rlock_is_owned_doc,
490"_is_owned() -> bool\n\
491\n\
492For internal use by `threading.Condition`.");
493
494static PyObject *
495rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
496{
Victor Stinner87255be2020-04-07 23:11:49 +0200497 rlockobject *self = (rlockobject *) type->tp_alloc(type, 0);
498 if (self == NULL) {
499 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 }
Victor Stinner87255be2020-04-07 23:11:49 +0200501 self->in_weakreflist = NULL;
502 self->rlock_owner = 0;
503 self->rlock_count = 0;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000504
Victor Stinner87255be2020-04-07 23:11:49 +0200505 self->rlock_lock = PyThread_allocate_lock();
506 if (self->rlock_lock == NULL) {
507 Py_DECREF(self);
508 PyErr_SetString(ThreadError, "can't allocate lock");
509 return NULL;
510 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 return (PyObject *) self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000512}
513
514static PyObject *
515rlock_repr(rlockobject *self)
516{
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700517 return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>",
518 self->rlock_count ? "locked" : "unlocked",
519 Py_TYPE(self)->tp_name, self->rlock_owner,
520 self->rlock_count, self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000521}
522
523
Victor Stinner87255be2020-04-07 23:11:49 +0200524#ifdef HAVE_FORK
525static PyObject *
526rlock__at_fork_reinit(rlockobject *self, PyObject *Py_UNUSED(args))
527{
528 if (_PyThread_at_fork_reinit(&self->rlock_lock) < 0) {
529 PyErr_SetString(ThreadError, "failed to reinitialize lock at fork");
530 return NULL;
531 }
532
533 self->rlock_owner = 0;
534 self->rlock_count = 0;
535
536 Py_RETURN_NONE;
537}
538#endif /* HAVE_FORK */
539
540
Antoine Pitrou434736a2009-11-10 18:46:01 +0000541static PyMethodDef rlock_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200542 {"acquire", (PyCFunction)(void(*)(void))rlock_acquire,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
544 {"release", (PyCFunction)rlock_release,
545 METH_NOARGS, rlock_release_doc},
546 {"_is_owned", (PyCFunction)rlock_is_owned,
547 METH_NOARGS, rlock_is_owned_doc},
548 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
Victor Stinnere8794522014-01-02 12:47:24 +0100549 METH_VARARGS, rlock_acquire_restore_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 {"_release_save", (PyCFunction)rlock_release_save,
551 METH_NOARGS, rlock_release_save_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200552 {"__enter__", (PyCFunction)(void(*)(void))rlock_acquire,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000553 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
554 {"__exit__", (PyCFunction)rlock_release,
555 METH_VARARGS, rlock_release_doc},
Victor Stinner87255be2020-04-07 23:11:49 +0200556#ifdef HAVE_FORK
557 {"_at_fork_reinit", (PyCFunction)rlock__at_fork_reinit,
558 METH_NOARGS, NULL},
559#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 {NULL, NULL} /* sentinel */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000561};
562
563
Victor Stinner61040132020-12-18 01:39:00 +0100564static PyMemberDef rlock_type_members[] = {
565 {"__weaklistoffset__", T_PYSSIZET, offsetof(rlockobject, in_weakreflist), READONLY},
566 {NULL},
567};
568
569static PyType_Slot rlock_type_slots[] = {
570 {Py_tp_dealloc, (destructor)rlock_dealloc},
571 {Py_tp_repr, (reprfunc)rlock_repr},
572 {Py_tp_methods, rlock_methods},
573 {Py_tp_alloc, PyType_GenericAlloc},
574 {Py_tp_new, rlock_new},
575 {Py_tp_members, rlock_type_members},
576 {0, 0},
577};
578
579static PyType_Spec rlock_type_spec = {
580 .name = "_thread.RLock",
581 .basicsize = sizeof(rlockobject),
582 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
583 .slots = rlock_type_slots,
Antoine Pitrou434736a2009-11-10 18:46:01 +0000584};
585
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000586static lockobject *
Victor Stinner61040132020-12-18 01:39:00 +0100587newlockobject(PyObject *module)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000588{
Victor Stinner61040132020-12-18 01:39:00 +0100589 thread_module_state *state = get_thread_state(module);
590
591 PyTypeObject *type = state->lock_type;
592 lockobject *self = (lockobject *)type->tp_alloc(type, 0);
Victor Stinner8203c732020-12-16 12:20:33 +0100593 if (self == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 return NULL;
Victor Stinner8203c732020-12-16 12:20:33 +0100595 }
596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 self->lock_lock = PyThread_allocate_lock();
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000598 self->locked = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599 self->in_weakreflist = NULL;
Victor Stinner8203c732020-12-16 12:20:33 +0100600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 if (self->lock_lock == NULL) {
602 Py_DECREF(self);
603 PyErr_SetString(ThreadError, "can't allocate lock");
604 return NULL;
605 }
606 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000607}
608
Jim Fultond15dc062004-07-14 19:11:50 +0000609/* Thread-local objects */
610
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000611/* Quick overview:
612
613 We need to be able to reclaim reference cycles as soon as possible
614 (both when a thread is being terminated, or a thread-local object
615 becomes unreachable from user data). Constraints:
616 - it must not be possible for thread-state dicts to be involved in
617 reference cycles (otherwise the cyclic GC will refuse to consider
618 objects referenced from a reachable thread-state dict, even though
619 local_dealloc would clear them)
620 - the death of a thread-state dict must still imply destruction of the
621 corresponding local dicts in all thread-local objects.
622
623 Our implementation uses small "localdummy" objects in order to break
624 the reference chain. These trivial objects are hashable (using the
625 default scheme of identity hashing) and weakrefable.
626 Each thread-state holds a separate localdummy for each local object
627 (as a /strong reference/),
628 and each thread-local object holds a dict mapping /weak references/
629 of localdummies to local dicts.
630
631 Therefore:
632 - only the thread-state dict holds a strong reference to the dummies
633 - only the thread-local object holds a strong reference to the local dicts
634 - only outside objects (application- or library-level) hold strong
635 references to the thread-local objects
636 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
637 dummies attached to that thread are called, and destroy the corresponding
638 local dicts from thread-local objects
639 - as soon as a thread-local object is destroyed, its local dicts are
640 destroyed and its dummies are manually removed from all thread states
641 - the GC can do its work correctly when a thread-local object is dangling,
642 without any interference from the thread-state dicts
643
644 As an additional optimization, each localdummy holds a borrowed reference
645 to the corresponding localdict. This borrowed reference is only used
646 by the thread-local object which has created the localdummy, which should
647 guarantee that the localdict still exists when accessed.
648*/
649
650typedef struct {
651 PyObject_HEAD
652 PyObject *localdict; /* Borrowed reference! */
653 PyObject *weakreflist; /* List of weak references to self */
654} localdummyobject;
655
656static void
657localdummy_dealloc(localdummyobject *self)
658{
659 if (self->weakreflist != NULL)
660 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner61040132020-12-18 01:39:00 +0100661 PyTypeObject *tp = Py_TYPE(self);
662 tp->tp_free((PyObject*)self);
663 Py_DECREF(tp);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000664}
665
Victor Stinner61040132020-12-18 01:39:00 +0100666static PyMemberDef local_dummy_type_members[] = {
667 {"__weaklistoffset__", T_PYSSIZET, offsetof(localdummyobject, weakreflist), READONLY},
668 {NULL},
669};
670
671static PyType_Slot local_dummy_type_slots[] = {
672 {Py_tp_dealloc, (destructor)localdummy_dealloc},
673 {Py_tp_doc, "Thread-local dummy"},
674 {Py_tp_members, local_dummy_type_members},
675 {0, 0}
676};
677
678static PyType_Spec local_dummy_type_spec = {
679 .name = "_thread._localdummy",
680 .basicsize = sizeof(localdummyobject),
681 .flags = Py_TPFLAGS_DEFAULT,
682 .slots = local_dummy_type_slots,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000683};
684
685
Jim Fultond15dc062004-07-14 19:11:50 +0000686typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 PyObject_HEAD
688 PyObject *key;
689 PyObject *args;
690 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000691 PyObject *weakreflist; /* List of weak references to self */
692 /* A {localdummy weakref -> localdict} dict */
693 PyObject *dummies;
694 /* The callback for weakrefs to localdummies */
695 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000696} localobject;
697
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000698/* Forward declaration */
Victor Stinner61040132020-12-18 01:39:00 +0100699static PyObject *_ldict(localobject *self, thread_module_state *state);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000700static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
701
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000702/* Create and register the dummy for the current thread.
703 Returns a borrowed reference of the corresponding local dict */
704static PyObject *
Victor Stinner61040132020-12-18 01:39:00 +0100705_local_create_dummy(localobject *self, thread_module_state *state)
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000706{
Victor Stinner8203c732020-12-16 12:20:33 +0100707 PyObject *ldict = NULL, *wr = NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000708 localdummyobject *dummy = NULL;
Victor Stinner61040132020-12-18 01:39:00 +0100709 PyTypeObject *type = state->local_dummy_type;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000710
Victor Stinner8203c732020-12-16 12:20:33 +0100711 PyObject *tdict = PyThreadState_GetDict();
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000712 if (tdict == NULL) {
713 PyErr_SetString(PyExc_SystemError,
714 "Couldn't get thread-state dictionary");
715 goto err;
716 }
717
718 ldict = PyDict_New();
Victor Stinner8203c732020-12-16 12:20:33 +0100719 if (ldict == NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000720 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100721 }
Victor Stinner61040132020-12-18 01:39:00 +0100722 dummy = (localdummyobject *) type->tp_alloc(type, 0);
Victor Stinner8203c732020-12-16 12:20:33 +0100723 if (dummy == NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000724 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100725 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000726 dummy->localdict = ldict;
727 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
Victor Stinner8203c732020-12-16 12:20:33 +0100728 if (wr == 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
732 /* As a side-effect, this will cache the weakref's hash before the
733 dummy gets deleted */
Victor Stinner8203c732020-12-16 12:20:33 +0100734 int r = PyDict_SetItem(self->dummies, wr, ldict);
735 if (r < 0) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000736 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100737 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000738 Py_CLEAR(wr);
739 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
Victor Stinner8203c732020-12-16 12:20:33 +0100740 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(dummy);
744
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000745 Py_DECREF(ldict);
746 return ldict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000747
748err:
749 Py_XDECREF(ldict);
750 Py_XDECREF(wr);
751 Py_XDECREF(dummy);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000752 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000753}
754
Jim Fultond15dc062004-07-14 19:11:50 +0000755static PyObject *
756local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
757{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000758 static PyMethodDef wr_callback_def = {
759 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
760 };
Jim Fultond15dc062004-07-14 19:11:50 +0000761
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300762 if (type->tp_init == PyBaseObject_Type.tp_init) {
763 int rc = 0;
764 if (args != NULL)
765 rc = PyObject_IsTrue(args);
766 if (rc == 0 && kw != NULL)
767 rc = PyObject_IsTrue(kw);
768 if (rc != 0) {
Victor Stinner8203c732020-12-16 12:20:33 +0100769 if (rc > 0) {
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300770 PyErr_SetString(PyExc_TypeError,
771 "Initialization arguments are not supported");
Victor Stinner8203c732020-12-16 12:20:33 +0100772 }
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300773 return NULL;
774 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000775 }
Jim Fultond15dc062004-07-14 19:11:50 +0000776
Victor Stinner61040132020-12-18 01:39:00 +0100777 PyObject *module = _PyType_GetModuleByDef(type, &thread_module);
778 thread_module_state *state = get_thread_state(module);
779
780 localobject *self = (localobject *)type->tp_alloc(type, 0);
Victor Stinner8203c732020-12-16 12:20:33 +0100781 if (self == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000782 return NULL;
Victor Stinner8203c732020-12-16 12:20:33 +0100783 }
Jim Fultond15dc062004-07-14 19:11:50 +0000784
Victor Stinner8203c732020-12-16 12:20:33 +0100785 self->args = Py_XNewRef(args);
786 self->kw = Py_XNewRef(kw);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 self->key = PyUnicode_FromFormat("thread.local.%p", self);
Victor Stinner8203c732020-12-16 12:20:33 +0100788 if (self->key == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000789 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100790 }
Jim Fultond15dc062004-07-14 19:11:50 +0000791
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000792 self->dummies = PyDict_New();
Victor Stinner8203c732020-12-16 12:20:33 +0100793 if (self->dummies == 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 /* We use a weak reference to self in the callback closure
798 in order to avoid spurious reference cycles */
Victor Stinner8203c732020-12-16 12:20:33 +0100799 PyObject *wr = PyWeakref_NewRef((PyObject *) self, NULL);
800 if (wr == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100802 }
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200803 self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000804 Py_DECREF(wr);
Victor Stinner8203c732020-12-16 12:20:33 +0100805 if (self->wr_callback == NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000806 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100807 }
Victor Stinner61040132020-12-18 01:39:00 +0100808 if (_local_create_dummy(self, state) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100810 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000811 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000812
813 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000814 Py_DECREF(self);
815 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000816}
817
818static int
819local_traverse(localobject *self, visitproc visit, void *arg)
820{
Victor Stinner61040132020-12-18 01:39:00 +0100821 Py_VISIT(Py_TYPE(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000822 Py_VISIT(self->args);
823 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000824 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000825 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000826}
827
828static int
829local_clear(localobject *self)
830{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000831 PyThreadState *tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000832 Py_CLEAR(self->args);
833 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000834 Py_CLEAR(self->dummies);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000835 Py_CLEAR(self->wr_callback);
836 /* Remove all strong references to dummies from the thread states */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000837 if (self->key
838 && (tstate = PyThreadState_Get())
839 && tstate->interp) {
840 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
841 tstate;
842 tstate = PyThreadState_Next(tstate))
Serhiy Storchakafb5db7e2020-10-26 08:43:39 +0200843 if (tstate->dict) {
844 PyObject *v = _PyDict_Pop(tstate->dict, self->key, Py_None);
845 if (v == NULL) {
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200846 PyErr_Clear();
847 }
Serhiy Storchakafb5db7e2020-10-26 08:43:39 +0200848 else {
849 Py_DECREF(v);
850 }
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200851 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000852 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000853 return 0;
854}
Jim Fultond15dc062004-07-14 19:11:50 +0000855
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000856static void
857local_dealloc(localobject *self)
858{
859 /* Weakrefs must be invalidated right now, otherwise they can be used
860 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
Victor Stinner8203c732020-12-16 12:20:33 +0100861 if (self->weakreflist != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000862 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner8203c732020-12-16 12:20:33 +0100863 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000864
865 PyObject_GC_UnTrack(self);
866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000867 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000868 Py_XDECREF(self->key);
Victor Stinner61040132020-12-18 01:39:00 +0100869
870 PyTypeObject *tp = Py_TYPE(self);
871 tp->tp_free((PyObject*)self);
872 Py_DECREF(tp);
Jim Fultond15dc062004-07-14 19:11:50 +0000873}
874
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000875/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000876static PyObject *
Victor Stinner61040132020-12-18 01:39:00 +0100877_ldict(localobject *self, thread_module_state *state)
Jim Fultond15dc062004-07-14 19:11:50 +0000878{
Victor Stinner8203c732020-12-16 12:20:33 +0100879 PyObject *tdict = PyThreadState_GetDict();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 if (tdict == NULL) {
881 PyErr_SetString(PyExc_SystemError,
882 "Couldn't get thread-state dictionary");
883 return NULL;
884 }
Jim Fultond15dc062004-07-14 19:11:50 +0000885
Victor Stinner8203c732020-12-16 12:20:33 +0100886 PyObject *ldict;
887 PyObject *dummy = PyDict_GetItemWithError(tdict, self->key);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000888 if (dummy == NULL) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200889 if (PyErr_Occurred()) {
890 return NULL;
891 }
Victor Stinner61040132020-12-18 01:39:00 +0100892 ldict = _local_create_dummy(self, state);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000893 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000896 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
897 Py_TYPE(self)->tp_init((PyObject*)self,
898 self->args, self->kw) < 0) {
899 /* we need to get rid of ldict from thread so
900 we create a new one the next time we do an attr
Ezio Melotti42da6632011-03-15 05:18:48 +0200901 access */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 PyDict_DelItem(tdict, self->key);
903 return NULL;
904 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000905 }
906 else {
Victor Stinner61040132020-12-18 01:39:00 +0100907 assert(Py_IS_TYPE(dummy, state->local_dummy_type));
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000908 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000909 }
Jim Fultond15dc062004-07-14 19:11:50 +0000910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000912}
913
Jim Fultond15dc062004-07-14 19:11:50 +0000914static int
915local_setattro(localobject *self, PyObject *name, PyObject *v)
916{
Victor Stinner61040132020-12-18 01:39:00 +0100917 PyObject *module = _PyType_GetModuleByDef(Py_TYPE(self), &thread_module);
918 thread_module_state *state = get_thread_state(module);
919
920 PyObject *ldict = _ldict(self, state);
Victor Stinner8203c732020-12-16 12:20:33 +0100921 if (ldict == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 return -1;
Victor Stinner8203c732020-12-16 12:20:33 +0100923 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924
Victor Stinner8203c732020-12-16 12:20:33 +0100925 PyObject *str_dict = _PyUnicode_FromId(&PyId___dict__); // borrowed ref
926 if (str_dict == NULL) {
927 return -1;
928 }
929
930 int r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
931 if (r == -1) {
932 return -1;
933 }
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000934 if (r == 1) {
935 PyErr_Format(PyExc_AttributeError,
936 "'%.50s' object attribute '%U' is read-only",
937 Py_TYPE(self)->tp_name, name);
938 return -1;
939 }
Jim Fultond15dc062004-07-14 19:11:50 +0000940
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000941 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000942}
943
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000944static PyObject *local_getattro(localobject *, PyObject *);
945
Victor Stinner61040132020-12-18 01:39:00 +0100946static PyMemberDef local_type_members[] = {
947 {"__weaklistoffset__", T_PYSSIZET, offsetof(localobject, weakreflist), READONLY},
948 {NULL},
949};
950
951static PyType_Slot local_type_slots[] = {
952 {Py_tp_dealloc, (destructor)local_dealloc},
953 {Py_tp_getattro, (getattrofunc)local_getattro},
954 {Py_tp_setattro, (setattrofunc)local_setattro},
955 {Py_tp_doc, "Thread-local data"},
956 {Py_tp_traverse, (traverseproc)local_traverse},
957 {Py_tp_clear, (inquiry)local_clear},
958 {Py_tp_new, local_new},
959 {Py_tp_members, local_type_members},
960 {0, 0}
961};
962
963static PyType_Spec local_type_spec = {
964 .name = "_thread._local",
965 .basicsize = sizeof(localobject),
966 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
967 .slots = local_type_slots,
Jim Fultond15dc062004-07-14 19:11:50 +0000968};
969
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000970static PyObject *
971local_getattro(localobject *self, PyObject *name)
972{
Victor Stinner61040132020-12-18 01:39:00 +0100973 PyObject *module = _PyType_GetModuleByDef(Py_TYPE(self), &thread_module);
974 thread_module_state *state = get_thread_state(module);
975
976 PyObject *ldict = _ldict(self, state);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 if (ldict == NULL)
978 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000979
Victor Stinner8203c732020-12-16 12:20:33 +0100980 PyObject *str_dict = _PyUnicode_FromId(&PyId___dict__); // borrowed ref
981 if (str_dict == NULL) {
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000982 return NULL;
Victor Stinner8203c732020-12-16 12:20:33 +0100983 }
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000984
Victor Stinner8203c732020-12-16 12:20:33 +0100985 int r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
986 if (r == 1) {
987 return Py_NewRef(ldict);
988 }
989 if (r == -1) {
990 return NULL;
991 }
992
Victor Stinner61040132020-12-18 01:39:00 +0100993 if (!Py_IS_TYPE(self, state->local_type)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000994 /* use generic lookup for subtypes */
Victor Stinner8203c732020-12-16 12:20:33 +0100995 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name,
996 ldict, 0);
997 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 /* Optimization: just look in dict ourselves */
Victor Stinner8203c732020-12-16 12:20:33 +01001000 PyObject *value = PyDict_GetItemWithError(ldict, name);
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001001 if (value != NULL) {
Victor Stinner8203c732020-12-16 12:20:33 +01001002 return Py_NewRef(value);
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001003 }
Victor Stinner8203c732020-12-16 12:20:33 +01001004 if (PyErr_Occurred()) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001005 return NULL;
1006 }
Victor Stinner8203c732020-12-16 12:20:33 +01001007
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001008 /* Fall back on generic to get __class__ and __dict__ */
1009 return _PyObject_GenericGetAttrWithDict(
1010 (PyObject *)self, name, ldict, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001011}
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001012
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001013/* Called when a dummy is destroyed. */
1014static PyObject *
1015_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
1016{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001017 assert(PyWeakref_CheckRef(localweakref));
Victor Stinner8203c732020-12-16 12:20:33 +01001018 PyObject *obj = PyWeakref_GET_OBJECT(localweakref);
1019 if (obj == Py_None) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001020 Py_RETURN_NONE;
Victor Stinner8203c732020-12-16 12:20:33 +01001021 }
1022
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001023 /* If the thread-local object is still alive and not being cleared,
1024 remove the corresponding local dict */
Victor Stinner8203c732020-12-16 12:20:33 +01001025 localobject *self = (localobject *)Py_NewRef(obj);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001026 if (self->dummies != NULL) {
1027 PyObject *ldict;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001028 ldict = PyDict_GetItemWithError(self->dummies, dummyweakref);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001029 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001030 PyDict_DelItem(self->dummies, dummyweakref);
1031 }
1032 if (PyErr_Occurred())
1033 PyErr_WriteUnraisable(obj);
1034 }
1035 Py_DECREF(obj);
1036 Py_RETURN_NONE;
1037}
1038
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001039/* Module functions */
1040
Guido van Rossuma027efa1997-05-05 20:56:21 +00001041struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 PyInterpreterState *interp;
1043 PyObject *func;
1044 PyObject *args;
Victor Stinner8203c732020-12-16 12:20:33 +01001045 PyObject *kwargs;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 PyThreadState *tstate;
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001047 _PyRuntimeState *runtime;
Guido van Rossuma027efa1997-05-05 20:56:21 +00001048};
1049
Victor Stinner8203c732020-12-16 12:20:33 +01001050
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001051static void
Victor Stinner8203c732020-12-16 12:20:33 +01001052thread_bootstate_free(struct bootstate *boot)
1053{
1054 Py_DECREF(boot->func);
1055 Py_DECREF(boot->args);
1056 Py_XDECREF(boot->kwargs);
1057 PyMem_Free(boot);
1058}
1059
1060
1061static void
1062thread_run(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001063{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 struct bootstate *boot = (struct bootstate *) boot_raw;
1065 PyThreadState *tstate;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 tstate = boot->tstate;
1068 tstate->thread_id = PyThread_get_thread_ident();
Victor Stinner01b1cc12019-11-20 02:27:56 +01001069 _PyThreadState_Init(tstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 PyEval_AcquireThread(tstate);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001071 tstate->interp->num_threads++;
Victor Stinner8203c732020-12-16 12:20:33 +01001072
1073 PyObject *res = PyObject_Call(boot->func, boot->args, boot->kwargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 if (res == NULL) {
1075 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Victor Stinner8b095002019-05-29 02:57:56 +02001076 /* SystemExit is ignored silently */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 PyErr_Clear();
1078 else {
Victor Stinner8b095002019-05-29 02:57:56 +02001079 _PyErr_WriteUnraisableMsg("in thread started by", boot->func);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001080 }
1081 }
Victor Stinner8b095002019-05-29 02:57:56 +02001082 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 Py_DECREF(res);
Victor Stinner8b095002019-05-29 02:57:56 +02001084 }
Victor Stinner8203c732020-12-16 12:20:33 +01001085
1086 thread_bootstate_free(boot);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001087 tstate->interp->num_threads--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088 PyThreadState_Clear(tstate);
Victor Stinner23ef89d2020-03-18 02:26:04 +01001089 _PyThreadState_DeleteCurrent(tstate);
Victor Stinner8203c732020-12-16 12:20:33 +01001090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001091 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001092}
1093
Barry Warsawd0c10421996-12-17 00:05:22 +00001094static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001095thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001096{
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001097 _PyRuntimeState *runtime = &_PyRuntime;
Victor Stinner8203c732020-12-16 12:20:33 +01001098 PyObject *func, *args, *kwargs = NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
Victor Stinner8203c732020-12-16 12:20:33 +01001101 &func, &args, &kwargs))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 return NULL;
1103 if (!PyCallable_Check(func)) {
1104 PyErr_SetString(PyExc_TypeError,
1105 "first arg must be callable");
1106 return NULL;
1107 }
1108 if (!PyTuple_Check(args)) {
1109 PyErr_SetString(PyExc_TypeError,
1110 "2nd arg must be a tuple");
1111 return NULL;
1112 }
Victor Stinner8203c732020-12-16 12:20:33 +01001113 if (kwargs != NULL && !PyDict_Check(kwargs)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 PyErr_SetString(PyExc_TypeError,
1115 "optional 3rd arg must be a dictionary");
1116 return NULL;
1117 }
Victor Stinner252346a2020-05-01 11:33:44 +02001118
1119 PyInterpreterState *interp = _PyInterpreterState_GET();
1120 if (interp->config._isolated_interpreter) {
1121 PyErr_SetString(PyExc_RuntimeError,
1122 "thread is not supported for isolated subinterpreters");
1123 return NULL;
1124 }
1125
Victor Stinner8203c732020-12-16 12:20:33 +01001126 struct bootstate *boot = PyMem_NEW(struct bootstate, 1);
1127 if (boot == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001128 return PyErr_NoMemory();
Victor Stinner8203c732020-12-16 12:20:33 +01001129 }
Victor Stinner81a7be32020-04-14 15:14:01 +02001130 boot->interp = _PyInterpreterState_GET();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 boot->tstate = _PyThreadState_Prealloc(boot->interp);
1132 if (boot->tstate == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01001133 PyMem_Free(boot);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001134 return PyErr_NoMemory();
1135 }
Victor Stinner8203c732020-12-16 12:20:33 +01001136 boot->runtime = runtime;
1137 boot->func = Py_NewRef(func);
1138 boot->args = Py_NewRef(args);
1139 boot->kwargs = Py_XNewRef(kwargs);
Victor Stinner3225b9f2020-03-09 20:56:57 +01001140
Victor Stinner8203c732020-12-16 12:20:33 +01001141 unsigned long ident = PyThread_start_new_thread(thread_run, (void*) boot);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001142 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 PyErr_SetString(ThreadError, "can't start new thread");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 PyThreadState_Clear(boot->tstate);
Victor Stinner8203c732020-12-16 12:20:33 +01001145 thread_bootstate_free(boot);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 return NULL;
1147 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001148 return PyLong_FromUnsignedLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001149}
1150
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001151PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001152"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001153(start_new() is an obsolete synonym)\n\
1154\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001155Start a new thread and return its identifier. The thread will call the\n\
1156function with positional arguments from the tuple args and keyword arguments\n\
1157taken from the optional dictionary kwargs. The thread exits when the\n\
1158function returns; the return value is ignored. The thread will also exit\n\
1159when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001160printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001161
Barry Warsawd0c10421996-12-17 00:05:22 +00001162static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301163thread_PyThread_exit_thread(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 PyErr_SetNone(PyExc_SystemExit);
1166 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001167}
1168
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001169PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001170"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001171(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001172\n\
1173This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001174thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001175
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001176static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301177thread_PyThread_interrupt_main(PyObject * self, PyObject *Py_UNUSED(ignored))
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 PyErr_SetInterrupt();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001180 Py_RETURN_NONE;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001181}
1182
1183PyDoc_STRVAR(interrupt_doc,
1184"interrupt_main()\n\
1185\n\
1186Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001187A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001188);
1189
Victor Stinner61040132020-12-18 01:39:00 +01001190static lockobject *newlockobject(PyObject *module);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001191
Barry Warsawd0c10421996-12-17 00:05:22 +00001192static PyObject *
Victor Stinner8203c732020-12-16 12:20:33 +01001193thread_PyThread_allocate_lock(PyObject *module, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001194{
Victor Stinner61040132020-12-18 01:39:00 +01001195 return (PyObject *) newlockobject(module);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001196}
1197
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001198PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001199"allocate_lock() -> lock object\n\
1200(allocate() is an obsolete synonym)\n\
1201\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001202Create a new lock object. See help(type(threading.Lock())) for\n\
1203information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001204
Barry Warsawd0c10421996-12-17 00:05:22 +00001205static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301206thread_get_ident(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001207{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001208 unsigned long ident = PyThread_get_thread_ident();
1209 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 PyErr_SetString(ThreadError, "no current thread ident");
1211 return NULL;
1212 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001213 return PyLong_FromUnsignedLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001214}
1215
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001216PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001217"get_ident() -> integer\n\
1218\n\
1219Return a non-zero integer that uniquely identifies the current thread\n\
1220amongst other threads that exist simultaneously.\n\
1221This may be used to identify per-thread resources.\n\
1222Even though on some platforms threads identities may appear to be\n\
1223allocated consecutive numbers starting at 1, this behavior should not\n\
1224be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001225A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001226
Jake Teslerb121f632019-05-22 08:43:17 -07001227#ifdef PY_HAVE_THREAD_NATIVE_ID
1228static PyObject *
1229thread_get_native_id(PyObject *self, PyObject *Py_UNUSED(ignored))
1230{
1231 unsigned long native_id = PyThread_get_thread_native_id();
1232 return PyLong_FromUnsignedLong(native_id);
1233}
1234
1235PyDoc_STRVAR(get_native_id_doc,
1236"get_native_id() -> integer\n\
1237\n\
1238Return a non-negative integer identifying the thread as reported\n\
1239by the OS (kernel). This may be used to uniquely identify a\n\
1240particular thread within a system.");
1241#endif
1242
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001243static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301244thread__count(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001245{
Victor Stinner81a7be32020-04-14 15:14:01 +02001246 PyInterpreterState *interp = _PyInterpreterState_GET();
Victor Stinnercaba55b2018-08-03 15:33:52 +02001247 return PyLong_FromLong(interp->num_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001248}
1249
1250PyDoc_STRVAR(_count_doc,
1251"_count() -> integer\n\
1252\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001253\
oldkaa0735f2018-02-02 16:52:55 +08001254Return the number of currently running Python threads, excluding\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001255the main thread. The returned number comprises all threads created\n\
1256through `start_new_thread()` as well as `threading.Thread`, and not\n\
1257yet finished.\n\
1258\n\
1259This function is meant for internal and specialized purposes only.\n\
1260In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001261
Antoine Pitrou7b476992013-09-07 23:38:37 +02001262static void
Victor Stinnera42de742018-11-22 10:25:22 +01001263release_sentinel(void *wr_raw)
Antoine Pitrou7b476992013-09-07 23:38:37 +02001264{
Victor Stinnera42de742018-11-22 10:25:22 +01001265 PyObject *wr = _PyObject_CAST(wr_raw);
Antoine Pitrou7b476992013-09-07 23:38:37 +02001266 /* Tricky: this function is called when the current thread state
1267 is being deleted. Therefore, only simple C code can safely
1268 execute here. */
1269 PyObject *obj = PyWeakref_GET_OBJECT(wr);
1270 lockobject *lock;
1271 if (obj != Py_None) {
Antoine Pitrou7b476992013-09-07 23:38:37 +02001272 lock = (lockobject *) obj;
1273 if (lock->locked) {
1274 PyThread_release_lock(lock->lock_lock);
1275 lock->locked = 0;
1276 }
1277 }
1278 /* Deallocating a weakref with a NULL callback only calls
1279 PyObject_GC_Del(), which can't call any Python code. */
1280 Py_DECREF(wr);
1281}
1282
1283static PyObject *
Victor Stinner8203c732020-12-16 12:20:33 +01001284thread__set_sentinel(PyObject *module, PyObject *Py_UNUSED(ignored))
Antoine Pitrou7b476992013-09-07 23:38:37 +02001285{
1286 PyObject *wr;
1287 PyThreadState *tstate = PyThreadState_Get();
1288 lockobject *lock;
1289
1290 if (tstate->on_delete_data != NULL) {
1291 /* We must support the re-creation of the lock from a
1292 fork()ed child. */
1293 assert(tstate->on_delete == &release_sentinel);
1294 wr = (PyObject *) tstate->on_delete_data;
1295 tstate->on_delete = NULL;
1296 tstate->on_delete_data = NULL;
1297 Py_DECREF(wr);
1298 }
Victor Stinner61040132020-12-18 01:39:00 +01001299 lock = newlockobject(module);
Antoine Pitrou7b476992013-09-07 23:38:37 +02001300 if (lock == NULL)
1301 return NULL;
1302 /* The lock is owned by whoever called _set_sentinel(), but the weakref
1303 hangs to the thread state. */
1304 wr = PyWeakref_NewRef((PyObject *) lock, NULL);
1305 if (wr == NULL) {
1306 Py_DECREF(lock);
1307 return NULL;
1308 }
1309 tstate->on_delete_data = (void *) wr;
1310 tstate->on_delete = &release_sentinel;
1311 return (PyObject *) lock;
1312}
1313
1314PyDoc_STRVAR(_set_sentinel_doc,
1315"_set_sentinel() -> lock\n\
1316\n\
1317Set a sentinel lock that will be released when the current thread\n\
1318state is finalized (after it is untied from the interpreter).\n\
1319\n\
1320This is a private API for the threading module.");
1321
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001322static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001323thread_stack_size(PyObject *self, PyObject *args)
1324{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 size_t old_size;
1326 Py_ssize_t new_size = 0;
1327 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1330 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 if (new_size < 0) {
1333 PyErr_SetString(PyExc_ValueError,
1334 "size must be 0 or a positive value");
1335 return NULL;
1336 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 rc = PyThread_set_stacksize((size_t) new_size);
1341 if (rc == -1) {
1342 PyErr_Format(PyExc_ValueError,
1343 "size not valid: %zd bytes",
1344 new_size);
1345 return NULL;
1346 }
1347 if (rc == -2) {
1348 PyErr_SetString(ThreadError,
1349 "setting stack size not supported");
1350 return NULL;
1351 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001354}
1355
1356PyDoc_STRVAR(stack_size_doc,
1357"stack_size([size]) -> size\n\
1358\n\
1359Return the thread stack size used when creating new threads. The\n\
1360optional size argument specifies the stack size (in bytes) to be used\n\
1361for subsequently created threads, and must be 0 (use platform or\n\
1362configured default) or a positive integer value of at least 32,768 (32k).\n\
1363If changing the thread stack size is unsupported, a ThreadError\n\
1364exception is raised. If the specified size is invalid, a ValueError\n\
1365exception is raised, and the stack size is unmodified. 32k bytes\n\
1366 currently the minimum supported stack size value to guarantee\n\
1367sufficient stack space for the interpreter itself.\n\
1368\n\
1369Note that some platforms may have particular restrictions on values for\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001370the stack size, such as requiring a minimum stack size larger than 32 KiB or\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001371requiring allocation in multiples of the system memory page size\n\
1372- platform documentation should be referred to for more information\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001373(4 KiB pages are common; using multiples of 4096 for the stack size is\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001374the suggested approach in the absence of more specific information).");
1375
Victor Stinnercd590a72019-05-28 00:39:52 +02001376static int
1377thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value,
1378 PyObject *exc_traceback, PyObject *thread)
1379{
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001380 _Py_IDENTIFIER(name);
Victor Stinnercd590a72019-05-28 00:39:52 +02001381 /* print(f"Exception in thread {thread.name}:", file=file) */
1382 if (PyFile_WriteString("Exception in thread ", file) < 0) {
1383 return -1;
1384 }
1385
1386 PyObject *name = NULL;
1387 if (thread != Py_None) {
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001388 if (_PyObject_LookupAttrId(thread, &PyId_name, &name) < 0) {
1389 return -1;
1390 }
Victor Stinnercd590a72019-05-28 00:39:52 +02001391 }
1392 if (name != NULL) {
1393 if (PyFile_WriteObject(name, file, Py_PRINT_RAW) < 0) {
1394 Py_DECREF(name);
1395 return -1;
1396 }
1397 Py_DECREF(name);
1398 }
1399 else {
Victor Stinnercd590a72019-05-28 00:39:52 +02001400 unsigned long ident = PyThread_get_thread_ident();
1401 PyObject *str = PyUnicode_FromFormat("%lu", ident);
1402 if (str != NULL) {
1403 if (PyFile_WriteObject(str, file, Py_PRINT_RAW) < 0) {
1404 Py_DECREF(str);
1405 return -1;
1406 }
1407 Py_DECREF(str);
1408 }
1409 else {
1410 PyErr_Clear();
1411
1412 if (PyFile_WriteString("<failed to get thread name>", file) < 0) {
1413 return -1;
1414 }
1415 }
1416 }
1417
1418 if (PyFile_WriteString(":\n", file) < 0) {
1419 return -1;
1420 }
1421
1422 /* Display the traceback */
1423 _PyErr_Display(file, exc_type, exc_value, exc_traceback);
1424
1425 /* Call file.flush() */
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001426 PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
Victor Stinnercd590a72019-05-28 00:39:52 +02001427 if (!res) {
1428 return -1;
1429 }
1430 Py_DECREF(res);
1431
1432 return 0;
1433}
1434
1435
1436PyDoc_STRVAR(ExceptHookArgs__doc__,
1437"ExceptHookArgs\n\
1438\n\
1439Type used to pass arguments to threading.excepthook.");
1440
1441static PyTypeObject ExceptHookArgsType;
1442
1443static PyStructSequence_Field ExceptHookArgs_fields[] = {
1444 {"exc_type", "Exception type"},
1445 {"exc_value", "Exception value"},
1446 {"exc_traceback", "Exception traceback"},
1447 {"thread", "Thread"},
1448 {0}
1449};
1450
1451static PyStructSequence_Desc ExceptHookArgs_desc = {
Victor Stinner8203c732020-12-16 12:20:33 +01001452 .name = "_thread._ExceptHookArgs",
Victor Stinnercd590a72019-05-28 00:39:52 +02001453 .doc = ExceptHookArgs__doc__,
1454 .fields = ExceptHookArgs_fields,
1455 .n_in_sequence = 4
1456};
1457
1458
1459static PyObject *
1460thread_excepthook(PyObject *self, PyObject *args)
1461{
Andy Lester55728702020-03-06 16:53:17 -06001462 if (!Py_IS_TYPE(args, &ExceptHookArgsType)) {
Victor Stinnercd590a72019-05-28 00:39:52 +02001463 PyErr_SetString(PyExc_TypeError,
1464 "_thread.excepthook argument type "
1465 "must be ExceptHookArgs");
1466 return NULL;
1467 }
1468
1469 /* Borrowed reference */
1470 PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0);
1471 if (exc_type == PyExc_SystemExit) {
1472 /* silently ignore SystemExit */
1473 Py_RETURN_NONE;
1474 }
1475
1476 /* Borrowed references */
1477 PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1);
1478 PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
1479 PyObject *thread = PyStructSequence_GET_ITEM(args, 3);
1480
1481 PyObject *file = _PySys_GetObjectId(&PyId_stderr);
1482 if (file == NULL || file == Py_None) {
1483 if (thread == Py_None) {
1484 /* do nothing if sys.stderr is None and thread is None */
1485 Py_RETURN_NONE;
1486 }
1487
1488 file = PyObject_GetAttrString(thread, "_stderr");
1489 if (file == NULL) {
1490 return NULL;
1491 }
1492 if (file == Py_None) {
1493 Py_DECREF(file);
1494 /* do nothing if sys.stderr is None and sys.stderr was None
1495 when the thread was created */
1496 Py_RETURN_NONE;
1497 }
1498 }
1499 else {
1500 Py_INCREF(file);
1501 }
1502
1503 int res = thread_excepthook_file(file, exc_type, exc_value, exc_tb,
1504 thread);
1505 Py_DECREF(file);
1506 if (res < 0) {
1507 return NULL;
1508 }
1509
1510 Py_RETURN_NONE;
1511}
1512
1513PyDoc_STRVAR(excepthook_doc,
1514"excepthook(exc_type, exc_value, exc_traceback, thread)\n\
1515\n\
1516Handle uncaught Thread.run() exception.");
1517
Barry Warsawd0c10421996-12-17 00:05:22 +00001518static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001520 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001522 METH_VARARGS, start_new_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301523 {"allocate_lock", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301525 {"allocate", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001526 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301527 {"exit_thread", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301529 {"exit", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301531 {"interrupt_main", thread_PyThread_interrupt_main,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 METH_NOARGS, interrupt_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301533 {"get_ident", thread_get_ident,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 METH_NOARGS, get_ident_doc},
Jake Teslerb121f632019-05-22 08:43:17 -07001535#ifdef PY_HAVE_THREAD_NATIVE_ID
1536 {"get_native_id", thread_get_native_id,
1537 METH_NOARGS, get_native_id_doc},
1538#endif
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301539 {"_count", thread__count,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 METH_NOARGS, _count_doc},
1541 {"stack_size", (PyCFunction)thread_stack_size,
Victor Stinner754851f2011-04-19 23:58:51 +02001542 METH_VARARGS, stack_size_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301543 {"_set_sentinel", thread__set_sentinel,
Antoine Pitrou7b476992013-09-07 23:38:37 +02001544 METH_NOARGS, _set_sentinel_doc},
Victor Stinnercd590a72019-05-28 00:39:52 +02001545 {"_excepthook", thread_excepthook,
1546 METH_O, excepthook_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001548};
1549
1550
1551/* Initialization function */
1552
Victor Stinner8203c732020-12-16 12:20:33 +01001553static int
Victor Stinner61040132020-12-18 01:39:00 +01001554thread_module_exec(PyObject *module)
Victor Stinner8203c732020-12-16 12:20:33 +01001555{
Victor Stinner61040132020-12-18 01:39:00 +01001556 thread_module_state *state = get_thread_state(module);
1557 PyObject *d = PyModule_GetDict(module);
1558
Victor Stinner8203c732020-12-16 12:20:33 +01001559 // Initialize the C thread library
1560 PyThread_init_thread();
1561
Victor Stinner61040132020-12-18 01:39:00 +01001562 // Lock
1563 state->lock_type = (PyTypeObject *)PyType_FromSpec(&lock_type_spec);
1564 if (state->lock_type == NULL) {
Victor Stinner8203c732020-12-16 12:20:33 +01001565 return -1;
1566 }
Victor Stinner61040132020-12-18 01:39:00 +01001567 if (PyDict_SetItemString(d, "LockType", (PyObject *)state->lock_type) < 0) {
Victor Stinner8203c732020-12-16 12:20:33 +01001568 return -1;
1569 }
Victor Stinner61040132020-12-18 01:39:00 +01001570
1571 // RLock
1572 PyTypeObject *rlock_type = (PyTypeObject *)PyType_FromSpec(&rlock_type_spec);
1573 if (rlock_type == NULL) {
Victor Stinner8203c732020-12-16 12:20:33 +01001574 return -1;
1575 }
Victor Stinner61040132020-12-18 01:39:00 +01001576 if (PyModule_AddType(module, rlock_type) < 0) {
1577 Py_DECREF(rlock_type);
1578 return -1;
1579 }
1580 Py_DECREF(rlock_type);
1581
1582 // Local dummy
1583 state->local_dummy_type = (PyTypeObject *)PyType_FromSpec(&local_dummy_type_spec);
1584 if (state->local_dummy_type == NULL) {
1585 return -1;
1586 }
1587
1588 // Local
1589 state->local_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &local_type_spec, NULL);
1590 if (state->local_type == NULL) {
1591 return -1;
1592 }
1593 if (PyModule_AddType(module, state->local_type) < 0) {
1594 return -1;
1595 }
1596
Victor Stinner8203c732020-12-16 12:20:33 +01001597 if (ExceptHookArgsType.tp_name == NULL) {
1598 if (PyStructSequence_InitType2(&ExceptHookArgsType,
1599 &ExceptHookArgs_desc) < 0) {
1600 return -1;
1601 }
1602 }
1603
1604 // Add module attributes
Victor Stinner8203c732020-12-16 12:20:33 +01001605 if (PyDict_SetItemString(d, "error", ThreadError) < 0) {
1606 return -1;
1607 }
Victor Stinner8203c732020-12-16 12:20:33 +01001608 if (PyModule_AddType(module, &ExceptHookArgsType) < 0) {
1609 return -1;
1610 }
1611
1612 // TIMEOUT_MAX
1613 double timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6;
1614 double time_max = _PyTime_AsSecondsDouble(_PyTime_MAX);
1615 timeout_max = Py_MIN(timeout_max, time_max);
1616 // Round towards minus infinity
1617 timeout_max = floor(timeout_max);
1618
1619 if (PyModule_AddObject(module, "TIMEOUT_MAX",
1620 PyFloat_FromDouble(timeout_max)) < 0) {
1621 return -1;
1622 }
1623
1624 return 0;
1625}
1626
1627
Victor Stinner61040132020-12-18 01:39:00 +01001628static int
1629thread_module_traverse(PyObject *module, visitproc visit, void *arg)
1630{
1631 thread_module_state *state = get_thread_state(module);
1632 Py_VISIT(state->lock_type);
1633 Py_VISIT(state->local_type);
1634 Py_VISIT(state->local_dummy_type);
1635 return 0;
1636}
1637
1638static int
1639thread_module_clear(PyObject *module)
1640{
1641 thread_module_state *state = get_thread_state(module);
1642 Py_CLEAR(state->lock_type);
1643 Py_CLEAR(state->local_type);
1644 Py_CLEAR(state->local_dummy_type);
1645 return 0;
1646}
1647
1648static void
1649thread_module_free(void *module)
1650{
1651 thread_module_clear((PyObject *)module);
1652}
1653
1654
1655
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001656PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001657"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001658The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001659
Victor Stinner61040132020-12-18 01:39:00 +01001660static PyModuleDef_Slot thread_module_slots[] = {
1661 {Py_mod_exec, thread_module_exec},
1662 {0, NULL}
1663};
1664
1665static struct PyModuleDef thread_module = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 PyModuleDef_HEAD_INIT,
Victor Stinner8203c732020-12-16 12:20:33 +01001667 .m_name = "_thread",
1668 .m_doc = thread_doc,
Victor Stinner61040132020-12-18 01:39:00 +01001669 .m_size = sizeof(thread_module_state),
Victor Stinner8203c732020-12-16 12:20:33 +01001670 .m_methods = thread_methods,
Victor Stinner61040132020-12-18 01:39:00 +01001671 .m_traverse = thread_module_traverse,
1672 .m_clear = thread_module_clear,
1673 .m_free = thread_module_free,
1674 .m_slots = thread_module_slots,
Martin v. Löwis1a214512008-06-11 05:26:20 +00001675};
1676
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001677PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001678PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001679{
Victor Stinner61040132020-12-18 01:39:00 +01001680 return PyModuleDef_Init(&thread_module);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001681}