blob: bd4331c6108bd8d778048de870de5ed54e2c40a0 [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()
Guido van Rossum1984f1e1992-08-04 12:41:02 +000010
Victor Stinner8203c732020-12-16 12:20:33 +010011// ThreadError is just an alias to PyExc_RuntimeError
12#define ThreadError PyExc_RuntimeError
13
14_Py_IDENTIFIER(__dict__);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000015
Victor Stinnerbd303c12013-11-07 23:07:29 +010016_Py_IDENTIFIER(stderr);
Victor Stinnercd590a72019-05-28 00:39:52 +020017_Py_IDENTIFIER(flush);
Victor Stinnerbd303c12013-11-07 23:07:29 +010018
Victor Stinner8203c732020-12-16 12:20:33 +010019
Guido van Rossum1984f1e1992-08-04 12:41:02 +000020/* Lock objects */
21
22typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000023 PyObject_HEAD
24 PyThread_type_lock lock_lock;
25 PyObject *in_weakreflist;
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000026 char locked; /* for sanity checking */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000027} lockobject;
28
Guido van Rossum1984f1e1992-08-04 12:41:02 +000029static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000030lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000031{
Victor Stinner8203c732020-12-16 12:20:33 +010032 if (self->in_weakreflist != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000033 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner8203c732020-12-16 12:20:33 +010034 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000035 if (self->lock_lock != NULL) {
36 /* Unlock the lock so it's safe to free it */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000037 if (self->locked)
38 PyThread_release_lock(self->lock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000039 PyThread_free_lock(self->lock_lock);
40 }
Victor Stinner32bd68c2020-12-01 10:37:39 +010041 PyObject_Free(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000042}
43
Antoine Pitrou810023d2010-12-15 22:59:16 +000044/* Helper to acquire an interruptible lock with a timeout. If the lock acquire
45 * is interrupted, signal handlers are run, and if they raise an exception,
46 * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE
Raymond Hettinger15f44ab2016-08-30 10:47:49 -070047 * are returned, depending on whether the lock can be acquired within the
Antoine Pitrou810023d2010-12-15 22:59:16 +000048 * timeout.
49 */
50static PyLockStatus
Victor Stinnerf5faad22015-03-28 03:52:05 +010051acquire_timed(PyThread_type_lock lock, _PyTime_t timeout)
Antoine Pitrou810023d2010-12-15 22:59:16 +000052{
53 PyLockStatus r;
Victor Stinnerf5faad22015-03-28 03:52:05 +010054 _PyTime_t endtime = 0;
Antoine Pitrou810023d2010-12-15 22:59:16 +000055
Victor Stinner8203c732020-12-16 12:20:33 +010056 if (timeout > 0) {
Victor Stinnerf5faad22015-03-28 03:52:05 +010057 endtime = _PyTime_GetMonotonicClock() + timeout;
Victor Stinner8203c732020-12-16 12:20:33 +010058 }
Antoine Pitrou810023d2010-12-15 22:59:16 +000059
60 do {
Victor Stinner8203c732020-12-16 12:20:33 +010061 _PyTime_t microseconds;
Victor Stinner869e1772015-03-30 03:49:14 +020062 microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING);
Victor Stinnerf5faad22015-03-28 03:52:05 +010063
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000064 /* first a simple non-blocking try without releasing the GIL */
65 r = PyThread_acquire_lock_timed(lock, 0, 0);
66 if (r == PY_LOCK_FAILURE && microseconds != 0) {
67 Py_BEGIN_ALLOW_THREADS
68 r = PyThread_acquire_lock_timed(lock, microseconds, 1);
69 Py_END_ALLOW_THREADS
Victor Stinner357f5152013-11-05 15:10:19 +010070 }
Antoine Pitrou810023d2010-12-15 22:59:16 +000071
72 if (r == PY_LOCK_INTR) {
73 /* Run signal handlers if we were interrupted. Propagate
74 * exceptions from signal handlers, such as KeyboardInterrupt, by
75 * passing up PY_LOCK_INTR. */
76 if (Py_MakePendingCalls() < 0) {
77 return PY_LOCK_INTR;
78 }
79
80 /* If we're using a timeout, recompute the timeout after processing
81 * signals, since those can take time. */
Victor Stinnerf5faad22015-03-28 03:52:05 +010082 if (timeout > 0) {
83 timeout = endtime - _PyTime_GetMonotonicClock();
Antoine Pitrou810023d2010-12-15 22:59:16 +000084
85 /* Check for negative values, since those mean block forever.
86 */
Victor Stinner6aa446c2015-03-30 21:33:51 +020087 if (timeout < 0) {
Antoine Pitrou810023d2010-12-15 22:59:16 +000088 r = PY_LOCK_FAILURE;
89 }
90 }
91 }
92 } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */
93
94 return r;
95}
96
Victor Stinnerf5faad22015-03-28 03:52:05 +010097static int
98lock_acquire_parse_args(PyObject *args, PyObject *kwds,
99 _PyTime_t *timeout)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000100{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000101 char *kwlist[] = {"blocking", "timeout", NULL};
102 int blocking = 1;
Victor Stinnerf5faad22015-03-28 03:52:05 +0100103 PyObject *timeout_obj = NULL;
Victor Stinner13019fd2015-04-03 13:10:54 +0200104 const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000105
Victor Stinnerf5faad22015-03-28 03:52:05 +0100106 *timeout = unset_timeout ;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000107
Victor Stinnerf5faad22015-03-28 03:52:05 +0100108 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:acquire", kwlist,
109 &blocking, &timeout_obj))
110 return -1;
111
112 if (timeout_obj
Victor Stinner869e1772015-03-30 03:49:14 +0200113 && _PyTime_FromSecondsObject(timeout,
Pablo Galindo59af94f2017-10-18 08:13:09 +0100114 timeout_obj, _PyTime_ROUND_TIMEOUT) < 0)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100115 return -1;
116
117 if (!blocking && *timeout != unset_timeout ) {
118 PyErr_SetString(PyExc_ValueError,
119 "can't specify a timeout for a non-blocking call");
120 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100122 if (*timeout < 0 && *timeout != unset_timeout) {
123 PyErr_SetString(PyExc_ValueError,
124 "timeout value must be positive");
125 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000126 }
127 if (!blocking)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100128 *timeout = 0;
129 else if (*timeout != unset_timeout) {
130 _PyTime_t microseconds;
131
Pablo Galindo59af94f2017-10-18 08:13:09 +0100132 microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinnerf5faad22015-03-28 03:52:05 +0100133 if (microseconds >= PY_TIMEOUT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000134 PyErr_SetString(PyExc_OverflowError,
135 "timeout value is too large");
Victor Stinnerf5faad22015-03-28 03:52:05 +0100136 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000138 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100139 return 0;
140}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000141
Victor Stinnerf5faad22015-03-28 03:52:05 +0100142static PyObject *
143lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
144{
145 _PyTime_t timeout;
Victor Stinnerf5faad22015-03-28 03:52:05 +0100146 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
147 return NULL;
148
Victor Stinner8203c732020-12-16 12:20:33 +0100149 PyLockStatus r = acquire_timed(self->lock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000150 if (r == PY_LOCK_INTR) {
151 return NULL;
152 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000154 if (r == PY_LOCK_ACQUIRED)
155 self->locked = 1;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000156 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000157}
158
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000159PyDoc_STRVAR(acquire_doc,
Berker Peksag720e6552016-05-02 12:25:35 +0300160"acquire(blocking=True, timeout=-1) -> bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000161(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000162\n\
163Lock the lock. Without argument, this blocks if the lock is already\n\
164locked (even by the same thread), waiting for another thread to release\n\
R David Murray95b71102013-02-04 10:15:58 -0500165the lock, and return True once the lock is acquired.\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000166With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000167and the return value reflects whether the lock is acquired.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000168The blocking operation is interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000169
Barry Warsawd0c10421996-12-17 00:05:22 +0000170static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530171lock_PyThread_release_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000172{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 /* Sanity check: the lock must be locked */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000174 if (!self->locked) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 PyErr_SetString(ThreadError, "release unlocked lock");
176 return NULL;
177 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000179 PyThread_release_lock(self->lock_lock);
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000180 self->locked = 0;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200181 Py_RETURN_NONE;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000182}
183
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000184PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000185"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000186(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000187\n\
188Release the lock, allowing another thread that is blocked waiting for\n\
189the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000190but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000191
Barry Warsawd0c10421996-12-17 00:05:22 +0000192static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530193lock_locked_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000194{
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000195 return PyBool_FromLong((long)self->locked);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000196}
197
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000198PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000199"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000200(locked_lock() is an obsolete synonym)\n\
201\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000202Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000203
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700204static PyObject *
205lock_repr(lockobject *self)
206{
207 return PyUnicode_FromFormat("<%s %s object at %p>",
208 self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
209}
210
Victor Stinner87255be2020-04-07 23:11:49 +0200211#ifdef HAVE_FORK
212static PyObject *
213lock__at_fork_reinit(lockobject *self, PyObject *Py_UNUSED(args))
214{
215 if (_PyThread_at_fork_reinit(&self->lock_lock) < 0) {
216 PyErr_SetString(ThreadError, "failed to reinitialize lock at fork");
217 return NULL;
218 }
219
220 self->locked = 0;
221
222 Py_RETURN_NONE;
223}
224#endif /* HAVE_FORK */
225
226
Barry Warsawd0c10421996-12-17 00:05:22 +0000227static PyMethodDef lock_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200228 {"acquire_lock", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 METH_VARARGS | METH_KEYWORDS, acquire_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200230 {"acquire", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 METH_VARARGS | METH_KEYWORDS, acquire_doc},
232 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
233 METH_NOARGS, release_doc},
234 {"release", (PyCFunction)lock_PyThread_release_lock,
235 METH_NOARGS, release_doc},
236 {"locked_lock", (PyCFunction)lock_locked_lock,
237 METH_NOARGS, locked_doc},
238 {"locked", (PyCFunction)lock_locked_lock,
239 METH_NOARGS, locked_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200240 {"__enter__", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 METH_VARARGS | METH_KEYWORDS, acquire_doc},
242 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
243 METH_VARARGS, release_doc},
Victor Stinner87255be2020-04-07 23:11:49 +0200244#ifdef HAVE_FORK
245 {"_at_fork_reinit", (PyCFunction)lock__at_fork_reinit,
246 METH_NOARGS, NULL},
247#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000249};
250
Victor Stinner8203c732020-12-16 12:20:33 +0100251PyDoc_STRVAR(lock_doc,
252"A lock object is a synchronization primitive. To create a lock,\n\
253call threading.Lock(). Methods are:\n\
254\n\
255acquire() -- lock the lock, possibly blocking until it can be obtained\n\
256release() -- unlock of the lock\n\
257locked() -- test whether the lock is currently locked\n\
258\n\
259A lock is not owned by the thread that locked it; another thread may\n\
260unlock it. A thread attempting to lock a lock that it has already locked\n\
261will block until another thread unlocks it. Deadlocks may ensue.");
262
Barry Warsawd0c10421996-12-17 00:05:22 +0000263static PyTypeObject Locktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Victor Stinner8203c732020-12-16 12:20:33 +0100265 .tp_name = "_thread.lock",
266 .tp_basicsize = sizeof(lockobject),
267 .tp_dealloc = (destructor)lock_dealloc,
268 .tp_repr = (reprfunc)lock_repr,
269 .tp_flags = Py_TPFLAGS_DEFAULT,
270 .tp_doc = lock_doc,
271 .tp_weaklistoffset = offsetof(lockobject, in_weakreflist),
272 .tp_methods = lock_methods,
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000273};
274
Antoine Pitrou434736a2009-11-10 18:46:01 +0000275/* Recursive lock objects */
276
277typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278 PyObject_HEAD
279 PyThread_type_lock rlock_lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200280 unsigned long rlock_owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 unsigned long rlock_count;
282 PyObject *in_weakreflist;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000283} rlockobject;
284
285static void
286rlock_dealloc(rlockobject *self)
287{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 if (self->in_weakreflist != NULL)
289 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner357f5152013-11-05 15:10:19 +0100290 /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed
291 in rlock_new() */
292 if (self->rlock_lock != NULL) {
293 /* Unlock the lock so it's safe to free it */
294 if (self->rlock_count > 0)
295 PyThread_release_lock(self->rlock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296
Victor Stinner357f5152013-11-05 15:10:19 +0100297 PyThread_free_lock(self->rlock_lock);
298 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000299 Py_TYPE(self)->tp_free(self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000300}
301
302static PyObject *
303rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
304{
Victor Stinnerf5faad22015-03-28 03:52:05 +0100305 _PyTime_t timeout;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200306 unsigned long tid;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000307 PyLockStatus r = PY_LOCK_ACQUIRED;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000308
Victor Stinnerf5faad22015-03-28 03:52:05 +0100309 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 tid = PyThread_get_thread_ident();
313 if (self->rlock_count > 0 && tid == self->rlock_owner) {
314 unsigned long count = self->rlock_count + 1;
315 if (count <= self->rlock_count) {
316 PyErr_SetString(PyExc_OverflowError,
317 "Internal lock count overflowed");
318 return NULL;
319 }
320 self->rlock_count = count;
321 Py_RETURN_TRUE;
322 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100323 r = acquire_timed(self->rlock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000324 if (r == PY_LOCK_ACQUIRED) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 assert(self->rlock_count == 0);
326 self->rlock_owner = tid;
327 self->rlock_count = 1;
328 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000329 else if (r == PY_LOCK_INTR) {
330 return NULL;
331 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332
Antoine Pitrou810023d2010-12-15 22:59:16 +0000333 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000334}
335
336PyDoc_STRVAR(rlock_acquire_doc,
337"acquire(blocking=True) -> bool\n\
338\n\
339Lock the lock. `blocking` indicates whether we should wait\n\
340for the lock to be available or not. If `blocking` is False\n\
341and another thread holds the lock, the method will return False\n\
342immediately. If `blocking` is True and another thread holds\n\
343the lock, the method will wait for the lock to be released,\n\
344take it and then return True.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000345(note: the blocking operation is interruptible.)\n\
Antoine Pitrou434736a2009-11-10 18:46:01 +0000346\n\
347In all other cases, the method will return True immediately.\n\
348Precisely, if the current thread already holds the lock, its\n\
349internal counter is simply incremented. If nobody holds the lock,\n\
350the lock is taken and its internal counter initialized to 1.");
351
352static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530353rlock_release(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000354{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200355 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrou434736a2009-11-10 18:46:01 +0000356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 if (self->rlock_count == 0 || self->rlock_owner != tid) {
358 PyErr_SetString(PyExc_RuntimeError,
359 "cannot release un-acquired lock");
360 return NULL;
361 }
362 if (--self->rlock_count == 0) {
363 self->rlock_owner = 0;
364 PyThread_release_lock(self->rlock_lock);
365 }
366 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000367}
368
369PyDoc_STRVAR(rlock_release_doc,
370"release()\n\
371\n\
372Release the lock, allowing another thread that is blocked waiting for\n\
373the lock to acquire the lock. The lock must be in the locked state,\n\
374and must be locked by the same thread that unlocks it; otherwise a\n\
375`RuntimeError` is raised.\n\
376\n\
377Do note that if the lock was acquire()d several times in a row by the\n\
378current thread, release() needs to be called as many times for the lock\n\
379to be available for other threads.");
380
381static PyObject *
Victor Stinnere8794522014-01-02 12:47:24 +0100382rlock_acquire_restore(rlockobject *self, PyObject *args)
Antoine Pitrou434736a2009-11-10 18:46:01 +0000383{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200384 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 unsigned long count;
386 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000387
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200388 if (!PyArg_ParseTuple(args, "(kk):_acquire_restore", &count, &owner))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
392 Py_BEGIN_ALLOW_THREADS
393 r = PyThread_acquire_lock(self->rlock_lock, 1);
394 Py_END_ALLOW_THREADS
395 }
396 if (!r) {
397 PyErr_SetString(ThreadError, "couldn't acquire lock");
398 return NULL;
399 }
400 assert(self->rlock_count == 0);
401 self->rlock_owner = owner;
402 self->rlock_count = count;
403 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000404}
405
406PyDoc_STRVAR(rlock_acquire_restore_doc,
407"_acquire_restore(state) -> None\n\
408\n\
409For internal use by `threading.Condition`.");
410
411static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530412rlock_release_save(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000413{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200414 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 unsigned long count;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000416
Victor Stinnerc2824d42011-04-24 23:41:33 +0200417 if (self->rlock_count == 0) {
418 PyErr_SetString(PyExc_RuntimeError,
419 "cannot release un-acquired lock");
420 return NULL;
421 }
422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 owner = self->rlock_owner;
424 count = self->rlock_count;
425 self->rlock_count = 0;
426 self->rlock_owner = 0;
427 PyThread_release_lock(self->rlock_lock);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200428 return Py_BuildValue("kk", count, owner);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000429}
430
431PyDoc_STRVAR(rlock_release_save_doc,
432"_release_save() -> tuple\n\
433\n\
434For internal use by `threading.Condition`.");
435
436
437static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530438rlock_is_owned(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000439{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200440 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441
442 if (self->rlock_count > 0 && self->rlock_owner == tid) {
443 Py_RETURN_TRUE;
444 }
445 Py_RETURN_FALSE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000446}
447
448PyDoc_STRVAR(rlock_is_owned_doc,
449"_is_owned() -> bool\n\
450\n\
451For internal use by `threading.Condition`.");
452
453static PyObject *
454rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
455{
Victor Stinner87255be2020-04-07 23:11:49 +0200456 rlockobject *self = (rlockobject *) type->tp_alloc(type, 0);
457 if (self == NULL) {
458 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 }
Victor Stinner87255be2020-04-07 23:11:49 +0200460 self->in_weakreflist = NULL;
461 self->rlock_owner = 0;
462 self->rlock_count = 0;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000463
Victor Stinner87255be2020-04-07 23:11:49 +0200464 self->rlock_lock = PyThread_allocate_lock();
465 if (self->rlock_lock == NULL) {
466 Py_DECREF(self);
467 PyErr_SetString(ThreadError, "can't allocate lock");
468 return NULL;
469 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 return (PyObject *) self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000471}
472
473static PyObject *
474rlock_repr(rlockobject *self)
475{
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700476 return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>",
477 self->rlock_count ? "locked" : "unlocked",
478 Py_TYPE(self)->tp_name, self->rlock_owner,
479 self->rlock_count, self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000480}
481
482
Victor Stinner87255be2020-04-07 23:11:49 +0200483#ifdef HAVE_FORK
484static PyObject *
485rlock__at_fork_reinit(rlockobject *self, PyObject *Py_UNUSED(args))
486{
487 if (_PyThread_at_fork_reinit(&self->rlock_lock) < 0) {
488 PyErr_SetString(ThreadError, "failed to reinitialize lock at fork");
489 return NULL;
490 }
491
492 self->rlock_owner = 0;
493 self->rlock_count = 0;
494
495 Py_RETURN_NONE;
496}
497#endif /* HAVE_FORK */
498
499
Antoine Pitrou434736a2009-11-10 18:46:01 +0000500static PyMethodDef rlock_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200501 {"acquire", (PyCFunction)(void(*)(void))rlock_acquire,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
503 {"release", (PyCFunction)rlock_release,
504 METH_NOARGS, rlock_release_doc},
505 {"_is_owned", (PyCFunction)rlock_is_owned,
506 METH_NOARGS, rlock_is_owned_doc},
507 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
Victor Stinnere8794522014-01-02 12:47:24 +0100508 METH_VARARGS, rlock_acquire_restore_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 {"_release_save", (PyCFunction)rlock_release_save,
510 METH_NOARGS, rlock_release_save_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200511 {"__enter__", (PyCFunction)(void(*)(void))rlock_acquire,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
513 {"__exit__", (PyCFunction)rlock_release,
514 METH_VARARGS, rlock_release_doc},
Victor Stinner87255be2020-04-07 23:11:49 +0200515#ifdef HAVE_FORK
516 {"_at_fork_reinit", (PyCFunction)rlock__at_fork_reinit,
517 METH_NOARGS, NULL},
518#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 {NULL, NULL} /* sentinel */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000520};
521
522
523static PyTypeObject RLocktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Victor Stinner8203c732020-12-16 12:20:33 +0100525 .tp_name = "_thread.RLock",
526 .tp_basicsize = sizeof(rlockobject),
527 .tp_dealloc = (destructor)rlock_dealloc,
528 .tp_repr = (reprfunc)rlock_repr,
529 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
530 .tp_weaklistoffset = offsetof(rlockobject, in_weakreflist),
531 .tp_methods = rlock_methods,
532 .tp_alloc = PyType_GenericAlloc,
533 .tp_new = rlock_new,
Antoine Pitrou434736a2009-11-10 18:46:01 +0000534};
535
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000536static lockobject *
537newlockobject(void)
538{
Victor Stinner8203c732020-12-16 12:20:33 +0100539 lockobject *self = PyObject_New(lockobject, &Locktype);
540 if (self == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 return NULL;
Victor Stinner8203c732020-12-16 12:20:33 +0100542 }
543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 self->lock_lock = PyThread_allocate_lock();
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000545 self->locked = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 self->in_weakreflist = NULL;
Victor Stinner8203c732020-12-16 12:20:33 +0100547
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 if (self->lock_lock == NULL) {
549 Py_DECREF(self);
550 PyErr_SetString(ThreadError, "can't allocate lock");
551 return NULL;
552 }
553 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000554}
555
Jim Fultond15dc062004-07-14 19:11:50 +0000556/* Thread-local objects */
557
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000558/* Quick overview:
559
560 We need to be able to reclaim reference cycles as soon as possible
561 (both when a thread is being terminated, or a thread-local object
562 becomes unreachable from user data). Constraints:
563 - it must not be possible for thread-state dicts to be involved in
564 reference cycles (otherwise the cyclic GC will refuse to consider
565 objects referenced from a reachable thread-state dict, even though
566 local_dealloc would clear them)
567 - the death of a thread-state dict must still imply destruction of the
568 corresponding local dicts in all thread-local objects.
569
570 Our implementation uses small "localdummy" objects in order to break
571 the reference chain. These trivial objects are hashable (using the
572 default scheme of identity hashing) and weakrefable.
573 Each thread-state holds a separate localdummy for each local object
574 (as a /strong reference/),
575 and each thread-local object holds a dict mapping /weak references/
576 of localdummies to local dicts.
577
578 Therefore:
579 - only the thread-state dict holds a strong reference to the dummies
580 - only the thread-local object holds a strong reference to the local dicts
581 - only outside objects (application- or library-level) hold strong
582 references to the thread-local objects
583 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
584 dummies attached to that thread are called, and destroy the corresponding
585 local dicts from thread-local objects
586 - as soon as a thread-local object is destroyed, its local dicts are
587 destroyed and its dummies are manually removed from all thread states
588 - the GC can do its work correctly when a thread-local object is dangling,
589 without any interference from the thread-state dicts
590
591 As an additional optimization, each localdummy holds a borrowed reference
592 to the corresponding localdict. This borrowed reference is only used
593 by the thread-local object which has created the localdummy, which should
594 guarantee that the localdict still exists when accessed.
595*/
596
597typedef struct {
598 PyObject_HEAD
599 PyObject *localdict; /* Borrowed reference! */
600 PyObject *weakreflist; /* List of weak references to self */
601} localdummyobject;
602
603static void
604localdummy_dealloc(localdummyobject *self)
605{
606 if (self->weakreflist != NULL)
607 PyObject_ClearWeakRefs((PyObject *) self);
608 Py_TYPE(self)->tp_free((PyObject*)self);
609}
610
611static PyTypeObject localdummytype = {
612 PyVarObject_HEAD_INIT(NULL, 0)
Victor Stinner8203c732020-12-16 12:20:33 +0100613 .tp_name = "_thread._localdummy",
614 .tp_basicsize = sizeof(localdummyobject),
615 .tp_dealloc = (destructor)localdummy_dealloc,
616 .tp_flags = Py_TPFLAGS_DEFAULT,
617 .tp_doc = "Thread-local dummy",
618 .tp_weaklistoffset = offsetof(localdummyobject, weakreflist),
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000619};
620
621
Jim Fultond15dc062004-07-14 19:11:50 +0000622typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 PyObject_HEAD
624 PyObject *key;
625 PyObject *args;
626 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000627 PyObject *weakreflist; /* List of weak references to self */
628 /* A {localdummy weakref -> localdict} dict */
629 PyObject *dummies;
630 /* The callback for weakrefs to localdummies */
631 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000632} localobject;
633
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000634/* Forward declaration */
635static PyObject *_ldict(localobject *self);
636static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
637
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000638/* Create and register the dummy for the current thread.
639 Returns a borrowed reference of the corresponding local dict */
640static PyObject *
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000641_local_create_dummy(localobject *self)
642{
Victor Stinner8203c732020-12-16 12:20:33 +0100643 PyObject *ldict = NULL, *wr = NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000644 localdummyobject *dummy = NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000645
Victor Stinner8203c732020-12-16 12:20:33 +0100646 PyObject *tdict = PyThreadState_GetDict();
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000647 if (tdict == NULL) {
648 PyErr_SetString(PyExc_SystemError,
649 "Couldn't get thread-state dictionary");
650 goto err;
651 }
652
653 ldict = PyDict_New();
Victor Stinner8203c732020-12-16 12:20:33 +0100654 if (ldict == NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000655 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100656 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000657 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
Victor Stinner8203c732020-12-16 12:20:33 +0100658 if (dummy == NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000659 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100660 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000661 dummy->localdict = ldict;
662 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
Victor Stinner8203c732020-12-16 12:20:33 +0100663 if (wr == NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000664 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100665 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000666
667 /* As a side-effect, this will cache the weakref's hash before the
668 dummy gets deleted */
Victor Stinner8203c732020-12-16 12:20:33 +0100669 int r = PyDict_SetItem(self->dummies, wr, ldict);
670 if (r < 0) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000671 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100672 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000673 Py_CLEAR(wr);
674 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
Victor Stinner8203c732020-12-16 12:20:33 +0100675 if (r < 0) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000676 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100677 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000678 Py_CLEAR(dummy);
679
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000680 Py_DECREF(ldict);
681 return ldict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000682
683err:
684 Py_XDECREF(ldict);
685 Py_XDECREF(wr);
686 Py_XDECREF(dummy);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000687 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000688}
689
Jim Fultond15dc062004-07-14 19:11:50 +0000690static PyObject *
691local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
692{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000693 localobject *self;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000694 static PyMethodDef wr_callback_def = {
695 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
696 };
Jim Fultond15dc062004-07-14 19:11:50 +0000697
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300698 if (type->tp_init == PyBaseObject_Type.tp_init) {
699 int rc = 0;
700 if (args != NULL)
701 rc = PyObject_IsTrue(args);
702 if (rc == 0 && kw != NULL)
703 rc = PyObject_IsTrue(kw);
704 if (rc != 0) {
Victor Stinner8203c732020-12-16 12:20:33 +0100705 if (rc > 0) {
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300706 PyErr_SetString(PyExc_TypeError,
707 "Initialization arguments are not supported");
Victor Stinner8203c732020-12-16 12:20:33 +0100708 }
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300709 return NULL;
710 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 }
Jim Fultond15dc062004-07-14 19:11:50 +0000712
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000713 self = (localobject *)type->tp_alloc(type, 0);
Victor Stinner8203c732020-12-16 12:20:33 +0100714 if (self == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 return NULL;
Victor Stinner8203c732020-12-16 12:20:33 +0100716 }
Jim Fultond15dc062004-07-14 19:11:50 +0000717
Victor Stinner8203c732020-12-16 12:20:33 +0100718 self->args = Py_XNewRef(args);
719 self->kw = Py_XNewRef(kw);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 self->key = PyUnicode_FromFormat("thread.local.%p", self);
Victor Stinner8203c732020-12-16 12:20:33 +0100721 if (self->key == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100723 }
Jim Fultond15dc062004-07-14 19:11:50 +0000724
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000725 self->dummies = PyDict_New();
Victor Stinner8203c732020-12-16 12:20:33 +0100726 if (self->dummies == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100728 }
Jim Fultond15dc062004-07-14 19:11:50 +0000729
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000730 /* We use a weak reference to self in the callback closure
731 in order to avoid spurious reference cycles */
Victor Stinner8203c732020-12-16 12:20:33 +0100732 PyObject *wr = PyWeakref_NewRef((PyObject *) self, NULL);
733 if (wr == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100735 }
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200736 self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000737 Py_DECREF(wr);
Victor Stinner8203c732020-12-16 12:20:33 +0100738 if (self->wr_callback == NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000739 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100740 }
741 if (_local_create_dummy(self) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 goto err;
Victor Stinner8203c732020-12-16 12:20:33 +0100743 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000744 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000745
746 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 Py_DECREF(self);
748 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000749}
750
751static int
752local_traverse(localobject *self, visitproc visit, void *arg)
753{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 Py_VISIT(self->args);
755 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000756 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000757 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000758}
759
760static int
761local_clear(localobject *self)
762{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000763 PyThreadState *tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000764 Py_CLEAR(self->args);
765 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000766 Py_CLEAR(self->dummies);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000767 Py_CLEAR(self->wr_callback);
768 /* Remove all strong references to dummies from the thread states */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 if (self->key
770 && (tstate = PyThreadState_Get())
771 && tstate->interp) {
772 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
773 tstate;
774 tstate = PyThreadState_Next(tstate))
Serhiy Storchakafb5db7e2020-10-26 08:43:39 +0200775 if (tstate->dict) {
776 PyObject *v = _PyDict_Pop(tstate->dict, self->key, Py_None);
777 if (v == NULL) {
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200778 PyErr_Clear();
779 }
Serhiy Storchakafb5db7e2020-10-26 08:43:39 +0200780 else {
781 Py_DECREF(v);
782 }
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200783 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000784 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000785 return 0;
786}
Jim Fultond15dc062004-07-14 19:11:50 +0000787
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000788static void
789local_dealloc(localobject *self)
790{
791 /* Weakrefs must be invalidated right now, otherwise they can be used
792 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
Victor Stinner8203c732020-12-16 12:20:33 +0100793 if (self->weakreflist != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000794 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner8203c732020-12-16 12:20:33 +0100795 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000796
797 PyObject_GC_UnTrack(self);
798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000799 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000800 Py_XDECREF(self->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000802}
803
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000804/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000805static PyObject *
806_ldict(localobject *self)
807{
Victor Stinner8203c732020-12-16 12:20:33 +0100808 PyObject *tdict = PyThreadState_GetDict();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 if (tdict == NULL) {
810 PyErr_SetString(PyExc_SystemError,
811 "Couldn't get thread-state dictionary");
812 return NULL;
813 }
Jim Fultond15dc062004-07-14 19:11:50 +0000814
Victor Stinner8203c732020-12-16 12:20:33 +0100815 PyObject *ldict;
816 PyObject *dummy = PyDict_GetItemWithError(tdict, self->key);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000817 if (dummy == NULL) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200818 if (PyErr_Occurred()) {
819 return NULL;
820 }
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000821 ldict = _local_create_dummy(self);
822 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000823 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000824
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000825 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
826 Py_TYPE(self)->tp_init((PyObject*)self,
827 self->args, self->kw) < 0) {
828 /* we need to get rid of ldict from thread so
829 we create a new one the next time we do an attr
Ezio Melotti42da6632011-03-15 05:18:48 +0200830 access */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000831 PyDict_DelItem(tdict, self->key);
832 return NULL;
833 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000834 }
835 else {
Andy Lesterdffe4c02020-03-04 07:15:20 -0600836 assert(Py_IS_TYPE(dummy, &localdummytype));
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000837 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000838 }
Jim Fultond15dc062004-07-14 19:11:50 +0000839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000840 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000841}
842
Jim Fultond15dc062004-07-14 19:11:50 +0000843static int
844local_setattro(localobject *self, PyObject *name, PyObject *v)
845{
Victor Stinner8203c732020-12-16 12:20:33 +0100846 PyObject *ldict = _ldict(self);
847 if (ldict == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 return -1;
Victor Stinner8203c732020-12-16 12:20:33 +0100849 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000850
Victor Stinner8203c732020-12-16 12:20:33 +0100851 PyObject *str_dict = _PyUnicode_FromId(&PyId___dict__); // borrowed ref
852 if (str_dict == NULL) {
853 return -1;
854 }
855
856 int r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
857 if (r == -1) {
858 return -1;
859 }
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000860 if (r == 1) {
861 PyErr_Format(PyExc_AttributeError,
862 "'%.50s' object attribute '%U' is read-only",
863 Py_TYPE(self)->tp_name, name);
864 return -1;
865 }
Jim Fultond15dc062004-07-14 19:11:50 +0000866
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000867 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000868}
869
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000870static PyObject *local_getattro(localobject *, PyObject *);
871
Jim Fultond15dc062004-07-14 19:11:50 +0000872static PyTypeObject localtype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000873 PyVarObject_HEAD_INIT(NULL, 0)
Victor Stinner8203c732020-12-16 12:20:33 +0100874 .tp_name = "_thread._local",
875 .tp_basicsize = sizeof(localobject),
876 .tp_dealloc = (destructor)local_dealloc,
877 .tp_getattro = (getattrofunc)local_getattro,
878 .tp_setattro = (setattrofunc)local_setattro,
879 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
880 .tp_doc = "Thread-local data",
881 .tp_traverse = (traverseproc)local_traverse,
882 .tp_clear = (inquiry)local_clear,
883 .tp_weaklistoffset = offsetof(localobject, weakreflist),
884 .tp_new = local_new,
Jim Fultond15dc062004-07-14 19:11:50 +0000885};
886
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000887static PyObject *
888local_getattro(localobject *self, PyObject *name)
889{
Victor Stinner8203c732020-12-16 12:20:33 +0100890 PyObject *ldict = _ldict(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 if (ldict == NULL)
892 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000893
Victor Stinner8203c732020-12-16 12:20:33 +0100894 PyObject *str_dict = _PyUnicode_FromId(&PyId___dict__); // borrowed ref
895 if (str_dict == NULL) {
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000896 return NULL;
Victor Stinner8203c732020-12-16 12:20:33 +0100897 }
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000898
Victor Stinner8203c732020-12-16 12:20:33 +0100899 int r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
900 if (r == 1) {
901 return Py_NewRef(ldict);
902 }
903 if (r == -1) {
904 return NULL;
905 }
906
907 if (!Py_IS_TYPE(self, &localtype)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000908 /* use generic lookup for subtypes */
Victor Stinner8203c732020-12-16 12:20:33 +0100909 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name,
910 ldict, 0);
911 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 /* Optimization: just look in dict ourselves */
Victor Stinner8203c732020-12-16 12:20:33 +0100914 PyObject *value = PyDict_GetItemWithError(ldict, name);
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200915 if (value != NULL) {
Victor Stinner8203c732020-12-16 12:20:33 +0100916 return Py_NewRef(value);
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200917 }
Victor Stinner8203c732020-12-16 12:20:33 +0100918 if (PyErr_Occurred()) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200919 return NULL;
920 }
Victor Stinner8203c732020-12-16 12:20:33 +0100921
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200922 /* Fall back on generic to get __class__ and __dict__ */
923 return _PyObject_GenericGetAttrWithDict(
924 (PyObject *)self, name, ldict, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000925}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000926
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000927/* Called when a dummy is destroyed. */
928static PyObject *
929_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
930{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000931 assert(PyWeakref_CheckRef(localweakref));
Victor Stinner8203c732020-12-16 12:20:33 +0100932 PyObject *obj = PyWeakref_GET_OBJECT(localweakref);
933 if (obj == Py_None) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000934 Py_RETURN_NONE;
Victor Stinner8203c732020-12-16 12:20:33 +0100935 }
936
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000937 /* If the thread-local object is still alive and not being cleared,
938 remove the corresponding local dict */
Victor Stinner8203c732020-12-16 12:20:33 +0100939 localobject *self = (localobject *)Py_NewRef(obj);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000940 if (self->dummies != NULL) {
941 PyObject *ldict;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200942 ldict = PyDict_GetItemWithError(self->dummies, dummyweakref);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000943 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000944 PyDict_DelItem(self->dummies, dummyweakref);
945 }
946 if (PyErr_Occurred())
947 PyErr_WriteUnraisable(obj);
948 }
949 Py_DECREF(obj);
950 Py_RETURN_NONE;
951}
952
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000953/* Module functions */
954
Guido van Rossuma027efa1997-05-05 20:56:21 +0000955struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000956 PyInterpreterState *interp;
957 PyObject *func;
958 PyObject *args;
Victor Stinner8203c732020-12-16 12:20:33 +0100959 PyObject *kwargs;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000960 PyThreadState *tstate;
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -0300961 _PyRuntimeState *runtime;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000962};
963
Victor Stinner8203c732020-12-16 12:20:33 +0100964
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000965static void
Victor Stinner8203c732020-12-16 12:20:33 +0100966thread_bootstate_free(struct bootstate *boot)
967{
968 Py_DECREF(boot->func);
969 Py_DECREF(boot->args);
970 Py_XDECREF(boot->kwargs);
971 PyMem_Free(boot);
972}
973
974
975static void
976thread_run(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000977{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 struct bootstate *boot = (struct bootstate *) boot_raw;
979 PyThreadState *tstate;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 tstate = boot->tstate;
982 tstate->thread_id = PyThread_get_thread_ident();
Victor Stinner01b1cc12019-11-20 02:27:56 +0100983 _PyThreadState_Init(tstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 PyEval_AcquireThread(tstate);
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600985 tstate->interp->num_threads++;
Victor Stinner8203c732020-12-16 12:20:33 +0100986
987 PyObject *res = PyObject_Call(boot->func, boot->args, boot->kwargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 if (res == NULL) {
989 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Victor Stinner8b095002019-05-29 02:57:56 +0200990 /* SystemExit is ignored silently */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 PyErr_Clear();
992 else {
Victor Stinner8b095002019-05-29 02:57:56 +0200993 _PyErr_WriteUnraisableMsg("in thread started by", boot->func);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000994 }
995 }
Victor Stinner8b095002019-05-29 02:57:56 +0200996 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000997 Py_DECREF(res);
Victor Stinner8b095002019-05-29 02:57:56 +0200998 }
Victor Stinner8203c732020-12-16 12:20:33 +0100999
1000 thread_bootstate_free(boot);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001001 tstate->interp->num_threads--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 PyThreadState_Clear(tstate);
Victor Stinner23ef89d2020-03-18 02:26:04 +01001003 _PyThreadState_DeleteCurrent(tstate);
Victor Stinner8203c732020-12-16 12:20:33 +01001004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001006}
1007
Barry Warsawd0c10421996-12-17 00:05:22 +00001008static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001009thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001010{
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001011 _PyRuntimeState *runtime = &_PyRuntime;
Victor Stinner8203c732020-12-16 12:20:33 +01001012 PyObject *func, *args, *kwargs = NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
Victor Stinner8203c732020-12-16 12:20:33 +01001015 &func, &args, &kwargs))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 return NULL;
1017 if (!PyCallable_Check(func)) {
1018 PyErr_SetString(PyExc_TypeError,
1019 "first arg must be callable");
1020 return NULL;
1021 }
1022 if (!PyTuple_Check(args)) {
1023 PyErr_SetString(PyExc_TypeError,
1024 "2nd arg must be a tuple");
1025 return NULL;
1026 }
Victor Stinner8203c732020-12-16 12:20:33 +01001027 if (kwargs != NULL && !PyDict_Check(kwargs)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 PyErr_SetString(PyExc_TypeError,
1029 "optional 3rd arg must be a dictionary");
1030 return NULL;
1031 }
Victor Stinner252346a2020-05-01 11:33:44 +02001032
1033 PyInterpreterState *interp = _PyInterpreterState_GET();
1034 if (interp->config._isolated_interpreter) {
1035 PyErr_SetString(PyExc_RuntimeError,
1036 "thread is not supported for isolated subinterpreters");
1037 return NULL;
1038 }
1039
Victor Stinner8203c732020-12-16 12:20:33 +01001040 struct bootstate *boot = PyMem_NEW(struct bootstate, 1);
1041 if (boot == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 return PyErr_NoMemory();
Victor Stinner8203c732020-12-16 12:20:33 +01001043 }
Victor Stinner81a7be32020-04-14 15:14:01 +02001044 boot->interp = _PyInterpreterState_GET();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 boot->tstate = _PyThreadState_Prealloc(boot->interp);
1046 if (boot->tstate == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01001047 PyMem_Free(boot);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 return PyErr_NoMemory();
1049 }
Victor Stinner8203c732020-12-16 12:20:33 +01001050 boot->runtime = runtime;
1051 boot->func = Py_NewRef(func);
1052 boot->args = Py_NewRef(args);
1053 boot->kwargs = Py_XNewRef(kwargs);
Victor Stinner3225b9f2020-03-09 20:56:57 +01001054
Victor Stinner8203c732020-12-16 12:20:33 +01001055 unsigned long ident = PyThread_start_new_thread(thread_run, (void*) boot);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001056 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 PyErr_SetString(ThreadError, "can't start new thread");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 PyThreadState_Clear(boot->tstate);
Victor Stinner8203c732020-12-16 12:20:33 +01001059 thread_bootstate_free(boot);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 return NULL;
1061 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001062 return PyLong_FromUnsignedLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001063}
1064
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001065PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001066"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001067(start_new() is an obsolete synonym)\n\
1068\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001069Start a new thread and return its identifier. The thread will call the\n\
1070function with positional arguments from the tuple args and keyword arguments\n\
1071taken from the optional dictionary kwargs. The thread exits when the\n\
1072function returns; the return value is ignored. The thread will also exit\n\
1073when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001074printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001075
Barry Warsawd0c10421996-12-17 00:05:22 +00001076static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301077thread_PyThread_exit_thread(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001078{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001079 PyErr_SetNone(PyExc_SystemExit);
1080 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001081}
1082
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001083PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001084"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001085(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001086\n\
1087This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001088thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001089
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001090static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301091thread_PyThread_interrupt_main(PyObject * self, PyObject *Py_UNUSED(ignored))
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001092{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 PyErr_SetInterrupt();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001094 Py_RETURN_NONE;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001095}
1096
1097PyDoc_STRVAR(interrupt_doc,
1098"interrupt_main()\n\
1099\n\
1100Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001101A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001102);
1103
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001104static lockobject *newlockobject(void);
1105
Barry Warsawd0c10421996-12-17 00:05:22 +00001106static PyObject *
Victor Stinner8203c732020-12-16 12:20:33 +01001107thread_PyThread_allocate_lock(PyObject *module, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001108{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001109 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001110}
1111
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001112PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001113"allocate_lock() -> lock object\n\
1114(allocate() is an obsolete synonym)\n\
1115\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001116Create a new lock object. See help(type(threading.Lock())) for\n\
1117information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001118
Barry Warsawd0c10421996-12-17 00:05:22 +00001119static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301120thread_get_ident(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001121{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001122 unsigned long ident = PyThread_get_thread_ident();
1123 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001124 PyErr_SetString(ThreadError, "no current thread ident");
1125 return NULL;
1126 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001127 return PyLong_FromUnsignedLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001128}
1129
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001130PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001131"get_ident() -> integer\n\
1132\n\
1133Return a non-zero integer that uniquely identifies the current thread\n\
1134amongst other threads that exist simultaneously.\n\
1135This may be used to identify per-thread resources.\n\
1136Even though on some platforms threads identities may appear to be\n\
1137allocated consecutive numbers starting at 1, this behavior should not\n\
1138be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001139A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001140
Jake Teslerb121f632019-05-22 08:43:17 -07001141#ifdef PY_HAVE_THREAD_NATIVE_ID
1142static PyObject *
1143thread_get_native_id(PyObject *self, PyObject *Py_UNUSED(ignored))
1144{
1145 unsigned long native_id = PyThread_get_thread_native_id();
1146 return PyLong_FromUnsignedLong(native_id);
1147}
1148
1149PyDoc_STRVAR(get_native_id_doc,
1150"get_native_id() -> integer\n\
1151\n\
1152Return a non-negative integer identifying the thread as reported\n\
1153by the OS (kernel). This may be used to uniquely identify a\n\
1154particular thread within a system.");
1155#endif
1156
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001157static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301158thread__count(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001159{
Victor Stinner81a7be32020-04-14 15:14:01 +02001160 PyInterpreterState *interp = _PyInterpreterState_GET();
Victor Stinnercaba55b2018-08-03 15:33:52 +02001161 return PyLong_FromLong(interp->num_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001162}
1163
1164PyDoc_STRVAR(_count_doc,
1165"_count() -> integer\n\
1166\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001167\
oldkaa0735f2018-02-02 16:52:55 +08001168Return the number of currently running Python threads, excluding\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001169the main thread. The returned number comprises all threads created\n\
1170through `start_new_thread()` as well as `threading.Thread`, and not\n\
1171yet finished.\n\
1172\n\
1173This function is meant for internal and specialized purposes only.\n\
1174In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001175
Antoine Pitrou7b476992013-09-07 23:38:37 +02001176static void
Victor Stinnera42de742018-11-22 10:25:22 +01001177release_sentinel(void *wr_raw)
Antoine Pitrou7b476992013-09-07 23:38:37 +02001178{
Victor Stinnera42de742018-11-22 10:25:22 +01001179 PyObject *wr = _PyObject_CAST(wr_raw);
Antoine Pitrou7b476992013-09-07 23:38:37 +02001180 /* Tricky: this function is called when the current thread state
1181 is being deleted. Therefore, only simple C code can safely
1182 execute here. */
1183 PyObject *obj = PyWeakref_GET_OBJECT(wr);
1184 lockobject *lock;
1185 if (obj != Py_None) {
Antoine Pitrou7b476992013-09-07 23:38:37 +02001186 lock = (lockobject *) obj;
1187 if (lock->locked) {
1188 PyThread_release_lock(lock->lock_lock);
1189 lock->locked = 0;
1190 }
1191 }
1192 /* Deallocating a weakref with a NULL callback only calls
1193 PyObject_GC_Del(), which can't call any Python code. */
1194 Py_DECREF(wr);
1195}
1196
1197static PyObject *
Victor Stinner8203c732020-12-16 12:20:33 +01001198thread__set_sentinel(PyObject *module, PyObject *Py_UNUSED(ignored))
Antoine Pitrou7b476992013-09-07 23:38:37 +02001199{
1200 PyObject *wr;
1201 PyThreadState *tstate = PyThreadState_Get();
1202 lockobject *lock;
1203
1204 if (tstate->on_delete_data != NULL) {
1205 /* We must support the re-creation of the lock from a
1206 fork()ed child. */
1207 assert(tstate->on_delete == &release_sentinel);
1208 wr = (PyObject *) tstate->on_delete_data;
1209 tstate->on_delete = NULL;
1210 tstate->on_delete_data = NULL;
1211 Py_DECREF(wr);
1212 }
1213 lock = newlockobject();
1214 if (lock == NULL)
1215 return NULL;
1216 /* The lock is owned by whoever called _set_sentinel(), but the weakref
1217 hangs to the thread state. */
1218 wr = PyWeakref_NewRef((PyObject *) lock, NULL);
1219 if (wr == NULL) {
1220 Py_DECREF(lock);
1221 return NULL;
1222 }
1223 tstate->on_delete_data = (void *) wr;
1224 tstate->on_delete = &release_sentinel;
1225 return (PyObject *) lock;
1226}
1227
1228PyDoc_STRVAR(_set_sentinel_doc,
1229"_set_sentinel() -> lock\n\
1230\n\
1231Set a sentinel lock that will be released when the current thread\n\
1232state is finalized (after it is untied from the interpreter).\n\
1233\n\
1234This is a private API for the threading module.");
1235
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001236static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001237thread_stack_size(PyObject *self, PyObject *args)
1238{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 size_t old_size;
1240 Py_ssize_t new_size = 0;
1241 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1244 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 if (new_size < 0) {
1247 PyErr_SetString(PyExc_ValueError,
1248 "size must be 0 or a positive value");
1249 return NULL;
1250 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 rc = PyThread_set_stacksize((size_t) new_size);
1255 if (rc == -1) {
1256 PyErr_Format(PyExc_ValueError,
1257 "size not valid: %zd bytes",
1258 new_size);
1259 return NULL;
1260 }
1261 if (rc == -2) {
1262 PyErr_SetString(ThreadError,
1263 "setting stack size not supported");
1264 return NULL;
1265 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001268}
1269
1270PyDoc_STRVAR(stack_size_doc,
1271"stack_size([size]) -> size\n\
1272\n\
1273Return the thread stack size used when creating new threads. The\n\
1274optional size argument specifies the stack size (in bytes) to be used\n\
1275for subsequently created threads, and must be 0 (use platform or\n\
1276configured default) or a positive integer value of at least 32,768 (32k).\n\
1277If changing the thread stack size is unsupported, a ThreadError\n\
1278exception is raised. If the specified size is invalid, a ValueError\n\
1279exception is raised, and the stack size is unmodified. 32k bytes\n\
1280 currently the minimum supported stack size value to guarantee\n\
1281sufficient stack space for the interpreter itself.\n\
1282\n\
1283Note that some platforms may have particular restrictions on values for\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001284the stack size, such as requiring a minimum stack size larger than 32 KiB or\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001285requiring allocation in multiples of the system memory page size\n\
1286- platform documentation should be referred to for more information\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001287(4 KiB pages are common; using multiples of 4096 for the stack size is\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001288the suggested approach in the absence of more specific information).");
1289
Victor Stinnercd590a72019-05-28 00:39:52 +02001290static int
1291thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value,
1292 PyObject *exc_traceback, PyObject *thread)
1293{
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001294 _Py_IDENTIFIER(name);
Victor Stinnercd590a72019-05-28 00:39:52 +02001295 /* print(f"Exception in thread {thread.name}:", file=file) */
1296 if (PyFile_WriteString("Exception in thread ", file) < 0) {
1297 return -1;
1298 }
1299
1300 PyObject *name = NULL;
1301 if (thread != Py_None) {
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001302 if (_PyObject_LookupAttrId(thread, &PyId_name, &name) < 0) {
1303 return -1;
1304 }
Victor Stinnercd590a72019-05-28 00:39:52 +02001305 }
1306 if (name != NULL) {
1307 if (PyFile_WriteObject(name, file, Py_PRINT_RAW) < 0) {
1308 Py_DECREF(name);
1309 return -1;
1310 }
1311 Py_DECREF(name);
1312 }
1313 else {
Victor Stinnercd590a72019-05-28 00:39:52 +02001314 unsigned long ident = PyThread_get_thread_ident();
1315 PyObject *str = PyUnicode_FromFormat("%lu", ident);
1316 if (str != NULL) {
1317 if (PyFile_WriteObject(str, file, Py_PRINT_RAW) < 0) {
1318 Py_DECREF(str);
1319 return -1;
1320 }
1321 Py_DECREF(str);
1322 }
1323 else {
1324 PyErr_Clear();
1325
1326 if (PyFile_WriteString("<failed to get thread name>", file) < 0) {
1327 return -1;
1328 }
1329 }
1330 }
1331
1332 if (PyFile_WriteString(":\n", file) < 0) {
1333 return -1;
1334 }
1335
1336 /* Display the traceback */
1337 _PyErr_Display(file, exc_type, exc_value, exc_traceback);
1338
1339 /* Call file.flush() */
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001340 PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
Victor Stinnercd590a72019-05-28 00:39:52 +02001341 if (!res) {
1342 return -1;
1343 }
1344 Py_DECREF(res);
1345
1346 return 0;
1347}
1348
1349
1350PyDoc_STRVAR(ExceptHookArgs__doc__,
1351"ExceptHookArgs\n\
1352\n\
1353Type used to pass arguments to threading.excepthook.");
1354
1355static PyTypeObject ExceptHookArgsType;
1356
1357static PyStructSequence_Field ExceptHookArgs_fields[] = {
1358 {"exc_type", "Exception type"},
1359 {"exc_value", "Exception value"},
1360 {"exc_traceback", "Exception traceback"},
1361 {"thread", "Thread"},
1362 {0}
1363};
1364
1365static PyStructSequence_Desc ExceptHookArgs_desc = {
Victor Stinner8203c732020-12-16 12:20:33 +01001366 .name = "_thread._ExceptHookArgs",
Victor Stinnercd590a72019-05-28 00:39:52 +02001367 .doc = ExceptHookArgs__doc__,
1368 .fields = ExceptHookArgs_fields,
1369 .n_in_sequence = 4
1370};
1371
1372
1373static PyObject *
1374thread_excepthook(PyObject *self, PyObject *args)
1375{
Andy Lester55728702020-03-06 16:53:17 -06001376 if (!Py_IS_TYPE(args, &ExceptHookArgsType)) {
Victor Stinnercd590a72019-05-28 00:39:52 +02001377 PyErr_SetString(PyExc_TypeError,
1378 "_thread.excepthook argument type "
1379 "must be ExceptHookArgs");
1380 return NULL;
1381 }
1382
1383 /* Borrowed reference */
1384 PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0);
1385 if (exc_type == PyExc_SystemExit) {
1386 /* silently ignore SystemExit */
1387 Py_RETURN_NONE;
1388 }
1389
1390 /* Borrowed references */
1391 PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1);
1392 PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
1393 PyObject *thread = PyStructSequence_GET_ITEM(args, 3);
1394
1395 PyObject *file = _PySys_GetObjectId(&PyId_stderr);
1396 if (file == NULL || file == Py_None) {
1397 if (thread == Py_None) {
1398 /* do nothing if sys.stderr is None and thread is None */
1399 Py_RETURN_NONE;
1400 }
1401
1402 file = PyObject_GetAttrString(thread, "_stderr");
1403 if (file == NULL) {
1404 return NULL;
1405 }
1406 if (file == Py_None) {
1407 Py_DECREF(file);
1408 /* do nothing if sys.stderr is None and sys.stderr was None
1409 when the thread was created */
1410 Py_RETURN_NONE;
1411 }
1412 }
1413 else {
1414 Py_INCREF(file);
1415 }
1416
1417 int res = thread_excepthook_file(file, exc_type, exc_value, exc_tb,
1418 thread);
1419 Py_DECREF(file);
1420 if (res < 0) {
1421 return NULL;
1422 }
1423
1424 Py_RETURN_NONE;
1425}
1426
1427PyDoc_STRVAR(excepthook_doc,
1428"excepthook(exc_type, exc_value, exc_traceback, thread)\n\
1429\n\
1430Handle uncaught Thread.run() exception.");
1431
Barry Warsawd0c10421996-12-17 00:05:22 +00001432static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001434 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001436 METH_VARARGS, start_new_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301437 {"allocate_lock", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301439 {"allocate", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301441 {"exit_thread", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301443 {"exit", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301445 {"interrupt_main", thread_PyThread_interrupt_main,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 METH_NOARGS, interrupt_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301447 {"get_ident", thread_get_ident,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 METH_NOARGS, get_ident_doc},
Jake Teslerb121f632019-05-22 08:43:17 -07001449#ifdef PY_HAVE_THREAD_NATIVE_ID
1450 {"get_native_id", thread_get_native_id,
1451 METH_NOARGS, get_native_id_doc},
1452#endif
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301453 {"_count", thread__count,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 METH_NOARGS, _count_doc},
1455 {"stack_size", (PyCFunction)thread_stack_size,
Victor Stinner754851f2011-04-19 23:58:51 +02001456 METH_VARARGS, stack_size_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301457 {"_set_sentinel", thread__set_sentinel,
Antoine Pitrou7b476992013-09-07 23:38:37 +02001458 METH_NOARGS, _set_sentinel_doc},
Victor Stinnercd590a72019-05-28 00:39:52 +02001459 {"_excepthook", thread_excepthook,
1460 METH_O, excepthook_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001462};
1463
1464
1465/* Initialization function */
1466
Victor Stinner8203c732020-12-16 12:20:33 +01001467static int
1468_thread_module_exec(PyObject *module)
1469{
1470 // Initialize the C thread library
1471 PyThread_init_thread();
1472
1473 // Initialize types
1474 if (PyType_Ready(&localdummytype) < 0)
1475 return -1;
1476 if (PyType_Ready(&localtype) < 0) {
1477 return -1;
1478 }
1479 if (PyType_Ready(&Locktype) < 0) {
1480 return -1;
1481 }
1482 if (PyType_Ready(&RLocktype) < 0) {
1483 return -1;
1484 }
1485 if (ExceptHookArgsType.tp_name == NULL) {
1486 if (PyStructSequence_InitType2(&ExceptHookArgsType,
1487 &ExceptHookArgs_desc) < 0) {
1488 return -1;
1489 }
1490 }
1491
1492 // Add module attributes
1493 PyObject *d = PyModule_GetDict(module);
1494 if (PyDict_SetItemString(d, "error", ThreadError) < 0) {
1495 return -1;
1496 }
1497 if (PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype) < 0) {
1498 return -1;
1499 }
1500 if (PyModule_AddType(module, &RLocktype) < 0) {
1501 return -1;
1502 }
1503 if (PyModule_AddType(module, &localtype) < 0) {
1504 return -1;
1505 }
1506 if (PyModule_AddType(module, &ExceptHookArgsType) < 0) {
1507 return -1;
1508 }
1509
1510 // TIMEOUT_MAX
1511 double timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6;
1512 double time_max = _PyTime_AsSecondsDouble(_PyTime_MAX);
1513 timeout_max = Py_MIN(timeout_max, time_max);
1514 // Round towards minus infinity
1515 timeout_max = floor(timeout_max);
1516
1517 if (PyModule_AddObject(module, "TIMEOUT_MAX",
1518 PyFloat_FromDouble(timeout_max)) < 0) {
1519 return -1;
1520 }
1521
1522 return 0;
1523}
1524
1525
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001526PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001527"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001528The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001529
Victor Stinner8203c732020-12-16 12:20:33 +01001530static struct PyModuleDef _thread_module = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 PyModuleDef_HEAD_INIT,
Victor Stinner8203c732020-12-16 12:20:33 +01001532 .m_name = "_thread",
1533 .m_doc = thread_doc,
1534 .m_size = -1,
1535 .m_methods = thread_methods,
Martin v. Löwis1a214512008-06-11 05:26:20 +00001536};
1537
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001538PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001539PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001540{
Victor Stinner8203c732020-12-16 12:20:33 +01001541 PyObject *module = PyModule_Create(&_thread_module);
1542 if (module == NULL)
1543 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001544
Victor Stinner8203c732020-12-16 12:20:33 +01001545 if (_thread_module_exec(module) < 0) {
1546 Py_DECREF(module);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001547 return NULL;
Victor Stinnercd590a72019-05-28 00:39:52 +02001548 }
Victor Stinner8203c732020-12-16 12:20:33 +01001549 return module;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001550}