blob: bd8a40f0c94b5b5a2a45548465115ea6741ac288 [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 Stinner621cebe2018-11-12 16:53:38 +01007#include "pycore_pystate.h"
Benjamin Petersonbec4d572009-10-10 01:16:07 +00008#include "structmember.h" /* offsetof */
Guido van Rossum49b56061998-10-01 20:42:43 +00009#include "pythread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000010
Victor Stinner066e5b12019-06-14 18:55:22 +020011#include "clinic/_threadmodule.c.h"
12
13/*[clinic input]
14module _thread
15[clinic start generated code]*/
16/*[clinic end generated code: output=da39a3ee5e6b4b0d input=be8dbe5cc4b16df7]*/
17
18
Barry Warsawd0c10421996-12-17 00:05:22 +000019static PyObject *ThreadError;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +000020static PyObject *str_dict;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000021
Victor Stinnerbd303c12013-11-07 23:07:29 +010022_Py_IDENTIFIER(stderr);
Victor Stinnercd590a72019-05-28 00:39:52 +020023_Py_IDENTIFIER(flush);
Victor Stinnerbd303c12013-11-07 23:07:29 +010024
Guido van Rossum1984f1e1992-08-04 12:41:02 +000025/* Lock objects */
26
27typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000028 PyObject_HEAD
29 PyThread_type_lock lock_lock;
30 PyObject *in_weakreflist;
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000031 char locked; /* for sanity checking */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000032} lockobject;
33
Guido van Rossum1984f1e1992-08-04 12:41:02 +000034static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000035lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000036{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037 if (self->in_weakreflist != NULL)
38 PyObject_ClearWeakRefs((PyObject *) self);
39 if (self->lock_lock != NULL) {
40 /* Unlock the lock so it's safe to free it */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000041 if (self->locked)
42 PyThread_release_lock(self->lock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000043 PyThread_free_lock(self->lock_lock);
44 }
45 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000046}
47
Antoine Pitrou810023d2010-12-15 22:59:16 +000048/* Helper to acquire an interruptible lock with a timeout. If the lock acquire
49 * is interrupted, signal handlers are run, and if they raise an exception,
50 * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE
Raymond Hettinger15f44ab2016-08-30 10:47:49 -070051 * are returned, depending on whether the lock can be acquired within the
Antoine Pitrou810023d2010-12-15 22:59:16 +000052 * timeout.
53 */
54static PyLockStatus
Victor Stinnerf5faad22015-03-28 03:52:05 +010055acquire_timed(PyThread_type_lock lock, _PyTime_t timeout)
Antoine Pitrou810023d2010-12-15 22:59:16 +000056{
57 PyLockStatus r;
Victor Stinnerf5faad22015-03-28 03:52:05 +010058 _PyTime_t endtime = 0;
59 _PyTime_t microseconds;
Antoine Pitrou810023d2010-12-15 22:59:16 +000060
Victor Stinnerf5faad22015-03-28 03:52:05 +010061 if (timeout > 0)
62 endtime = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrou810023d2010-12-15 22:59:16 +000063
64 do {
Victor Stinner869e1772015-03-30 03:49:14 +020065 microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING);
Victor Stinnerf5faad22015-03-28 03:52:05 +010066
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000067 /* first a simple non-blocking try without releasing the GIL */
68 r = PyThread_acquire_lock_timed(lock, 0, 0);
69 if (r == PY_LOCK_FAILURE && microseconds != 0) {
70 Py_BEGIN_ALLOW_THREADS
71 r = PyThread_acquire_lock_timed(lock, microseconds, 1);
72 Py_END_ALLOW_THREADS
Victor Stinner357f5152013-11-05 15:10:19 +010073 }
Antoine Pitrou810023d2010-12-15 22:59:16 +000074
75 if (r == PY_LOCK_INTR) {
76 /* Run signal handlers if we were interrupted. Propagate
77 * exceptions from signal handlers, such as KeyboardInterrupt, by
78 * passing up PY_LOCK_INTR. */
79 if (Py_MakePendingCalls() < 0) {
80 return PY_LOCK_INTR;
81 }
82
83 /* If we're using a timeout, recompute the timeout after processing
84 * signals, since those can take time. */
Victor Stinnerf5faad22015-03-28 03:52:05 +010085 if (timeout > 0) {
86 timeout = endtime - _PyTime_GetMonotonicClock();
Antoine Pitrou810023d2010-12-15 22:59:16 +000087
88 /* Check for negative values, since those mean block forever.
89 */
Victor Stinner6aa446c2015-03-30 21:33:51 +020090 if (timeout < 0) {
Antoine Pitrou810023d2010-12-15 22:59:16 +000091 r = PY_LOCK_FAILURE;
92 }
93 }
94 }
95 } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */
96
97 return r;
98}
99
Victor Stinnerf5faad22015-03-28 03:52:05 +0100100static int
101lock_acquire_parse_args(PyObject *args, PyObject *kwds,
102 _PyTime_t *timeout)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000103{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 char *kwlist[] = {"blocking", "timeout", NULL};
105 int blocking = 1;
Victor Stinnerf5faad22015-03-28 03:52:05 +0100106 PyObject *timeout_obj = NULL;
Victor Stinner13019fd2015-04-03 13:10:54 +0200107 const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000108
Victor Stinnerf5faad22015-03-28 03:52:05 +0100109 *timeout = unset_timeout ;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000110
Victor Stinnerf5faad22015-03-28 03:52:05 +0100111 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:acquire", kwlist,
112 &blocking, &timeout_obj))
113 return -1;
114
115 if (timeout_obj
Victor Stinner869e1772015-03-30 03:49:14 +0200116 && _PyTime_FromSecondsObject(timeout,
Pablo Galindo59af94f2017-10-18 08:13:09 +0100117 timeout_obj, _PyTime_ROUND_TIMEOUT) < 0)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100118 return -1;
119
120 if (!blocking && *timeout != unset_timeout ) {
121 PyErr_SetString(PyExc_ValueError,
122 "can't specify a timeout for a non-blocking call");
123 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100125 if (*timeout < 0 && *timeout != unset_timeout) {
126 PyErr_SetString(PyExc_ValueError,
127 "timeout value must be positive");
128 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 }
130 if (!blocking)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100131 *timeout = 0;
132 else if (*timeout != unset_timeout) {
133 _PyTime_t microseconds;
134
Pablo Galindo59af94f2017-10-18 08:13:09 +0100135 microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinnerf5faad22015-03-28 03:52:05 +0100136 if (microseconds >= PY_TIMEOUT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 PyErr_SetString(PyExc_OverflowError,
138 "timeout value is too large");
Victor Stinnerf5faad22015-03-28 03:52:05 +0100139 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000140 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000141 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100142 return 0;
143}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000144
Victor Stinnerf5faad22015-03-28 03:52:05 +0100145static PyObject *
146lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
147{
148 _PyTime_t timeout;
149 PyLockStatus r;
150
151 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
152 return NULL;
153
154 r = acquire_timed(self->lock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000155 if (r == PY_LOCK_INTR) {
156 return NULL;
157 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000159 if (r == PY_LOCK_ACQUIRED)
160 self->locked = 1;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000161 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000162}
163
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000164PyDoc_STRVAR(acquire_doc,
Berker Peksag720e6552016-05-02 12:25:35 +0300165"acquire(blocking=True, timeout=-1) -> bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000166(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000167\n\
168Lock the lock. Without argument, this blocks if the lock is already\n\
169locked (even by the same thread), waiting for another thread to release\n\
R David Murray95b71102013-02-04 10:15:58 -0500170the lock, and return True once the lock is acquired.\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000171With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000172and the return value reflects whether the lock is acquired.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000173The blocking operation is interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000174
Barry Warsawd0c10421996-12-17 00:05:22 +0000175static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530176lock_PyThread_release_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000177{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000178 /* Sanity check: the lock must be locked */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000179 if (!self->locked) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 PyErr_SetString(ThreadError, "release unlocked lock");
181 return NULL;
182 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000184 PyThread_release_lock(self->lock_lock);
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000185 self->locked = 0;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200186 Py_RETURN_NONE;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000187}
188
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000189PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000190"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000191(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000192\n\
193Release the lock, allowing another thread that is blocked waiting for\n\
194the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000195but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000196
Barry Warsawd0c10421996-12-17 00:05:22 +0000197static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530198lock_locked_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000199{
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000200 return PyBool_FromLong((long)self->locked);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000201}
202
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000203PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000204"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000205(locked_lock() is an obsolete synonym)\n\
206\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000207Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000208
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700209static PyObject *
210lock_repr(lockobject *self)
211{
212 return PyUnicode_FromFormat("<%s %s object at %p>",
213 self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
214}
215
Barry Warsawd0c10421996-12-17 00:05:22 +0000216static PyMethodDef lock_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200217 {"acquire_lock", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000218 METH_VARARGS | METH_KEYWORDS, acquire_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200219 {"acquire", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 METH_VARARGS | METH_KEYWORDS, acquire_doc},
221 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
222 METH_NOARGS, release_doc},
223 {"release", (PyCFunction)lock_PyThread_release_lock,
224 METH_NOARGS, release_doc},
225 {"locked_lock", (PyCFunction)lock_locked_lock,
226 METH_NOARGS, locked_doc},
227 {"locked", (PyCFunction)lock_locked_lock,
228 METH_NOARGS, locked_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200229 {"__enter__", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 METH_VARARGS | METH_KEYWORDS, acquire_doc},
231 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
232 METH_VARARGS, release_doc},
233 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000234};
235
Barry Warsawd0c10421996-12-17 00:05:22 +0000236static PyTypeObject Locktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 PyVarObject_HEAD_INIT(&PyType_Type, 0)
238 "_thread.lock", /*tp_name*/
Peter Eisentraut0e0bc4e2018-09-10 18:46:08 +0200239 sizeof(lockobject), /*tp_basicsize*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000240 0, /*tp_itemsize*/
241 /* methods */
242 (destructor)lock_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200243 0, /*tp_vectorcall_offset*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 0, /*tp_getattr*/
245 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200246 0, /*tp_as_async*/
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700247 (reprfunc)lock_repr, /*tp_repr*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 0, /*tp_as_number*/
249 0, /*tp_as_sequence*/
250 0, /*tp_as_mapping*/
251 0, /*tp_hash*/
252 0, /*tp_call*/
253 0, /*tp_str*/
254 0, /*tp_getattro*/
255 0, /*tp_setattro*/
256 0, /*tp_as_buffer*/
257 Py_TPFLAGS_DEFAULT, /*tp_flags*/
258 0, /*tp_doc*/
259 0, /*tp_traverse*/
260 0, /*tp_clear*/
261 0, /*tp_richcompare*/
262 offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
263 0, /*tp_iter*/
264 0, /*tp_iternext*/
265 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000266};
267
Antoine Pitrou434736a2009-11-10 18:46:01 +0000268/* Recursive lock objects */
269
270typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 PyObject_HEAD
272 PyThread_type_lock rlock_lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200273 unsigned long rlock_owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274 unsigned long rlock_count;
275 PyObject *in_weakreflist;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000276} rlockobject;
277
278static void
279rlock_dealloc(rlockobject *self)
280{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 if (self->in_weakreflist != NULL)
282 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner357f5152013-11-05 15:10:19 +0100283 /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed
284 in rlock_new() */
285 if (self->rlock_lock != NULL) {
286 /* Unlock the lock so it's safe to free it */
287 if (self->rlock_count > 0)
288 PyThread_release_lock(self->rlock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289
Victor Stinner357f5152013-11-05 15:10:19 +0100290 PyThread_free_lock(self->rlock_lock);
291 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 Py_TYPE(self)->tp_free(self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000293}
294
295static PyObject *
296rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
297{
Victor Stinnerf5faad22015-03-28 03:52:05 +0100298 _PyTime_t timeout;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200299 unsigned long tid;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000300 PyLockStatus r = PY_LOCK_ACQUIRED;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000301
Victor Stinnerf5faad22015-03-28 03:52:05 +0100302 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 tid = PyThread_get_thread_ident();
306 if (self->rlock_count > 0 && tid == self->rlock_owner) {
307 unsigned long count = self->rlock_count + 1;
308 if (count <= self->rlock_count) {
309 PyErr_SetString(PyExc_OverflowError,
310 "Internal lock count overflowed");
311 return NULL;
312 }
313 self->rlock_count = count;
314 Py_RETURN_TRUE;
315 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100316 r = acquire_timed(self->rlock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000317 if (r == PY_LOCK_ACQUIRED) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 assert(self->rlock_count == 0);
319 self->rlock_owner = tid;
320 self->rlock_count = 1;
321 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000322 else if (r == PY_LOCK_INTR) {
323 return NULL;
324 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325
Antoine Pitrou810023d2010-12-15 22:59:16 +0000326 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000327}
328
329PyDoc_STRVAR(rlock_acquire_doc,
330"acquire(blocking=True) -> bool\n\
331\n\
332Lock the lock. `blocking` indicates whether we should wait\n\
333for the lock to be available or not. If `blocking` is False\n\
334and another thread holds the lock, the method will return False\n\
335immediately. If `blocking` is True and another thread holds\n\
336the lock, the method will wait for the lock to be released,\n\
337take it and then return True.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000338(note: the blocking operation is interruptible.)\n\
Antoine Pitrou434736a2009-11-10 18:46:01 +0000339\n\
340In all other cases, the method will return True immediately.\n\
341Precisely, if the current thread already holds the lock, its\n\
342internal counter is simply incremented. If nobody holds the lock,\n\
343the lock is taken and its internal counter initialized to 1.");
344
345static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530346rlock_release(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000347{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200348 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrou434736a2009-11-10 18:46:01 +0000349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 if (self->rlock_count == 0 || self->rlock_owner != tid) {
351 PyErr_SetString(PyExc_RuntimeError,
352 "cannot release un-acquired lock");
353 return NULL;
354 }
355 if (--self->rlock_count == 0) {
356 self->rlock_owner = 0;
357 PyThread_release_lock(self->rlock_lock);
358 }
359 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000360}
361
362PyDoc_STRVAR(rlock_release_doc,
363"release()\n\
364\n\
365Release the lock, allowing another thread that is blocked waiting for\n\
366the lock to acquire the lock. The lock must be in the locked state,\n\
367and must be locked by the same thread that unlocks it; otherwise a\n\
368`RuntimeError` is raised.\n\
369\n\
370Do note that if the lock was acquire()d several times in a row by the\n\
371current thread, release() needs to be called as many times for the lock\n\
372to be available for other threads.");
373
374static PyObject *
Victor Stinnere8794522014-01-02 12:47:24 +0100375rlock_acquire_restore(rlockobject *self, PyObject *args)
Antoine Pitrou434736a2009-11-10 18:46:01 +0000376{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200377 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 unsigned long count;
379 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000380
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200381 if (!PyArg_ParseTuple(args, "(kk):_acquire_restore", &count, &owner))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
385 Py_BEGIN_ALLOW_THREADS
386 r = PyThread_acquire_lock(self->rlock_lock, 1);
387 Py_END_ALLOW_THREADS
388 }
389 if (!r) {
390 PyErr_SetString(ThreadError, "couldn't acquire lock");
391 return NULL;
392 }
393 assert(self->rlock_count == 0);
394 self->rlock_owner = owner;
395 self->rlock_count = count;
396 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000397}
398
399PyDoc_STRVAR(rlock_acquire_restore_doc,
400"_acquire_restore(state) -> None\n\
401\n\
402For internal use by `threading.Condition`.");
403
404static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530405rlock_release_save(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000406{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200407 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 unsigned long count;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000409
Victor Stinnerc2824d42011-04-24 23:41:33 +0200410 if (self->rlock_count == 0) {
411 PyErr_SetString(PyExc_RuntimeError,
412 "cannot release un-acquired lock");
413 return NULL;
414 }
415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 owner = self->rlock_owner;
417 count = self->rlock_count;
418 self->rlock_count = 0;
419 self->rlock_owner = 0;
420 PyThread_release_lock(self->rlock_lock);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200421 return Py_BuildValue("kk", count, owner);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000422}
423
424PyDoc_STRVAR(rlock_release_save_doc,
425"_release_save() -> tuple\n\
426\n\
427For internal use by `threading.Condition`.");
428
429
430static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530431rlock_is_owned(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000432{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200433 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434
435 if (self->rlock_count > 0 && self->rlock_owner == tid) {
436 Py_RETURN_TRUE;
437 }
438 Py_RETURN_FALSE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000439}
440
441PyDoc_STRVAR(rlock_is_owned_doc,
442"_is_owned() -> bool\n\
443\n\
444For internal use by `threading.Condition`.");
445
446static PyObject *
447rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
448{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 rlockobject *self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 self = (rlockobject *) type->tp_alloc(type, 0);
452 if (self != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 self->in_weakreflist = NULL;
454 self->rlock_owner = 0;
455 self->rlock_count = 0;
Victor Stinner357f5152013-11-05 15:10:19 +0100456
457 self->rlock_lock = PyThread_allocate_lock();
458 if (self->rlock_lock == NULL) {
459 Py_DECREF(self);
460 PyErr_SetString(ThreadError, "can't allocate lock");
461 return NULL;
462 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 return (PyObject *) self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000466}
467
468static PyObject *
469rlock_repr(rlockobject *self)
470{
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700471 return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>",
472 self->rlock_count ? "locked" : "unlocked",
473 Py_TYPE(self)->tp_name, self->rlock_owner,
474 self->rlock_count, self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000475}
476
477
478static PyMethodDef rlock_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200479 {"acquire", (PyCFunction)(void(*)(void))rlock_acquire,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
481 {"release", (PyCFunction)rlock_release,
482 METH_NOARGS, rlock_release_doc},
483 {"_is_owned", (PyCFunction)rlock_is_owned,
484 METH_NOARGS, rlock_is_owned_doc},
485 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
Victor Stinnere8794522014-01-02 12:47:24 +0100486 METH_VARARGS, rlock_acquire_restore_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 {"_release_save", (PyCFunction)rlock_release_save,
488 METH_NOARGS, rlock_release_save_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200489 {"__enter__", (PyCFunction)(void(*)(void))rlock_acquire,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
491 {"__exit__", (PyCFunction)rlock_release,
492 METH_VARARGS, rlock_release_doc},
493 {NULL, NULL} /* sentinel */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000494};
495
496
497static PyTypeObject RLocktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 PyVarObject_HEAD_INIT(&PyType_Type, 0)
499 "_thread.RLock", /*tp_name*/
Peter Eisentraut0e0bc4e2018-09-10 18:46:08 +0200500 sizeof(rlockobject), /*tp_basicsize*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 0, /*tp_itemsize*/
502 /* methods */
503 (destructor)rlock_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200504 0, /*tp_vectorcall_offset*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 0, /*tp_getattr*/
506 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200507 0, /*tp_as_async*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 (reprfunc)rlock_repr, /*tp_repr*/
509 0, /*tp_as_number*/
510 0, /*tp_as_sequence*/
511 0, /*tp_as_mapping*/
512 0, /*tp_hash*/
513 0, /*tp_call*/
514 0, /*tp_str*/
515 0, /*tp_getattro*/
516 0, /*tp_setattro*/
517 0, /*tp_as_buffer*/
518 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
519 0, /*tp_doc*/
520 0, /*tp_traverse*/
521 0, /*tp_clear*/
522 0, /*tp_richcompare*/
523 offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
524 0, /*tp_iter*/
525 0, /*tp_iternext*/
526 rlock_methods, /*tp_methods*/
527 0, /* tp_members */
528 0, /* tp_getset */
529 0, /* tp_base */
530 0, /* tp_dict */
531 0, /* tp_descr_get */
532 0, /* tp_descr_set */
533 0, /* tp_dictoffset */
534 0, /* tp_init */
535 PyType_GenericAlloc, /* tp_alloc */
536 rlock_new /* tp_new */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000537};
538
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000539static lockobject *
540newlockobject(void)
541{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 lockobject *self;
543 self = PyObject_New(lockobject, &Locktype);
544 if (self == NULL)
545 return NULL;
546 self->lock_lock = PyThread_allocate_lock();
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000547 self->locked = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 self->in_weakreflist = NULL;
549 if (self->lock_lock == NULL) {
550 Py_DECREF(self);
551 PyErr_SetString(ThreadError, "can't allocate lock");
552 return NULL;
553 }
554 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000555}
556
Jim Fultond15dc062004-07-14 19:11:50 +0000557/* Thread-local objects */
558
559#include "structmember.h"
560
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000561/* Quick overview:
562
563 We need to be able to reclaim reference cycles as soon as possible
564 (both when a thread is being terminated, or a thread-local object
565 becomes unreachable from user data). Constraints:
566 - it must not be possible for thread-state dicts to be involved in
567 reference cycles (otherwise the cyclic GC will refuse to consider
568 objects referenced from a reachable thread-state dict, even though
569 local_dealloc would clear them)
570 - the death of a thread-state dict must still imply destruction of the
571 corresponding local dicts in all thread-local objects.
572
573 Our implementation uses small "localdummy" objects in order to break
574 the reference chain. These trivial objects are hashable (using the
575 default scheme of identity hashing) and weakrefable.
576 Each thread-state holds a separate localdummy for each local object
577 (as a /strong reference/),
578 and each thread-local object holds a dict mapping /weak references/
579 of localdummies to local dicts.
580
581 Therefore:
582 - only the thread-state dict holds a strong reference to the dummies
583 - only the thread-local object holds a strong reference to the local dicts
584 - only outside objects (application- or library-level) hold strong
585 references to the thread-local objects
586 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
587 dummies attached to that thread are called, and destroy the corresponding
588 local dicts from thread-local objects
589 - as soon as a thread-local object is destroyed, its local dicts are
590 destroyed and its dummies are manually removed from all thread states
591 - the GC can do its work correctly when a thread-local object is dangling,
592 without any interference from the thread-state dicts
593
594 As an additional optimization, each localdummy holds a borrowed reference
595 to the corresponding localdict. This borrowed reference is only used
596 by the thread-local object which has created the localdummy, which should
597 guarantee that the localdict still exists when accessed.
598*/
599
600typedef struct {
601 PyObject_HEAD
602 PyObject *localdict; /* Borrowed reference! */
603 PyObject *weakreflist; /* List of weak references to self */
604} localdummyobject;
605
606static void
607localdummy_dealloc(localdummyobject *self)
608{
609 if (self->weakreflist != NULL)
610 PyObject_ClearWeakRefs((PyObject *) self);
611 Py_TYPE(self)->tp_free((PyObject*)self);
612}
613
614static PyTypeObject localdummytype = {
615 PyVarObject_HEAD_INIT(NULL, 0)
616 /* tp_name */ "_thread._localdummy",
617 /* tp_basicsize */ sizeof(localdummyobject),
618 /* tp_itemsize */ 0,
619 /* tp_dealloc */ (destructor)localdummy_dealloc,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200620 /* tp_vectorcall_offset */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000621 /* tp_getattr */ 0,
622 /* tp_setattr */ 0,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200623 /* tp_as_async */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000624 /* tp_repr */ 0,
625 /* tp_as_number */ 0,
626 /* tp_as_sequence */ 0,
627 /* tp_as_mapping */ 0,
628 /* tp_hash */ 0,
629 /* tp_call */ 0,
630 /* tp_str */ 0,
631 /* tp_getattro */ 0,
632 /* tp_setattro */ 0,
633 /* tp_as_buffer */ 0,
634 /* tp_flags */ Py_TPFLAGS_DEFAULT,
635 /* tp_doc */ "Thread-local dummy",
636 /* tp_traverse */ 0,
637 /* tp_clear */ 0,
638 /* tp_richcompare */ 0,
639 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
640};
641
642
Jim Fultond15dc062004-07-14 19:11:50 +0000643typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 PyObject_HEAD
645 PyObject *key;
646 PyObject *args;
647 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000648 PyObject *weakreflist; /* List of weak references to self */
649 /* A {localdummy weakref -> localdict} dict */
650 PyObject *dummies;
651 /* The callback for weakrefs to localdummies */
652 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000653} localobject;
654
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000655/* Forward declaration */
656static PyObject *_ldict(localobject *self);
657static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
658
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000659/* Create and register the dummy for the current thread.
660 Returns a borrowed reference of the corresponding local dict */
661static PyObject *
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000662_local_create_dummy(localobject *self)
663{
664 PyObject *tdict, *ldict = NULL, *wr = NULL;
665 localdummyobject *dummy = NULL;
666 int r;
667
668 tdict = PyThreadState_GetDict();
669 if (tdict == NULL) {
670 PyErr_SetString(PyExc_SystemError,
671 "Couldn't get thread-state dictionary");
672 goto err;
673 }
674
675 ldict = PyDict_New();
676 if (ldict == NULL)
677 goto err;
678 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
679 if (dummy == NULL)
680 goto err;
681 dummy->localdict = ldict;
682 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
683 if (wr == NULL)
684 goto err;
685
686 /* As a side-effect, this will cache the weakref's hash before the
687 dummy gets deleted */
688 r = PyDict_SetItem(self->dummies, wr, ldict);
689 if (r < 0)
690 goto err;
691 Py_CLEAR(wr);
692 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
693 if (r < 0)
694 goto err;
695 Py_CLEAR(dummy);
696
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000697 Py_DECREF(ldict);
698 return ldict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000699
700err:
701 Py_XDECREF(ldict);
702 Py_XDECREF(wr);
703 Py_XDECREF(dummy);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000704 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000705}
706
Jim Fultond15dc062004-07-14 19:11:50 +0000707static PyObject *
708local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
709{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000710 localobject *self;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000711 PyObject *wr;
712 static PyMethodDef wr_callback_def = {
713 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
714 };
Jim Fultond15dc062004-07-14 19:11:50 +0000715
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300716 if (type->tp_init == PyBaseObject_Type.tp_init) {
717 int rc = 0;
718 if (args != NULL)
719 rc = PyObject_IsTrue(args);
720 if (rc == 0 && kw != NULL)
721 rc = PyObject_IsTrue(kw);
722 if (rc != 0) {
723 if (rc > 0)
724 PyErr_SetString(PyExc_TypeError,
725 "Initialization arguments are not supported");
726 return NULL;
727 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 }
Jim Fultond15dc062004-07-14 19:11:50 +0000729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 self = (localobject *)type->tp_alloc(type, 0);
731 if (self == NULL)
732 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000733
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 Py_XINCREF(args);
735 self->args = args;
736 Py_XINCREF(kw);
737 self->kw = kw;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 self->key = PyUnicode_FromFormat("thread.local.%p", self);
739 if (self->key == NULL)
740 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000741
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000742 self->dummies = PyDict_New();
743 if (self->dummies == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000744 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000745
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000746 /* We use a weak reference to self in the callback closure
747 in order to avoid spurious reference cycles */
748 wr = PyWeakref_NewRef((PyObject *) self, NULL);
749 if (wr == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 goto err;
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200751 self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000752 Py_DECREF(wr);
753 if (self->wr_callback == NULL)
754 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000755
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000756 if (_local_create_dummy(self) == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000757 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000758
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000760
761 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 Py_DECREF(self);
763 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000764}
765
766static int
767local_traverse(localobject *self, visitproc visit, void *arg)
768{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 Py_VISIT(self->args);
770 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000771 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000772 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000773}
774
775static int
776local_clear(localobject *self)
777{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000778 PyThreadState *tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779 Py_CLEAR(self->args);
780 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000781 Py_CLEAR(self->dummies);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000782 Py_CLEAR(self->wr_callback);
783 /* Remove all strong references to dummies from the thread states */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000784 if (self->key
785 && (tstate = PyThreadState_Get())
786 && tstate->interp) {
787 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
788 tstate;
789 tstate = PyThreadState_Next(tstate))
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200790 if (tstate->dict && PyDict_GetItem(tstate->dict, self->key)) {
791 if (PyDict_DelItem(tstate->dict, self->key)) {
792 PyErr_Clear();
793 }
794 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000795 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000796 return 0;
797}
Jim Fultond15dc062004-07-14 19:11:50 +0000798
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000799static void
800local_dealloc(localobject *self)
801{
802 /* Weakrefs must be invalidated right now, otherwise they can be used
803 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
804 if (self->weakreflist != NULL)
805 PyObject_ClearWeakRefs((PyObject *) self);
806
807 PyObject_GC_UnTrack(self);
808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000810 Py_XDECREF(self->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000811 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000812}
813
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000814/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000815static PyObject *
816_ldict(localobject *self)
817{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000818 PyObject *tdict, *ldict, *dummy;
Jim Fultond15dc062004-07-14 19:11:50 +0000819
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000820 tdict = PyThreadState_GetDict();
821 if (tdict == NULL) {
822 PyErr_SetString(PyExc_SystemError,
823 "Couldn't get thread-state dictionary");
824 return NULL;
825 }
Jim Fultond15dc062004-07-14 19:11:50 +0000826
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200827 dummy = PyDict_GetItemWithError(tdict, self->key);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000828 if (dummy == NULL) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200829 if (PyErr_Occurred()) {
830 return NULL;
831 }
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000832 ldict = _local_create_dummy(self);
833 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000834 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000836 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
837 Py_TYPE(self)->tp_init((PyObject*)self,
838 self->args, self->kw) < 0) {
839 /* we need to get rid of ldict from thread so
840 we create a new one the next time we do an attr
Ezio Melotti42da6632011-03-15 05:18:48 +0200841 access */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 PyDict_DelItem(tdict, self->key);
843 return NULL;
844 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000845 }
846 else {
Andy Lesterdffe4c02020-03-04 07:15:20 -0600847 assert(Py_IS_TYPE(dummy, &localdummytype));
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000848 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000849 }
Jim Fultond15dc062004-07-14 19:11:50 +0000850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000851 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000852}
853
Jim Fultond15dc062004-07-14 19:11:50 +0000854static int
855local_setattro(localobject *self, PyObject *name, PyObject *v)
856{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 PyObject *ldict;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000858 int r;
Jim Fultond15dc062004-07-14 19:11:50 +0000859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 ldict = _ldict(self);
861 if (ldict == NULL)
862 return -1;
863
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000864 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
865 if (r == 1) {
866 PyErr_Format(PyExc_AttributeError,
867 "'%.50s' object attribute '%U' is read-only",
868 Py_TYPE(self)->tp_name, name);
869 return -1;
870 }
871 if (r == -1)
872 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000873
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000874 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000875}
876
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000877static PyObject *local_getattro(localobject *, PyObject *);
878
Jim Fultond15dc062004-07-14 19:11:50 +0000879static PyTypeObject localtype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 PyVarObject_HEAD_INIT(NULL, 0)
881 /* tp_name */ "_thread._local",
882 /* tp_basicsize */ sizeof(localobject),
883 /* tp_itemsize */ 0,
884 /* tp_dealloc */ (destructor)local_dealloc,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200885 /* tp_vectorcall_offset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 /* tp_getattr */ 0,
887 /* tp_setattr */ 0,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200888 /* tp_as_async */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 /* tp_repr */ 0,
890 /* tp_as_number */ 0,
891 /* tp_as_sequence */ 0,
892 /* tp_as_mapping */ 0,
893 /* tp_hash */ 0,
894 /* tp_call */ 0,
895 /* tp_str */ 0,
896 /* tp_getattro */ (getattrofunc)local_getattro,
897 /* tp_setattro */ (setattrofunc)local_setattro,
898 /* tp_as_buffer */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000899 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
900 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 /* tp_doc */ "Thread-local data",
902 /* tp_traverse */ (traverseproc)local_traverse,
903 /* tp_clear */ (inquiry)local_clear,
904 /* tp_richcompare */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000905 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 /* tp_iter */ 0,
907 /* tp_iternext */ 0,
908 /* tp_methods */ 0,
909 /* tp_members */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000910 /* tp_getset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 /* tp_base */ 0,
912 /* tp_dict */ 0, /* internal use */
913 /* tp_descr_get */ 0,
914 /* tp_descr_set */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000915 /* tp_dictoffset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 /* tp_init */ 0,
917 /* tp_alloc */ 0,
918 /* tp_new */ local_new,
919 /* tp_free */ 0, /* Low-level free-mem routine */
920 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000921};
922
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000923static PyObject *
924local_getattro(localobject *self, PyObject *name)
925{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 PyObject *ldict, *value;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000927 int r;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000928
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000929 ldict = _ldict(self);
930 if (ldict == NULL)
931 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000932
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000933 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
934 if (r == 1) {
935 Py_INCREF(ldict);
936 return ldict;
937 }
938 if (r == -1)
939 return NULL;
940
Andy Lester55728702020-03-06 16:53:17 -0600941 if (!Py_IS_TYPE(self, &localtype))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000942 /* use generic lookup for subtypes */
INADA Naoki378edee2018-01-16 20:52:41 +0900943 return _PyObject_GenericGetAttrWithDict(
944 (PyObject *)self, name, ldict, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 /* Optimization: just look in dict ourselves */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200947 value = PyDict_GetItemWithError(ldict, name);
948 if (value != NULL) {
949 Py_INCREF(value);
950 return value;
951 }
952 else if (PyErr_Occurred()) {
953 return NULL;
954 }
955 /* Fall back on generic to get __class__ and __dict__ */
956 return _PyObject_GenericGetAttrWithDict(
957 (PyObject *)self, name, ldict, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000958}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000959
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000960/* Called when a dummy is destroyed. */
961static PyObject *
962_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
963{
964 PyObject *obj;
965 localobject *self;
966 assert(PyWeakref_CheckRef(localweakref));
967 obj = PyWeakref_GET_OBJECT(localweakref);
968 if (obj == Py_None)
969 Py_RETURN_NONE;
970 Py_INCREF(obj);
971 assert(PyObject_TypeCheck(obj, &localtype));
972 /* If the thread-local object is still alive and not being cleared,
973 remove the corresponding local dict */
974 self = (localobject *) obj;
975 if (self->dummies != NULL) {
976 PyObject *ldict;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200977 ldict = PyDict_GetItemWithError(self->dummies, dummyweakref);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000978 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000979 PyDict_DelItem(self->dummies, dummyweakref);
980 }
981 if (PyErr_Occurred())
982 PyErr_WriteUnraisable(obj);
983 }
984 Py_DECREF(obj);
985 Py_RETURN_NONE;
986}
987
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000988/* Module functions */
989
Guido van Rossuma027efa1997-05-05 20:56:21 +0000990struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 PyInterpreterState *interp;
992 PyObject *func;
993 PyObject *args;
994 PyObject *keyw;
995 PyThreadState *tstate;
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -0300996 _PyRuntimeState *runtime;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000997};
998
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000999static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001000t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001001{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 struct bootstate *boot = (struct bootstate *) boot_raw;
1003 PyThreadState *tstate;
1004 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 tstate = boot->tstate;
1007 tstate->thread_id = PyThread_get_thread_ident();
Victor Stinner01b1cc12019-11-20 02:27:56 +01001008 _PyThreadState_Init(tstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 PyEval_AcquireThread(tstate);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001010 tstate->interp->num_threads++;
INADA Naoki72dccde2017-02-16 09:26:01 +09001011 res = PyObject_Call(boot->func, boot->args, boot->keyw);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 if (res == NULL) {
1013 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Victor Stinner8b095002019-05-29 02:57:56 +02001014 /* SystemExit is ignored silently */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 PyErr_Clear();
1016 else {
Victor Stinner8b095002019-05-29 02:57:56 +02001017 _PyErr_WriteUnraisableMsg("in thread started by", boot->func);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018 }
1019 }
Victor Stinner8b095002019-05-29 02:57:56 +02001020 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 Py_DECREF(res);
Victor Stinner8b095002019-05-29 02:57:56 +02001022 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 Py_DECREF(boot->func);
1024 Py_DECREF(boot->args);
1025 Py_XDECREF(boot->keyw);
1026 PyMem_DEL(boot_raw);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001027 tstate->interp->num_threads--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 PyThreadState_Clear(tstate);
Victor Stinner23ef89d2020-03-18 02:26:04 +01001029 _PyThreadState_DeleteCurrent(tstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001031}
1032
Barry Warsawd0c10421996-12-17 00:05:22 +00001033static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001034thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001035{
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001036 _PyRuntimeState *runtime = &_PyRuntime;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001037 PyObject *func, *args, *keyw = NULL;
1038 struct bootstate *boot;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001039 unsigned long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
1042 &func, &args, &keyw))
1043 return NULL;
1044 if (!PyCallable_Check(func)) {
1045 PyErr_SetString(PyExc_TypeError,
1046 "first arg must be callable");
1047 return NULL;
1048 }
1049 if (!PyTuple_Check(args)) {
1050 PyErr_SetString(PyExc_TypeError,
1051 "2nd arg must be a tuple");
1052 return NULL;
1053 }
1054 if (keyw != NULL && !PyDict_Check(keyw)) {
1055 PyErr_SetString(PyExc_TypeError,
1056 "optional 3rd arg must be a dictionary");
1057 return NULL;
1058 }
1059 boot = PyMem_NEW(struct bootstate, 1);
1060 if (boot == NULL)
1061 return PyErr_NoMemory();
Victor Stinnerff4584c2020-03-13 18:03:56 +01001062 boot->interp = _PyInterpreterState_GET_UNSAFE();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 boot->func = func;
1064 boot->args = args;
1065 boot->keyw = keyw;
1066 boot->tstate = _PyThreadState_Prealloc(boot->interp);
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001067 boot->runtime = runtime;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 if (boot->tstate == NULL) {
1069 PyMem_DEL(boot);
1070 return PyErr_NoMemory();
1071 }
1072 Py_INCREF(func);
1073 Py_INCREF(args);
1074 Py_XINCREF(keyw);
Victor Stinner3225b9f2020-03-09 20:56:57 +01001075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001076 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001077 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001078 PyErr_SetString(ThreadError, "can't start new thread");
1079 Py_DECREF(func);
1080 Py_DECREF(args);
1081 Py_XDECREF(keyw);
1082 PyThreadState_Clear(boot->tstate);
1083 PyMem_DEL(boot);
1084 return NULL;
1085 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001086 return PyLong_FromUnsignedLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001087}
1088
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001089PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001090"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001091(start_new() is an obsolete synonym)\n\
1092\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001093Start a new thread and return its identifier. The thread will call the\n\
1094function with positional arguments from the tuple args and keyword arguments\n\
1095taken from the optional dictionary kwargs. The thread exits when the\n\
1096function returns; the return value is ignored. The thread will also exit\n\
1097when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001098printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001099
Barry Warsawd0c10421996-12-17 00:05:22 +00001100static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301101thread_PyThread_exit_thread(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001102{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001103 PyErr_SetNone(PyExc_SystemExit);
1104 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001105}
1106
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001107PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001108"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001109(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001110\n\
1111This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001112thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001113
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001114static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301115thread_PyThread_interrupt_main(PyObject * self, PyObject *Py_UNUSED(ignored))
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001116{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 PyErr_SetInterrupt();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001118 Py_RETURN_NONE;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001119}
1120
1121PyDoc_STRVAR(interrupt_doc,
1122"interrupt_main()\n\
1123\n\
1124Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001125A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001126);
1127
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001128static lockobject *newlockobject(void);
1129
Barry Warsawd0c10421996-12-17 00:05:22 +00001130static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301131thread_PyThread_allocate_lock(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001133 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001134}
1135
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001136PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001137"allocate_lock() -> lock object\n\
1138(allocate() is an obsolete synonym)\n\
1139\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001140Create a new lock object. See help(type(threading.Lock())) for\n\
1141information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001142
Barry Warsawd0c10421996-12-17 00:05:22 +00001143static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301144thread_get_ident(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001145{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001146 unsigned long ident = PyThread_get_thread_ident();
1147 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 PyErr_SetString(ThreadError, "no current thread ident");
1149 return NULL;
1150 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001151 return PyLong_FromUnsignedLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001152}
1153
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001154PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001155"get_ident() -> integer\n\
1156\n\
1157Return a non-zero integer that uniquely identifies the current thread\n\
1158amongst other threads that exist simultaneously.\n\
1159This may be used to identify per-thread resources.\n\
1160Even though on some platforms threads identities may appear to be\n\
1161allocated consecutive numbers starting at 1, this behavior should not\n\
1162be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001163A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001164
Jake Teslerb121f632019-05-22 08:43:17 -07001165#ifdef PY_HAVE_THREAD_NATIVE_ID
1166static PyObject *
1167thread_get_native_id(PyObject *self, PyObject *Py_UNUSED(ignored))
1168{
1169 unsigned long native_id = PyThread_get_thread_native_id();
1170 return PyLong_FromUnsignedLong(native_id);
1171}
1172
1173PyDoc_STRVAR(get_native_id_doc,
1174"get_native_id() -> integer\n\
1175\n\
1176Return a non-negative integer identifying the thread as reported\n\
1177by the OS (kernel). This may be used to uniquely identify a\n\
1178particular thread within a system.");
1179#endif
1180
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001181static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301182thread__count(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001183{
Victor Stinnerff4584c2020-03-13 18:03:56 +01001184 PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
Victor Stinnercaba55b2018-08-03 15:33:52 +02001185 return PyLong_FromLong(interp->num_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001186}
1187
1188PyDoc_STRVAR(_count_doc,
1189"_count() -> integer\n\
1190\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001191\
oldkaa0735f2018-02-02 16:52:55 +08001192Return the number of currently running Python threads, excluding\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001193the main thread. The returned number comprises all threads created\n\
1194through `start_new_thread()` as well as `threading.Thread`, and not\n\
1195yet finished.\n\
1196\n\
1197This function is meant for internal and specialized purposes only.\n\
1198In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001199
Antoine Pitrou7b476992013-09-07 23:38:37 +02001200static void
Victor Stinnera42de742018-11-22 10:25:22 +01001201release_sentinel(void *wr_raw)
Antoine Pitrou7b476992013-09-07 23:38:37 +02001202{
Victor Stinnera42de742018-11-22 10:25:22 +01001203 PyObject *wr = _PyObject_CAST(wr_raw);
Antoine Pitrou7b476992013-09-07 23:38:37 +02001204 /* Tricky: this function is called when the current thread state
1205 is being deleted. Therefore, only simple C code can safely
1206 execute here. */
1207 PyObject *obj = PyWeakref_GET_OBJECT(wr);
1208 lockobject *lock;
1209 if (obj != Py_None) {
Andy Lesterdffe4c02020-03-04 07:15:20 -06001210 assert(Py_IS_TYPE(obj, &Locktype));
Antoine Pitrou7b476992013-09-07 23:38:37 +02001211 lock = (lockobject *) obj;
1212 if (lock->locked) {
1213 PyThread_release_lock(lock->lock_lock);
1214 lock->locked = 0;
1215 }
1216 }
1217 /* Deallocating a weakref with a NULL callback only calls
1218 PyObject_GC_Del(), which can't call any Python code. */
1219 Py_DECREF(wr);
1220}
1221
1222static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301223thread__set_sentinel(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou7b476992013-09-07 23:38:37 +02001224{
1225 PyObject *wr;
1226 PyThreadState *tstate = PyThreadState_Get();
1227 lockobject *lock;
1228
1229 if (tstate->on_delete_data != NULL) {
1230 /* We must support the re-creation of the lock from a
1231 fork()ed child. */
1232 assert(tstate->on_delete == &release_sentinel);
1233 wr = (PyObject *) tstate->on_delete_data;
1234 tstate->on_delete = NULL;
1235 tstate->on_delete_data = NULL;
1236 Py_DECREF(wr);
1237 }
1238 lock = newlockobject();
1239 if (lock == NULL)
1240 return NULL;
1241 /* The lock is owned by whoever called _set_sentinel(), but the weakref
1242 hangs to the thread state. */
1243 wr = PyWeakref_NewRef((PyObject *) lock, NULL);
1244 if (wr == NULL) {
1245 Py_DECREF(lock);
1246 return NULL;
1247 }
1248 tstate->on_delete_data = (void *) wr;
1249 tstate->on_delete = &release_sentinel;
1250 return (PyObject *) lock;
1251}
1252
1253PyDoc_STRVAR(_set_sentinel_doc,
1254"_set_sentinel() -> lock\n\
1255\n\
1256Set a sentinel lock that will be released when the current thread\n\
1257state is finalized (after it is untied from the interpreter).\n\
1258\n\
1259This is a private API for the threading module.");
1260
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001261static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001262thread_stack_size(PyObject *self, PyObject *args)
1263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 size_t old_size;
1265 Py_ssize_t new_size = 0;
1266 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1269 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 if (new_size < 0) {
1272 PyErr_SetString(PyExc_ValueError,
1273 "size must be 0 or a positive value");
1274 return NULL;
1275 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 rc = PyThread_set_stacksize((size_t) new_size);
1280 if (rc == -1) {
1281 PyErr_Format(PyExc_ValueError,
1282 "size not valid: %zd bytes",
1283 new_size);
1284 return NULL;
1285 }
1286 if (rc == -2) {
1287 PyErr_SetString(ThreadError,
1288 "setting stack size not supported");
1289 return NULL;
1290 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001293}
1294
1295PyDoc_STRVAR(stack_size_doc,
1296"stack_size([size]) -> size\n\
1297\n\
1298Return the thread stack size used when creating new threads. The\n\
1299optional size argument specifies the stack size (in bytes) to be used\n\
1300for subsequently created threads, and must be 0 (use platform or\n\
1301configured default) or a positive integer value of at least 32,768 (32k).\n\
1302If changing the thread stack size is unsupported, a ThreadError\n\
1303exception is raised. If the specified size is invalid, a ValueError\n\
1304exception is raised, and the stack size is unmodified. 32k bytes\n\
1305 currently the minimum supported stack size value to guarantee\n\
1306sufficient stack space for the interpreter itself.\n\
1307\n\
1308Note that some platforms may have particular restrictions on values for\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001309the stack size, such as requiring a minimum stack size larger than 32 KiB or\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001310requiring allocation in multiples of the system memory page size\n\
1311- platform documentation should be referred to for more information\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001312(4 KiB pages are common; using multiples of 4096 for the stack size is\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001313the suggested approach in the absence of more specific information).");
1314
Victor Stinnercd590a72019-05-28 00:39:52 +02001315static int
1316thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value,
1317 PyObject *exc_traceback, PyObject *thread)
1318{
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001319 _Py_IDENTIFIER(name);
Victor Stinnercd590a72019-05-28 00:39:52 +02001320 /* print(f"Exception in thread {thread.name}:", file=file) */
1321 if (PyFile_WriteString("Exception in thread ", file) < 0) {
1322 return -1;
1323 }
1324
1325 PyObject *name = NULL;
1326 if (thread != Py_None) {
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001327 if (_PyObject_LookupAttrId(thread, &PyId_name, &name) < 0) {
1328 return -1;
1329 }
Victor Stinnercd590a72019-05-28 00:39:52 +02001330 }
1331 if (name != NULL) {
1332 if (PyFile_WriteObject(name, file, Py_PRINT_RAW) < 0) {
1333 Py_DECREF(name);
1334 return -1;
1335 }
1336 Py_DECREF(name);
1337 }
1338 else {
Victor Stinnercd590a72019-05-28 00:39:52 +02001339 unsigned long ident = PyThread_get_thread_ident();
1340 PyObject *str = PyUnicode_FromFormat("%lu", ident);
1341 if (str != NULL) {
1342 if (PyFile_WriteObject(str, file, Py_PRINT_RAW) < 0) {
1343 Py_DECREF(str);
1344 return -1;
1345 }
1346 Py_DECREF(str);
1347 }
1348 else {
1349 PyErr_Clear();
1350
1351 if (PyFile_WriteString("<failed to get thread name>", file) < 0) {
1352 return -1;
1353 }
1354 }
1355 }
1356
1357 if (PyFile_WriteString(":\n", file) < 0) {
1358 return -1;
1359 }
1360
1361 /* Display the traceback */
1362 _PyErr_Display(file, exc_type, exc_value, exc_traceback);
1363
1364 /* Call file.flush() */
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001365 PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
Victor Stinnercd590a72019-05-28 00:39:52 +02001366 if (!res) {
1367 return -1;
1368 }
1369 Py_DECREF(res);
1370
1371 return 0;
1372}
1373
1374
1375PyDoc_STRVAR(ExceptHookArgs__doc__,
1376"ExceptHookArgs\n\
1377\n\
1378Type used to pass arguments to threading.excepthook.");
1379
1380static PyTypeObject ExceptHookArgsType;
1381
1382static PyStructSequence_Field ExceptHookArgs_fields[] = {
1383 {"exc_type", "Exception type"},
1384 {"exc_value", "Exception value"},
1385 {"exc_traceback", "Exception traceback"},
1386 {"thread", "Thread"},
1387 {0}
1388};
1389
1390static PyStructSequence_Desc ExceptHookArgs_desc = {
1391 .name = "_thread.ExceptHookArgs",
1392 .doc = ExceptHookArgs__doc__,
1393 .fields = ExceptHookArgs_fields,
1394 .n_in_sequence = 4
1395};
1396
1397
1398static PyObject *
1399thread_excepthook(PyObject *self, PyObject *args)
1400{
Andy Lester55728702020-03-06 16:53:17 -06001401 if (!Py_IS_TYPE(args, &ExceptHookArgsType)) {
Victor Stinnercd590a72019-05-28 00:39:52 +02001402 PyErr_SetString(PyExc_TypeError,
1403 "_thread.excepthook argument type "
1404 "must be ExceptHookArgs");
1405 return NULL;
1406 }
1407
1408 /* Borrowed reference */
1409 PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0);
1410 if (exc_type == PyExc_SystemExit) {
1411 /* silently ignore SystemExit */
1412 Py_RETURN_NONE;
1413 }
1414
1415 /* Borrowed references */
1416 PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1);
1417 PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
1418 PyObject *thread = PyStructSequence_GET_ITEM(args, 3);
1419
1420 PyObject *file = _PySys_GetObjectId(&PyId_stderr);
1421 if (file == NULL || file == Py_None) {
1422 if (thread == Py_None) {
1423 /* do nothing if sys.stderr is None and thread is None */
1424 Py_RETURN_NONE;
1425 }
1426
1427 file = PyObject_GetAttrString(thread, "_stderr");
1428 if (file == NULL) {
1429 return NULL;
1430 }
1431 if (file == Py_None) {
1432 Py_DECREF(file);
1433 /* do nothing if sys.stderr is None and sys.stderr was None
1434 when the thread was created */
1435 Py_RETURN_NONE;
1436 }
1437 }
1438 else {
1439 Py_INCREF(file);
1440 }
1441
1442 int res = thread_excepthook_file(file, exc_type, exc_value, exc_tb,
1443 thread);
1444 Py_DECREF(file);
1445 if (res < 0) {
1446 return NULL;
1447 }
1448
1449 Py_RETURN_NONE;
1450}
1451
1452PyDoc_STRVAR(excepthook_doc,
1453"excepthook(exc_type, exc_value, exc_traceback, thread)\n\
1454\n\
1455Handle uncaught Thread.run() exception.");
1456
Victor Stinner066e5b12019-06-14 18:55:22 +02001457/*[clinic input]
1458_thread._is_main_interpreter
1459
1460Return True if the current interpreter is the main Python interpreter.
1461[clinic start generated code]*/
1462
1463static PyObject *
1464_thread__is_main_interpreter_impl(PyObject *module)
1465/*[clinic end generated code: output=7dd82e1728339adc input=cc1eb00fd4598915]*/
1466{
Victor Stinnerfff7bbf2019-11-20 17:34:39 +01001467 PyThreadState *tstate = _PyThreadState_GET();
1468 int is_main = _Py_IsMainInterpreter(tstate);
1469 return PyBool_FromLong(is_main);
Victor Stinner066e5b12019-06-14 18:55:22 +02001470}
1471
Barry Warsawd0c10421996-12-17 00:05:22 +00001472static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001473 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001474 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001476 METH_VARARGS, start_new_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301477 {"allocate_lock", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301479 {"allocate", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301481 {"exit_thread", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301483 {"exit", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301485 {"interrupt_main", thread_PyThread_interrupt_main,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 METH_NOARGS, interrupt_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301487 {"get_ident", thread_get_ident,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 METH_NOARGS, get_ident_doc},
Jake Teslerb121f632019-05-22 08:43:17 -07001489#ifdef PY_HAVE_THREAD_NATIVE_ID
1490 {"get_native_id", thread_get_native_id,
1491 METH_NOARGS, get_native_id_doc},
1492#endif
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301493 {"_count", thread__count,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 METH_NOARGS, _count_doc},
1495 {"stack_size", (PyCFunction)thread_stack_size,
Victor Stinner754851f2011-04-19 23:58:51 +02001496 METH_VARARGS, stack_size_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301497 {"_set_sentinel", thread__set_sentinel,
Antoine Pitrou7b476992013-09-07 23:38:37 +02001498 METH_NOARGS, _set_sentinel_doc},
Victor Stinnercd590a72019-05-28 00:39:52 +02001499 {"_excepthook", thread_excepthook,
1500 METH_O, excepthook_doc},
Victor Stinner066e5b12019-06-14 18:55:22 +02001501 _THREAD__IS_MAIN_INTERPRETER_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001503};
1504
1505
1506/* Initialization function */
1507
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001508PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001509"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001510The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001511
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001512PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001513"A lock object is a synchronization primitive. To create a lock,\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001514call threading.Lock(). Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001515\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001516acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1517release() -- unlock of the lock\n\
1518locked() -- test whether the lock is currently locked\n\
1519\n\
1520A lock is not owned by the thread that locked it; another thread may\n\
1521unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001522will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001523
Martin v. Löwis1a214512008-06-11 05:26:20 +00001524static struct PyModuleDef threadmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 PyModuleDef_HEAD_INIT,
1526 "_thread",
1527 thread_doc,
1528 -1,
1529 thread_methods,
1530 NULL,
1531 NULL,
1532 NULL,
1533 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001534};
1535
1536
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001537PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001538PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001539{
Victor Stinnerf5faad22015-03-28 03:52:05 +01001540 PyObject *m, *d, *v;
1541 double time_max;
1542 double timeout_max;
Victor Stinnerff4584c2020-03-13 18:03:56 +01001543 PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 /* Initialize types: */
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001546 if (PyType_Ready(&localdummytype) < 0)
1547 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 if (PyType_Ready(&localtype) < 0)
1549 return NULL;
1550 if (PyType_Ready(&Locktype) < 0)
1551 return NULL;
1552 if (PyType_Ready(&RLocktype) < 0)
1553 return NULL;
Victor Stinnercd590a72019-05-28 00:39:52 +02001554 if (ExceptHookArgsType.tp_name == NULL) {
1555 if (PyStructSequence_InitType2(&ExceptHookArgsType,
1556 &ExceptHookArgs_desc) < 0) {
1557 return NULL;
1558 }
1559 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 /* Create the module and add the functions */
1562 m = PyModule_Create(&threadmodule);
1563 if (m == NULL)
1564 return NULL;
Antoine Pitrou7c3e5772010-04-14 15:44:10 +00001565
Victor Stinnerc319eee2017-11-30 23:03:47 +01001566 timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6;
Victor Stinner850a18e2017-10-24 16:53:32 -07001567 time_max = _PyTime_AsSecondsDouble(_PyTime_MAX);
Victor Stinnerf5faad22015-03-28 03:52:05 +01001568 timeout_max = Py_MIN(timeout_max, time_max);
Victor Stinner850a18e2017-10-24 16:53:32 -07001569 /* Round towards minus infinity */
1570 timeout_max = floor(timeout_max);
Victor Stinnerf5faad22015-03-28 03:52:05 +01001571
1572 v = PyFloat_FromDouble(timeout_max);
1573 if (!v)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 return NULL;
Victor Stinnerf5faad22015-03-28 03:52:05 +01001575 if (PyModule_AddObject(m, "TIMEOUT_MAX", v) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001577
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 /* Add a symbolic constant */
1579 d = PyModule_GetDict(m);
Antoine Pitroufcf81fd2011-02-28 22:03:34 +00001580 ThreadError = PyExc_RuntimeError;
1581 Py_INCREF(ThreadError);
Victor Stinner754851f2011-04-19 23:58:51 +02001582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 PyDict_SetItemString(d, "error", ThreadError);
1584 Locktype.tp_doc = lock_doc;
1585 Py_INCREF(&Locktype);
1586 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Antoine Pitrou434736a2009-11-10 18:46:01 +00001587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 Py_INCREF(&RLocktype);
1589 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1590 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001591
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 Py_INCREF(&localtype);
1593 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1594 return NULL;
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001595
Victor Stinnercd590a72019-05-28 00:39:52 +02001596 Py_INCREF(&ExceptHookArgsType);
1597 if (PyModule_AddObject(m, "_ExceptHookArgs",
1598 (PyObject *)&ExceptHookArgsType) < 0)
1599 return NULL;
1600
Victor Stinnercaba55b2018-08-03 15:33:52 +02001601 interp->num_threads = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +00001603 str_dict = PyUnicode_InternFromString("__dict__");
1604 if (str_dict == NULL)
1605 return NULL;
1606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 /* Initialize the C thread library */
1608 PyThread_init_thread();
1609 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001610}