blob: 6e7ee0f43e3e0a847ff353ebc596d2ee96926dc5 [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 Stinner4a3fe082020-04-14 14:26:24 +02007#include "pycore_interp.h" // _PyInterpreterState.num_threads
Victor Stinnere5014be2020-04-14 17:52:15 +02008#include "pycore_pystate.h" // _PyThreadState_Init()
Victor Stinner4a3fe082020-04-14 14:26:24 +02009#include <stddef.h> // offsetof()
Guido van Rossum1984f1e1992-08-04 12:41:02 +000010
Barry Warsawd0c10421996-12-17 00:05:22 +000011static PyObject *ThreadError;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +000012static PyObject *str_dict;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000013
Victor Stinnerbd303c12013-11-07 23:07:29 +010014_Py_IDENTIFIER(stderr);
Victor Stinnercd590a72019-05-28 00:39:52 +020015_Py_IDENTIFIER(flush);
Victor Stinnerbd303c12013-11-07 23:07:29 +010016
Guido van Rossum1984f1e1992-08-04 12:41:02 +000017/* Lock objects */
18
19typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000020 PyObject_HEAD
21 PyThread_type_lock lock_lock;
22 PyObject *in_weakreflist;
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000023 char locked; /* for sanity checking */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000024} lockobject;
25
Guido van Rossum1984f1e1992-08-04 12:41:02 +000026static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000027lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000028{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000029 if (self->in_weakreflist != NULL)
30 PyObject_ClearWeakRefs((PyObject *) self);
31 if (self->lock_lock != NULL) {
32 /* Unlock the lock so it's safe to free it */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000033 if (self->locked)
34 PyThread_release_lock(self->lock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000035 PyThread_free_lock(self->lock_lock);
36 }
37 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000038}
39
Antoine Pitrou810023d2010-12-15 22:59:16 +000040/* Helper to acquire an interruptible lock with a timeout. If the lock acquire
41 * is interrupted, signal handlers are run, and if they raise an exception,
42 * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE
Raymond Hettinger15f44ab2016-08-30 10:47:49 -070043 * are returned, depending on whether the lock can be acquired within the
Antoine Pitrou810023d2010-12-15 22:59:16 +000044 * timeout.
45 */
46static PyLockStatus
Victor Stinnerf5faad22015-03-28 03:52:05 +010047acquire_timed(PyThread_type_lock lock, _PyTime_t timeout)
Antoine Pitrou810023d2010-12-15 22:59:16 +000048{
49 PyLockStatus r;
Victor Stinnerf5faad22015-03-28 03:52:05 +010050 _PyTime_t endtime = 0;
51 _PyTime_t microseconds;
Antoine Pitrou810023d2010-12-15 22:59:16 +000052
Victor Stinnerf5faad22015-03-28 03:52:05 +010053 if (timeout > 0)
54 endtime = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrou810023d2010-12-15 22:59:16 +000055
56 do {
Victor Stinner869e1772015-03-30 03:49:14 +020057 microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING);
Victor Stinnerf5faad22015-03-28 03:52:05 +010058
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000059 /* first a simple non-blocking try without releasing the GIL */
60 r = PyThread_acquire_lock_timed(lock, 0, 0);
61 if (r == PY_LOCK_FAILURE && microseconds != 0) {
62 Py_BEGIN_ALLOW_THREADS
63 r = PyThread_acquire_lock_timed(lock, microseconds, 1);
64 Py_END_ALLOW_THREADS
Victor Stinner357f5152013-11-05 15:10:19 +010065 }
Antoine Pitrou810023d2010-12-15 22:59:16 +000066
67 if (r == PY_LOCK_INTR) {
68 /* Run signal handlers if we were interrupted. Propagate
69 * exceptions from signal handlers, such as KeyboardInterrupt, by
70 * passing up PY_LOCK_INTR. */
71 if (Py_MakePendingCalls() < 0) {
72 return PY_LOCK_INTR;
73 }
74
75 /* If we're using a timeout, recompute the timeout after processing
76 * signals, since those can take time. */
Victor Stinnerf5faad22015-03-28 03:52:05 +010077 if (timeout > 0) {
78 timeout = endtime - _PyTime_GetMonotonicClock();
Antoine Pitrou810023d2010-12-15 22:59:16 +000079
80 /* Check for negative values, since those mean block forever.
81 */
Victor Stinner6aa446c2015-03-30 21:33:51 +020082 if (timeout < 0) {
Antoine Pitrou810023d2010-12-15 22:59:16 +000083 r = PY_LOCK_FAILURE;
84 }
85 }
86 }
87 } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */
88
89 return r;
90}
91
Victor Stinnerf5faad22015-03-28 03:52:05 +010092static int
93lock_acquire_parse_args(PyObject *args, PyObject *kwds,
94 _PyTime_t *timeout)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000095{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000096 char *kwlist[] = {"blocking", "timeout", NULL};
97 int blocking = 1;
Victor Stinnerf5faad22015-03-28 03:52:05 +010098 PyObject *timeout_obj = NULL;
Victor Stinner13019fd2015-04-03 13:10:54 +020099 const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000100
Victor Stinnerf5faad22015-03-28 03:52:05 +0100101 *timeout = unset_timeout ;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000102
Victor Stinnerf5faad22015-03-28 03:52:05 +0100103 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:acquire", kwlist,
104 &blocking, &timeout_obj))
105 return -1;
106
107 if (timeout_obj
Victor Stinner869e1772015-03-30 03:49:14 +0200108 && _PyTime_FromSecondsObject(timeout,
Pablo Galindo59af94f2017-10-18 08:13:09 +0100109 timeout_obj, _PyTime_ROUND_TIMEOUT) < 0)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100110 return -1;
111
112 if (!blocking && *timeout != unset_timeout ) {
113 PyErr_SetString(PyExc_ValueError,
114 "can't specify a timeout for a non-blocking call");
115 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100117 if (*timeout < 0 && *timeout != unset_timeout) {
118 PyErr_SetString(PyExc_ValueError,
119 "timeout value must be positive");
120 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 }
122 if (!blocking)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100123 *timeout = 0;
124 else if (*timeout != unset_timeout) {
125 _PyTime_t microseconds;
126
Pablo Galindo59af94f2017-10-18 08:13:09 +0100127 microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinnerf5faad22015-03-28 03:52:05 +0100128 if (microseconds >= PY_TIMEOUT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 PyErr_SetString(PyExc_OverflowError,
130 "timeout value is too large");
Victor Stinnerf5faad22015-03-28 03:52:05 +0100131 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000132 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100134 return 0;
135}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000136
Victor Stinnerf5faad22015-03-28 03:52:05 +0100137static PyObject *
138lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
139{
140 _PyTime_t timeout;
141 PyLockStatus r;
142
143 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
144 return NULL;
145
146 r = acquire_timed(self->lock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000147 if (r == PY_LOCK_INTR) {
148 return NULL;
149 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000151 if (r == PY_LOCK_ACQUIRED)
152 self->locked = 1;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000153 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000154}
155
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000156PyDoc_STRVAR(acquire_doc,
Berker Peksag720e6552016-05-02 12:25:35 +0300157"acquire(blocking=True, timeout=-1) -> bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000158(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000159\n\
160Lock the lock. Without argument, this blocks if the lock is already\n\
161locked (even by the same thread), waiting for another thread to release\n\
R David Murray95b71102013-02-04 10:15:58 -0500162the lock, and return True once the lock is acquired.\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000163With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000164and the return value reflects whether the lock is acquired.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000165The blocking operation is interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000166
Barry Warsawd0c10421996-12-17 00:05:22 +0000167static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530168lock_PyThread_release_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000169{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000170 /* Sanity check: the lock must be locked */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000171 if (!self->locked) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000172 PyErr_SetString(ThreadError, "release unlocked lock");
173 return NULL;
174 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 PyThread_release_lock(self->lock_lock);
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000177 self->locked = 0;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200178 Py_RETURN_NONE;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000179}
180
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000181PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000182"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000183(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000184\n\
185Release the lock, allowing another thread that is blocked waiting for\n\
186the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000187but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000188
Barry Warsawd0c10421996-12-17 00:05:22 +0000189static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530190lock_locked_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000191{
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000192 return PyBool_FromLong((long)self->locked);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000193}
194
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000195PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000196"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000197(locked_lock() is an obsolete synonym)\n\
198\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000199Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000200
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700201static PyObject *
202lock_repr(lockobject *self)
203{
204 return PyUnicode_FromFormat("<%s %s object at %p>",
205 self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
206}
207
Victor Stinner87255be2020-04-07 23:11:49 +0200208#ifdef HAVE_FORK
209static PyObject *
210lock__at_fork_reinit(lockobject *self, PyObject *Py_UNUSED(args))
211{
212 if (_PyThread_at_fork_reinit(&self->lock_lock) < 0) {
213 PyErr_SetString(ThreadError, "failed to reinitialize lock at fork");
214 return NULL;
215 }
216
217 self->locked = 0;
218
219 Py_RETURN_NONE;
220}
221#endif /* HAVE_FORK */
222
223
Barry Warsawd0c10421996-12-17 00:05:22 +0000224static PyMethodDef lock_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200225 {"acquire_lock", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 METH_VARARGS | METH_KEYWORDS, acquire_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200227 {"acquire", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 METH_VARARGS | METH_KEYWORDS, acquire_doc},
229 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
230 METH_NOARGS, release_doc},
231 {"release", (PyCFunction)lock_PyThread_release_lock,
232 METH_NOARGS, release_doc},
233 {"locked_lock", (PyCFunction)lock_locked_lock,
234 METH_NOARGS, locked_doc},
235 {"locked", (PyCFunction)lock_locked_lock,
236 METH_NOARGS, locked_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200237 {"__enter__", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 METH_VARARGS | METH_KEYWORDS, acquire_doc},
239 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
240 METH_VARARGS, release_doc},
Victor Stinner87255be2020-04-07 23:11:49 +0200241#ifdef HAVE_FORK
242 {"_at_fork_reinit", (PyCFunction)lock__at_fork_reinit,
243 METH_NOARGS, NULL},
244#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000246};
247
Barry Warsawd0c10421996-12-17 00:05:22 +0000248static PyTypeObject Locktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 PyVarObject_HEAD_INIT(&PyType_Type, 0)
250 "_thread.lock", /*tp_name*/
Peter Eisentraut0e0bc4e2018-09-10 18:46:08 +0200251 sizeof(lockobject), /*tp_basicsize*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 0, /*tp_itemsize*/
253 /* methods */
254 (destructor)lock_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200255 0, /*tp_vectorcall_offset*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 0, /*tp_getattr*/
257 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200258 0, /*tp_as_async*/
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700259 (reprfunc)lock_repr, /*tp_repr*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 0, /*tp_as_number*/
261 0, /*tp_as_sequence*/
262 0, /*tp_as_mapping*/
263 0, /*tp_hash*/
264 0, /*tp_call*/
265 0, /*tp_str*/
266 0, /*tp_getattro*/
267 0, /*tp_setattro*/
268 0, /*tp_as_buffer*/
269 Py_TPFLAGS_DEFAULT, /*tp_flags*/
270 0, /*tp_doc*/
271 0, /*tp_traverse*/
272 0, /*tp_clear*/
273 0, /*tp_richcompare*/
274 offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
275 0, /*tp_iter*/
276 0, /*tp_iternext*/
277 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000278};
279
Antoine Pitrou434736a2009-11-10 18:46:01 +0000280/* Recursive lock objects */
281
282typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 PyObject_HEAD
284 PyThread_type_lock rlock_lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200285 unsigned long rlock_owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 unsigned long rlock_count;
287 PyObject *in_weakreflist;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000288} rlockobject;
289
290static void
291rlock_dealloc(rlockobject *self)
292{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293 if (self->in_weakreflist != NULL)
294 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner357f5152013-11-05 15:10:19 +0100295 /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed
296 in rlock_new() */
297 if (self->rlock_lock != NULL) {
298 /* Unlock the lock so it's safe to free it */
299 if (self->rlock_count > 0)
300 PyThread_release_lock(self->rlock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301
Victor Stinner357f5152013-11-05 15:10:19 +0100302 PyThread_free_lock(self->rlock_lock);
303 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 Py_TYPE(self)->tp_free(self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000305}
306
307static PyObject *
308rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
309{
Victor Stinnerf5faad22015-03-28 03:52:05 +0100310 _PyTime_t timeout;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200311 unsigned long tid;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000312 PyLockStatus r = PY_LOCK_ACQUIRED;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000313
Victor Stinnerf5faad22015-03-28 03:52:05 +0100314 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 tid = PyThread_get_thread_ident();
318 if (self->rlock_count > 0 && tid == self->rlock_owner) {
319 unsigned long count = self->rlock_count + 1;
320 if (count <= self->rlock_count) {
321 PyErr_SetString(PyExc_OverflowError,
322 "Internal lock count overflowed");
323 return NULL;
324 }
325 self->rlock_count = count;
326 Py_RETURN_TRUE;
327 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100328 r = acquire_timed(self->rlock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000329 if (r == PY_LOCK_ACQUIRED) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330 assert(self->rlock_count == 0);
331 self->rlock_owner = tid;
332 self->rlock_count = 1;
333 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000334 else if (r == PY_LOCK_INTR) {
335 return NULL;
336 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337
Antoine Pitrou810023d2010-12-15 22:59:16 +0000338 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000339}
340
341PyDoc_STRVAR(rlock_acquire_doc,
342"acquire(blocking=True) -> bool\n\
343\n\
344Lock the lock. `blocking` indicates whether we should wait\n\
345for the lock to be available or not. If `blocking` is False\n\
346and another thread holds the lock, the method will return False\n\
347immediately. If `blocking` is True and another thread holds\n\
348the lock, the method will wait for the lock to be released,\n\
349take it and then return True.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000350(note: the blocking operation is interruptible.)\n\
Antoine Pitrou434736a2009-11-10 18:46:01 +0000351\n\
352In all other cases, the method will return True immediately.\n\
353Precisely, if the current thread already holds the lock, its\n\
354internal counter is simply incremented. If nobody holds the lock,\n\
355the lock is taken and its internal counter initialized to 1.");
356
357static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530358rlock_release(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000359{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200360 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrou434736a2009-11-10 18:46:01 +0000361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 if (self->rlock_count == 0 || self->rlock_owner != tid) {
363 PyErr_SetString(PyExc_RuntimeError,
364 "cannot release un-acquired lock");
365 return NULL;
366 }
367 if (--self->rlock_count == 0) {
368 self->rlock_owner = 0;
369 PyThread_release_lock(self->rlock_lock);
370 }
371 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000372}
373
374PyDoc_STRVAR(rlock_release_doc,
375"release()\n\
376\n\
377Release the lock, allowing another thread that is blocked waiting for\n\
378the lock to acquire the lock. The lock must be in the locked state,\n\
379and must be locked by the same thread that unlocks it; otherwise a\n\
380`RuntimeError` is raised.\n\
381\n\
382Do note that if the lock was acquire()d several times in a row by the\n\
383current thread, release() needs to be called as many times for the lock\n\
384to be available for other threads.");
385
386static PyObject *
Victor Stinnere8794522014-01-02 12:47:24 +0100387rlock_acquire_restore(rlockobject *self, PyObject *args)
Antoine Pitrou434736a2009-11-10 18:46:01 +0000388{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200389 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390 unsigned long count;
391 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000392
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200393 if (!PyArg_ParseTuple(args, "(kk):_acquire_restore", &count, &owner))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
397 Py_BEGIN_ALLOW_THREADS
398 r = PyThread_acquire_lock(self->rlock_lock, 1);
399 Py_END_ALLOW_THREADS
400 }
401 if (!r) {
402 PyErr_SetString(ThreadError, "couldn't acquire lock");
403 return NULL;
404 }
405 assert(self->rlock_count == 0);
406 self->rlock_owner = owner;
407 self->rlock_count = count;
408 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000409}
410
411PyDoc_STRVAR(rlock_acquire_restore_doc,
412"_acquire_restore(state) -> None\n\
413\n\
414For internal use by `threading.Condition`.");
415
416static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530417rlock_release_save(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000418{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200419 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 unsigned long count;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000421
Victor Stinnerc2824d42011-04-24 23:41:33 +0200422 if (self->rlock_count == 0) {
423 PyErr_SetString(PyExc_RuntimeError,
424 "cannot release un-acquired lock");
425 return NULL;
426 }
427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 owner = self->rlock_owner;
429 count = self->rlock_count;
430 self->rlock_count = 0;
431 self->rlock_owner = 0;
432 PyThread_release_lock(self->rlock_lock);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200433 return Py_BuildValue("kk", count, owner);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000434}
435
436PyDoc_STRVAR(rlock_release_save_doc,
437"_release_save() -> tuple\n\
438\n\
439For internal use by `threading.Condition`.");
440
441
442static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530443rlock_is_owned(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000444{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200445 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446
447 if (self->rlock_count > 0 && self->rlock_owner == tid) {
448 Py_RETURN_TRUE;
449 }
450 Py_RETURN_FALSE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000451}
452
453PyDoc_STRVAR(rlock_is_owned_doc,
454"_is_owned() -> bool\n\
455\n\
456For internal use by `threading.Condition`.");
457
458static PyObject *
459rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
460{
Victor Stinner87255be2020-04-07 23:11:49 +0200461 rlockobject *self = (rlockobject *) type->tp_alloc(type, 0);
462 if (self == NULL) {
463 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 }
Victor Stinner87255be2020-04-07 23:11:49 +0200465 self->in_weakreflist = NULL;
466 self->rlock_owner = 0;
467 self->rlock_count = 0;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000468
Victor Stinner87255be2020-04-07 23:11:49 +0200469 self->rlock_lock = PyThread_allocate_lock();
470 if (self->rlock_lock == NULL) {
471 Py_DECREF(self);
472 PyErr_SetString(ThreadError, "can't allocate lock");
473 return NULL;
474 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 return (PyObject *) self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000476}
477
478static PyObject *
479rlock_repr(rlockobject *self)
480{
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700481 return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>",
482 self->rlock_count ? "locked" : "unlocked",
483 Py_TYPE(self)->tp_name, self->rlock_owner,
484 self->rlock_count, self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000485}
486
487
Victor Stinner87255be2020-04-07 23:11:49 +0200488#ifdef HAVE_FORK
489static PyObject *
490rlock__at_fork_reinit(rlockobject *self, PyObject *Py_UNUSED(args))
491{
492 if (_PyThread_at_fork_reinit(&self->rlock_lock) < 0) {
493 PyErr_SetString(ThreadError, "failed to reinitialize lock at fork");
494 return NULL;
495 }
496
497 self->rlock_owner = 0;
498 self->rlock_count = 0;
499
500 Py_RETURN_NONE;
501}
502#endif /* HAVE_FORK */
503
504
Antoine Pitrou434736a2009-11-10 18:46:01 +0000505static PyMethodDef rlock_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200506 {"acquire", (PyCFunction)(void(*)(void))rlock_acquire,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
508 {"release", (PyCFunction)rlock_release,
509 METH_NOARGS, rlock_release_doc},
510 {"_is_owned", (PyCFunction)rlock_is_owned,
511 METH_NOARGS, rlock_is_owned_doc},
512 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
Victor Stinnere8794522014-01-02 12:47:24 +0100513 METH_VARARGS, rlock_acquire_restore_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 {"_release_save", (PyCFunction)rlock_release_save,
515 METH_NOARGS, rlock_release_save_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200516 {"__enter__", (PyCFunction)(void(*)(void))rlock_acquire,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
518 {"__exit__", (PyCFunction)rlock_release,
519 METH_VARARGS, rlock_release_doc},
Victor Stinner87255be2020-04-07 23:11:49 +0200520#ifdef HAVE_FORK
521 {"_at_fork_reinit", (PyCFunction)rlock__at_fork_reinit,
522 METH_NOARGS, NULL},
523#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 {NULL, NULL} /* sentinel */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000525};
526
527
528static PyTypeObject RLocktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 PyVarObject_HEAD_INIT(&PyType_Type, 0)
530 "_thread.RLock", /*tp_name*/
Peter Eisentraut0e0bc4e2018-09-10 18:46:08 +0200531 sizeof(rlockobject), /*tp_basicsize*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 0, /*tp_itemsize*/
533 /* methods */
534 (destructor)rlock_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200535 0, /*tp_vectorcall_offset*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 0, /*tp_getattr*/
537 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200538 0, /*tp_as_async*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 (reprfunc)rlock_repr, /*tp_repr*/
540 0, /*tp_as_number*/
541 0, /*tp_as_sequence*/
542 0, /*tp_as_mapping*/
543 0, /*tp_hash*/
544 0, /*tp_call*/
545 0, /*tp_str*/
546 0, /*tp_getattro*/
547 0, /*tp_setattro*/
548 0, /*tp_as_buffer*/
549 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
550 0, /*tp_doc*/
551 0, /*tp_traverse*/
552 0, /*tp_clear*/
553 0, /*tp_richcompare*/
554 offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
555 0, /*tp_iter*/
556 0, /*tp_iternext*/
557 rlock_methods, /*tp_methods*/
558 0, /* tp_members */
559 0, /* tp_getset */
560 0, /* tp_base */
561 0, /* tp_dict */
562 0, /* tp_descr_get */
563 0, /* tp_descr_set */
564 0, /* tp_dictoffset */
565 0, /* tp_init */
566 PyType_GenericAlloc, /* tp_alloc */
567 rlock_new /* tp_new */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000568};
569
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000570static lockobject *
571newlockobject(void)
572{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 lockobject *self;
574 self = PyObject_New(lockobject, &Locktype);
575 if (self == NULL)
576 return NULL;
577 self->lock_lock = PyThread_allocate_lock();
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000578 self->locked = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 self->in_weakreflist = NULL;
580 if (self->lock_lock == NULL) {
581 Py_DECREF(self);
582 PyErr_SetString(ThreadError, "can't allocate lock");
583 return NULL;
584 }
585 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000586}
587
Jim Fultond15dc062004-07-14 19:11:50 +0000588/* Thread-local objects */
589
590#include "structmember.h"
591
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000592/* Quick overview:
593
594 We need to be able to reclaim reference cycles as soon as possible
595 (both when a thread is being terminated, or a thread-local object
596 becomes unreachable from user data). Constraints:
597 - it must not be possible for thread-state dicts to be involved in
598 reference cycles (otherwise the cyclic GC will refuse to consider
599 objects referenced from a reachable thread-state dict, even though
600 local_dealloc would clear them)
601 - the death of a thread-state dict must still imply destruction of the
602 corresponding local dicts in all thread-local objects.
603
604 Our implementation uses small "localdummy" objects in order to break
605 the reference chain. These trivial objects are hashable (using the
606 default scheme of identity hashing) and weakrefable.
607 Each thread-state holds a separate localdummy for each local object
608 (as a /strong reference/),
609 and each thread-local object holds a dict mapping /weak references/
610 of localdummies to local dicts.
611
612 Therefore:
613 - only the thread-state dict holds a strong reference to the dummies
614 - only the thread-local object holds a strong reference to the local dicts
615 - only outside objects (application- or library-level) hold strong
616 references to the thread-local objects
617 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
618 dummies attached to that thread are called, and destroy the corresponding
619 local dicts from thread-local objects
620 - as soon as a thread-local object is destroyed, its local dicts are
621 destroyed and its dummies are manually removed from all thread states
622 - the GC can do its work correctly when a thread-local object is dangling,
623 without any interference from the thread-state dicts
624
625 As an additional optimization, each localdummy holds a borrowed reference
626 to the corresponding localdict. This borrowed reference is only used
627 by the thread-local object which has created the localdummy, which should
628 guarantee that the localdict still exists when accessed.
629*/
630
631typedef struct {
632 PyObject_HEAD
633 PyObject *localdict; /* Borrowed reference! */
634 PyObject *weakreflist; /* List of weak references to self */
635} localdummyobject;
636
637static void
638localdummy_dealloc(localdummyobject *self)
639{
640 if (self->weakreflist != NULL)
641 PyObject_ClearWeakRefs((PyObject *) self);
642 Py_TYPE(self)->tp_free((PyObject*)self);
643}
644
645static PyTypeObject localdummytype = {
646 PyVarObject_HEAD_INIT(NULL, 0)
647 /* tp_name */ "_thread._localdummy",
648 /* tp_basicsize */ sizeof(localdummyobject),
649 /* tp_itemsize */ 0,
650 /* tp_dealloc */ (destructor)localdummy_dealloc,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200651 /* tp_vectorcall_offset */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000652 /* tp_getattr */ 0,
653 /* tp_setattr */ 0,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200654 /* tp_as_async */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000655 /* tp_repr */ 0,
656 /* tp_as_number */ 0,
657 /* tp_as_sequence */ 0,
658 /* tp_as_mapping */ 0,
659 /* tp_hash */ 0,
660 /* tp_call */ 0,
661 /* tp_str */ 0,
662 /* tp_getattro */ 0,
663 /* tp_setattro */ 0,
664 /* tp_as_buffer */ 0,
665 /* tp_flags */ Py_TPFLAGS_DEFAULT,
666 /* tp_doc */ "Thread-local dummy",
667 /* tp_traverse */ 0,
668 /* tp_clear */ 0,
669 /* tp_richcompare */ 0,
670 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
671};
672
673
Jim Fultond15dc062004-07-14 19:11:50 +0000674typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 PyObject_HEAD
676 PyObject *key;
677 PyObject *args;
678 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000679 PyObject *weakreflist; /* List of weak references to self */
680 /* A {localdummy weakref -> localdict} dict */
681 PyObject *dummies;
682 /* The callback for weakrefs to localdummies */
683 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000684} localobject;
685
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000686/* Forward declaration */
687static PyObject *_ldict(localobject *self);
688static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
689
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000690/* Create and register the dummy for the current thread.
691 Returns a borrowed reference of the corresponding local dict */
692static PyObject *
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000693_local_create_dummy(localobject *self)
694{
695 PyObject *tdict, *ldict = NULL, *wr = NULL;
696 localdummyobject *dummy = NULL;
697 int r;
698
699 tdict = PyThreadState_GetDict();
700 if (tdict == NULL) {
701 PyErr_SetString(PyExc_SystemError,
702 "Couldn't get thread-state dictionary");
703 goto err;
704 }
705
706 ldict = PyDict_New();
707 if (ldict == NULL)
708 goto err;
709 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
710 if (dummy == NULL)
711 goto err;
712 dummy->localdict = ldict;
713 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
714 if (wr == NULL)
715 goto err;
716
717 /* As a side-effect, this will cache the weakref's hash before the
718 dummy gets deleted */
719 r = PyDict_SetItem(self->dummies, wr, ldict);
720 if (r < 0)
721 goto err;
722 Py_CLEAR(wr);
723 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
724 if (r < 0)
725 goto err;
726 Py_CLEAR(dummy);
727
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000728 Py_DECREF(ldict);
729 return ldict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000730
731err:
732 Py_XDECREF(ldict);
733 Py_XDECREF(wr);
734 Py_XDECREF(dummy);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000735 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000736}
737
Jim Fultond15dc062004-07-14 19:11:50 +0000738static PyObject *
739local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
740{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 localobject *self;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000742 PyObject *wr;
743 static PyMethodDef wr_callback_def = {
744 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
745 };
Jim Fultond15dc062004-07-14 19:11:50 +0000746
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300747 if (type->tp_init == PyBaseObject_Type.tp_init) {
748 int rc = 0;
749 if (args != NULL)
750 rc = PyObject_IsTrue(args);
751 if (rc == 0 && kw != NULL)
752 rc = PyObject_IsTrue(kw);
753 if (rc != 0) {
754 if (rc > 0)
755 PyErr_SetString(PyExc_TypeError,
756 "Initialization arguments are not supported");
757 return NULL;
758 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 }
Jim Fultond15dc062004-07-14 19:11:50 +0000760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 self = (localobject *)type->tp_alloc(type, 0);
762 if (self == NULL)
763 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000764
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 Py_XINCREF(args);
766 self->args = args;
767 Py_XINCREF(kw);
768 self->kw = kw;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 self->key = PyUnicode_FromFormat("thread.local.%p", self);
770 if (self->key == NULL)
771 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000772
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000773 self->dummies = PyDict_New();
774 if (self->dummies == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000775 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000776
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000777 /* We use a weak reference to self in the callback closure
778 in order to avoid spurious reference cycles */
779 wr = PyWeakref_NewRef((PyObject *) self, NULL);
780 if (wr == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000781 goto err;
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200782 self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000783 Py_DECREF(wr);
784 if (self->wr_callback == NULL)
785 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000786
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000787 if (_local_create_dummy(self) == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000788 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000790 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000791
792 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000793 Py_DECREF(self);
794 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000795}
796
797static int
798local_traverse(localobject *self, visitproc visit, void *arg)
799{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 Py_VISIT(self->args);
801 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000802 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000803 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000804}
805
806static int
807local_clear(localobject *self)
808{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000809 PyThreadState *tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000810 Py_CLEAR(self->args);
811 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000812 Py_CLEAR(self->dummies);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000813 Py_CLEAR(self->wr_callback);
814 /* Remove all strong references to dummies from the thread states */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000815 if (self->key
816 && (tstate = PyThreadState_Get())
817 && tstate->interp) {
818 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
819 tstate;
820 tstate = PyThreadState_Next(tstate))
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200821 if (tstate->dict && PyDict_GetItem(tstate->dict, self->key)) {
822 if (PyDict_DelItem(tstate->dict, self->key)) {
823 PyErr_Clear();
824 }
825 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000827 return 0;
828}
Jim Fultond15dc062004-07-14 19:11:50 +0000829
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000830static void
831local_dealloc(localobject *self)
832{
833 /* Weakrefs must be invalidated right now, otherwise they can be used
834 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
835 if (self->weakreflist != NULL)
836 PyObject_ClearWeakRefs((PyObject *) self);
837
838 PyObject_GC_UnTrack(self);
839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000840 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000841 Py_XDECREF(self->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000843}
844
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000845/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000846static PyObject *
847_ldict(localobject *self)
848{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000849 PyObject *tdict, *ldict, *dummy;
Jim Fultond15dc062004-07-14 19:11:50 +0000850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000851 tdict = PyThreadState_GetDict();
852 if (tdict == NULL) {
853 PyErr_SetString(PyExc_SystemError,
854 "Couldn't get thread-state dictionary");
855 return NULL;
856 }
Jim Fultond15dc062004-07-14 19:11:50 +0000857
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200858 dummy = PyDict_GetItemWithError(tdict, self->key);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000859 if (dummy == NULL) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200860 if (PyErr_Occurred()) {
861 return NULL;
862 }
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000863 ldict = _local_create_dummy(self);
864 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000867 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
868 Py_TYPE(self)->tp_init((PyObject*)self,
869 self->args, self->kw) < 0) {
870 /* we need to get rid of ldict from thread so
871 we create a new one the next time we do an attr
Ezio Melotti42da6632011-03-15 05:18:48 +0200872 access */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000873 PyDict_DelItem(tdict, self->key);
874 return NULL;
875 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000876 }
877 else {
Andy Lesterdffe4c02020-03-04 07:15:20 -0600878 assert(Py_IS_TYPE(dummy, &localdummytype));
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000879 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 }
Jim Fultond15dc062004-07-14 19:11:50 +0000881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000882 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000883}
884
Jim Fultond15dc062004-07-14 19:11:50 +0000885static int
886local_setattro(localobject *self, PyObject *name, PyObject *v)
887{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000888 PyObject *ldict;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000889 int r;
Jim Fultond15dc062004-07-14 19:11:50 +0000890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 ldict = _ldict(self);
892 if (ldict == NULL)
893 return -1;
894
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000895 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
896 if (r == 1) {
897 PyErr_Format(PyExc_AttributeError,
898 "'%.50s' object attribute '%U' is read-only",
899 Py_TYPE(self)->tp_name, name);
900 return -1;
901 }
902 if (r == -1)
903 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000904
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000905 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000906}
907
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000908static PyObject *local_getattro(localobject *, PyObject *);
909
Jim Fultond15dc062004-07-14 19:11:50 +0000910static PyTypeObject localtype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 PyVarObject_HEAD_INIT(NULL, 0)
912 /* tp_name */ "_thread._local",
913 /* tp_basicsize */ sizeof(localobject),
914 /* tp_itemsize */ 0,
915 /* tp_dealloc */ (destructor)local_dealloc,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200916 /* tp_vectorcall_offset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000917 /* tp_getattr */ 0,
918 /* tp_setattr */ 0,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200919 /* tp_as_async */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000920 /* tp_repr */ 0,
921 /* tp_as_number */ 0,
922 /* tp_as_sequence */ 0,
923 /* tp_as_mapping */ 0,
924 /* tp_hash */ 0,
925 /* tp_call */ 0,
926 /* tp_str */ 0,
927 /* tp_getattro */ (getattrofunc)local_getattro,
928 /* tp_setattro */ (setattrofunc)local_setattro,
929 /* tp_as_buffer */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000930 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
931 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000932 /* tp_doc */ "Thread-local data",
933 /* tp_traverse */ (traverseproc)local_traverse,
934 /* tp_clear */ (inquiry)local_clear,
935 /* tp_richcompare */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000936 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000937 /* tp_iter */ 0,
938 /* tp_iternext */ 0,
939 /* tp_methods */ 0,
940 /* tp_members */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000941 /* tp_getset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000942 /* tp_base */ 0,
943 /* tp_dict */ 0, /* internal use */
944 /* tp_descr_get */ 0,
945 /* tp_descr_set */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000946 /* tp_dictoffset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000947 /* tp_init */ 0,
948 /* tp_alloc */ 0,
949 /* tp_new */ local_new,
950 /* tp_free */ 0, /* Low-level free-mem routine */
951 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000952};
953
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000954static PyObject *
955local_getattro(localobject *self, PyObject *name)
956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 PyObject *ldict, *value;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000958 int r;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000960 ldict = _ldict(self);
961 if (ldict == NULL)
962 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000963
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000964 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
965 if (r == 1) {
966 Py_INCREF(ldict);
967 return ldict;
968 }
969 if (r == -1)
970 return NULL;
971
Andy Lester55728702020-03-06 16:53:17 -0600972 if (!Py_IS_TYPE(self, &localtype))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 /* use generic lookup for subtypes */
INADA Naoki378edee2018-01-16 20:52:41 +0900974 return _PyObject_GenericGetAttrWithDict(
975 (PyObject *)self, name, ldict, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 /* Optimization: just look in dict ourselves */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200978 value = PyDict_GetItemWithError(ldict, name);
979 if (value != NULL) {
980 Py_INCREF(value);
981 return value;
982 }
983 else if (PyErr_Occurred()) {
984 return NULL;
985 }
986 /* Fall back on generic to get __class__ and __dict__ */
987 return _PyObject_GenericGetAttrWithDict(
988 (PyObject *)self, name, ldict, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000989}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000990
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000991/* Called when a dummy is destroyed. */
992static PyObject *
993_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
994{
995 PyObject *obj;
996 localobject *self;
997 assert(PyWeakref_CheckRef(localweakref));
998 obj = PyWeakref_GET_OBJECT(localweakref);
999 if (obj == Py_None)
1000 Py_RETURN_NONE;
1001 Py_INCREF(obj);
1002 assert(PyObject_TypeCheck(obj, &localtype));
1003 /* If the thread-local object is still alive and not being cleared,
1004 remove the corresponding local dict */
1005 self = (localobject *) obj;
1006 if (self->dummies != NULL) {
1007 PyObject *ldict;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001008 ldict = PyDict_GetItemWithError(self->dummies, dummyweakref);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001009 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001010 PyDict_DelItem(self->dummies, dummyweakref);
1011 }
1012 if (PyErr_Occurred())
1013 PyErr_WriteUnraisable(obj);
1014 }
1015 Py_DECREF(obj);
1016 Py_RETURN_NONE;
1017}
1018
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001019/* Module functions */
1020
Guido van Rossuma027efa1997-05-05 20:56:21 +00001021struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001022 PyInterpreterState *interp;
1023 PyObject *func;
1024 PyObject *args;
1025 PyObject *keyw;
1026 PyThreadState *tstate;
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001027 _PyRuntimeState *runtime;
Guido van Rossuma027efa1997-05-05 20:56:21 +00001028};
1029
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001030static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001031t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001032{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033 struct bootstate *boot = (struct bootstate *) boot_raw;
1034 PyThreadState *tstate;
1035 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001036
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001037 tstate = boot->tstate;
1038 tstate->thread_id = PyThread_get_thread_ident();
Victor Stinner01b1cc12019-11-20 02:27:56 +01001039 _PyThreadState_Init(tstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 PyEval_AcquireThread(tstate);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001041 tstate->interp->num_threads++;
INADA Naoki72dccde2017-02-16 09:26:01 +09001042 res = PyObject_Call(boot->func, boot->args, boot->keyw);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001043 if (res == NULL) {
1044 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Victor Stinner8b095002019-05-29 02:57:56 +02001045 /* SystemExit is ignored silently */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 PyErr_Clear();
1047 else {
Victor Stinner8b095002019-05-29 02:57:56 +02001048 _PyErr_WriteUnraisableMsg("in thread started by", boot->func);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 }
1050 }
Victor Stinner8b095002019-05-29 02:57:56 +02001051 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001052 Py_DECREF(res);
Victor Stinner8b095002019-05-29 02:57:56 +02001053 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 Py_DECREF(boot->func);
1055 Py_DECREF(boot->args);
1056 Py_XDECREF(boot->keyw);
1057 PyMem_DEL(boot_raw);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001058 tstate->interp->num_threads--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 PyThreadState_Clear(tstate);
Victor Stinner23ef89d2020-03-18 02:26:04 +01001060 _PyThreadState_DeleteCurrent(tstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001062}
1063
Barry Warsawd0c10421996-12-17 00:05:22 +00001064static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001065thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001066{
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001067 _PyRuntimeState *runtime = &_PyRuntime;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 PyObject *func, *args, *keyw = NULL;
1069 struct bootstate *boot;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001070 unsigned long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
1073 &func, &args, &keyw))
1074 return NULL;
1075 if (!PyCallable_Check(func)) {
1076 PyErr_SetString(PyExc_TypeError,
1077 "first arg must be callable");
1078 return NULL;
1079 }
1080 if (!PyTuple_Check(args)) {
1081 PyErr_SetString(PyExc_TypeError,
1082 "2nd arg must be a tuple");
1083 return NULL;
1084 }
1085 if (keyw != NULL && !PyDict_Check(keyw)) {
1086 PyErr_SetString(PyExc_TypeError,
1087 "optional 3rd arg must be a dictionary");
1088 return NULL;
1089 }
1090 boot = PyMem_NEW(struct bootstate, 1);
1091 if (boot == NULL)
1092 return PyErr_NoMemory();
Victor Stinner81a7be32020-04-14 15:14:01 +02001093 boot->interp = _PyInterpreterState_GET();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 boot->func = func;
1095 boot->args = args;
1096 boot->keyw = keyw;
1097 boot->tstate = _PyThreadState_Prealloc(boot->interp);
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001098 boot->runtime = runtime;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 if (boot->tstate == NULL) {
1100 PyMem_DEL(boot);
1101 return PyErr_NoMemory();
1102 }
1103 Py_INCREF(func);
1104 Py_INCREF(args);
1105 Py_XINCREF(keyw);
Victor Stinner3225b9f2020-03-09 20:56:57 +01001106
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001108 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001109 PyErr_SetString(ThreadError, "can't start new thread");
1110 Py_DECREF(func);
1111 Py_DECREF(args);
1112 Py_XDECREF(keyw);
1113 PyThreadState_Clear(boot->tstate);
1114 PyMem_DEL(boot);
1115 return NULL;
1116 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001117 return PyLong_FromUnsignedLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001118}
1119
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001120PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001121"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001122(start_new() is an obsolete synonym)\n\
1123\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001124Start a new thread and return its identifier. The thread will call the\n\
1125function with positional arguments from the tuple args and keyword arguments\n\
1126taken from the optional dictionary kwargs. The thread exits when the\n\
1127function returns; the return value is ignored. The thread will also exit\n\
1128when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001129printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001130
Barry Warsawd0c10421996-12-17 00:05:22 +00001131static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301132thread_PyThread_exit_thread(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001133{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001134 PyErr_SetNone(PyExc_SystemExit);
1135 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001136}
1137
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001138PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001139"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001140(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001141\n\
1142This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001143thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001144
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001145static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301146thread_PyThread_interrupt_main(PyObject * self, PyObject *Py_UNUSED(ignored))
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001147{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 PyErr_SetInterrupt();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001149 Py_RETURN_NONE;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001150}
1151
1152PyDoc_STRVAR(interrupt_doc,
1153"interrupt_main()\n\
1154\n\
1155Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001156A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001157);
1158
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001159static lockobject *newlockobject(void);
1160
Barry Warsawd0c10421996-12-17 00:05:22 +00001161static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301162thread_PyThread_allocate_lock(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001163{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001165}
1166
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001167PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001168"allocate_lock() -> lock object\n\
1169(allocate() is an obsolete synonym)\n\
1170\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001171Create a new lock object. See help(type(threading.Lock())) for\n\
1172information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001173
Barry Warsawd0c10421996-12-17 00:05:22 +00001174static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301175thread_get_ident(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001176{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001177 unsigned long ident = PyThread_get_thread_ident();
1178 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 PyErr_SetString(ThreadError, "no current thread ident");
1180 return NULL;
1181 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001182 return PyLong_FromUnsignedLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001183}
1184
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001185PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001186"get_ident() -> integer\n\
1187\n\
1188Return a non-zero integer that uniquely identifies the current thread\n\
1189amongst other threads that exist simultaneously.\n\
1190This may be used to identify per-thread resources.\n\
1191Even though on some platforms threads identities may appear to be\n\
1192allocated consecutive numbers starting at 1, this behavior should not\n\
1193be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001194A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001195
Jake Teslerb121f632019-05-22 08:43:17 -07001196#ifdef PY_HAVE_THREAD_NATIVE_ID
1197static PyObject *
1198thread_get_native_id(PyObject *self, PyObject *Py_UNUSED(ignored))
1199{
1200 unsigned long native_id = PyThread_get_thread_native_id();
1201 return PyLong_FromUnsignedLong(native_id);
1202}
1203
1204PyDoc_STRVAR(get_native_id_doc,
1205"get_native_id() -> integer\n\
1206\n\
1207Return a non-negative integer identifying the thread as reported\n\
1208by the OS (kernel). This may be used to uniquely identify a\n\
1209particular thread within a system.");
1210#endif
1211
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001212static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301213thread__count(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001214{
Victor Stinner81a7be32020-04-14 15:14:01 +02001215 PyInterpreterState *interp = _PyInterpreterState_GET();
Victor Stinnercaba55b2018-08-03 15:33:52 +02001216 return PyLong_FromLong(interp->num_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001217}
1218
1219PyDoc_STRVAR(_count_doc,
1220"_count() -> integer\n\
1221\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001222\
oldkaa0735f2018-02-02 16:52:55 +08001223Return the number of currently running Python threads, excluding\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001224the main thread. The returned number comprises all threads created\n\
1225through `start_new_thread()` as well as `threading.Thread`, and not\n\
1226yet finished.\n\
1227\n\
1228This function is meant for internal and specialized purposes only.\n\
1229In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001230
Antoine Pitrou7b476992013-09-07 23:38:37 +02001231static void
Victor Stinnera42de742018-11-22 10:25:22 +01001232release_sentinel(void *wr_raw)
Antoine Pitrou7b476992013-09-07 23:38:37 +02001233{
Victor Stinnera42de742018-11-22 10:25:22 +01001234 PyObject *wr = _PyObject_CAST(wr_raw);
Antoine Pitrou7b476992013-09-07 23:38:37 +02001235 /* Tricky: this function is called when the current thread state
1236 is being deleted. Therefore, only simple C code can safely
1237 execute here. */
1238 PyObject *obj = PyWeakref_GET_OBJECT(wr);
1239 lockobject *lock;
1240 if (obj != Py_None) {
Andy Lesterdffe4c02020-03-04 07:15:20 -06001241 assert(Py_IS_TYPE(obj, &Locktype));
Antoine Pitrou7b476992013-09-07 23:38:37 +02001242 lock = (lockobject *) obj;
1243 if (lock->locked) {
1244 PyThread_release_lock(lock->lock_lock);
1245 lock->locked = 0;
1246 }
1247 }
1248 /* Deallocating a weakref with a NULL callback only calls
1249 PyObject_GC_Del(), which can't call any Python code. */
1250 Py_DECREF(wr);
1251}
1252
1253static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301254thread__set_sentinel(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou7b476992013-09-07 23:38:37 +02001255{
1256 PyObject *wr;
1257 PyThreadState *tstate = PyThreadState_Get();
1258 lockobject *lock;
1259
1260 if (tstate->on_delete_data != NULL) {
1261 /* We must support the re-creation of the lock from a
1262 fork()ed child. */
1263 assert(tstate->on_delete == &release_sentinel);
1264 wr = (PyObject *) tstate->on_delete_data;
1265 tstate->on_delete = NULL;
1266 tstate->on_delete_data = NULL;
1267 Py_DECREF(wr);
1268 }
1269 lock = newlockobject();
1270 if (lock == NULL)
1271 return NULL;
1272 /* The lock is owned by whoever called _set_sentinel(), but the weakref
1273 hangs to the thread state. */
1274 wr = PyWeakref_NewRef((PyObject *) lock, NULL);
1275 if (wr == NULL) {
1276 Py_DECREF(lock);
1277 return NULL;
1278 }
1279 tstate->on_delete_data = (void *) wr;
1280 tstate->on_delete = &release_sentinel;
1281 return (PyObject *) lock;
1282}
1283
1284PyDoc_STRVAR(_set_sentinel_doc,
1285"_set_sentinel() -> lock\n\
1286\n\
1287Set a sentinel lock that will be released when the current thread\n\
1288state is finalized (after it is untied from the interpreter).\n\
1289\n\
1290This is a private API for the threading module.");
1291
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001292static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001293thread_stack_size(PyObject *self, PyObject *args)
1294{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 size_t old_size;
1296 Py_ssize_t new_size = 0;
1297 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1300 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 if (new_size < 0) {
1303 PyErr_SetString(PyExc_ValueError,
1304 "size must be 0 or a positive value");
1305 return NULL;
1306 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 rc = PyThread_set_stacksize((size_t) new_size);
1311 if (rc == -1) {
1312 PyErr_Format(PyExc_ValueError,
1313 "size not valid: %zd bytes",
1314 new_size);
1315 return NULL;
1316 }
1317 if (rc == -2) {
1318 PyErr_SetString(ThreadError,
1319 "setting stack size not supported");
1320 return NULL;
1321 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001324}
1325
1326PyDoc_STRVAR(stack_size_doc,
1327"stack_size([size]) -> size\n\
1328\n\
1329Return the thread stack size used when creating new threads. The\n\
1330optional size argument specifies the stack size (in bytes) to be used\n\
1331for subsequently created threads, and must be 0 (use platform or\n\
1332configured default) or a positive integer value of at least 32,768 (32k).\n\
1333If changing the thread stack size is unsupported, a ThreadError\n\
1334exception is raised. If the specified size is invalid, a ValueError\n\
1335exception is raised, and the stack size is unmodified. 32k bytes\n\
1336 currently the minimum supported stack size value to guarantee\n\
1337sufficient stack space for the interpreter itself.\n\
1338\n\
1339Note that some platforms may have particular restrictions on values for\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001340the stack size, such as requiring a minimum stack size larger than 32 KiB or\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001341requiring allocation in multiples of the system memory page size\n\
1342- platform documentation should be referred to for more information\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001343(4 KiB pages are common; using multiples of 4096 for the stack size is\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001344the suggested approach in the absence of more specific information).");
1345
Victor Stinnercd590a72019-05-28 00:39:52 +02001346static int
1347thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value,
1348 PyObject *exc_traceback, PyObject *thread)
1349{
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001350 _Py_IDENTIFIER(name);
Victor Stinnercd590a72019-05-28 00:39:52 +02001351 /* print(f"Exception in thread {thread.name}:", file=file) */
1352 if (PyFile_WriteString("Exception in thread ", file) < 0) {
1353 return -1;
1354 }
1355
1356 PyObject *name = NULL;
1357 if (thread != Py_None) {
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001358 if (_PyObject_LookupAttrId(thread, &PyId_name, &name) < 0) {
1359 return -1;
1360 }
Victor Stinnercd590a72019-05-28 00:39:52 +02001361 }
1362 if (name != NULL) {
1363 if (PyFile_WriteObject(name, file, Py_PRINT_RAW) < 0) {
1364 Py_DECREF(name);
1365 return -1;
1366 }
1367 Py_DECREF(name);
1368 }
1369 else {
Victor Stinnercd590a72019-05-28 00:39:52 +02001370 unsigned long ident = PyThread_get_thread_ident();
1371 PyObject *str = PyUnicode_FromFormat("%lu", ident);
1372 if (str != NULL) {
1373 if (PyFile_WriteObject(str, file, Py_PRINT_RAW) < 0) {
1374 Py_DECREF(str);
1375 return -1;
1376 }
1377 Py_DECREF(str);
1378 }
1379 else {
1380 PyErr_Clear();
1381
1382 if (PyFile_WriteString("<failed to get thread name>", file) < 0) {
1383 return -1;
1384 }
1385 }
1386 }
1387
1388 if (PyFile_WriteString(":\n", file) < 0) {
1389 return -1;
1390 }
1391
1392 /* Display the traceback */
1393 _PyErr_Display(file, exc_type, exc_value, exc_traceback);
1394
1395 /* Call file.flush() */
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001396 PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
Victor Stinnercd590a72019-05-28 00:39:52 +02001397 if (!res) {
1398 return -1;
1399 }
1400 Py_DECREF(res);
1401
1402 return 0;
1403}
1404
1405
1406PyDoc_STRVAR(ExceptHookArgs__doc__,
1407"ExceptHookArgs\n\
1408\n\
1409Type used to pass arguments to threading.excepthook.");
1410
1411static PyTypeObject ExceptHookArgsType;
1412
1413static PyStructSequence_Field ExceptHookArgs_fields[] = {
1414 {"exc_type", "Exception type"},
1415 {"exc_value", "Exception value"},
1416 {"exc_traceback", "Exception traceback"},
1417 {"thread", "Thread"},
1418 {0}
1419};
1420
1421static PyStructSequence_Desc ExceptHookArgs_desc = {
1422 .name = "_thread.ExceptHookArgs",
1423 .doc = ExceptHookArgs__doc__,
1424 .fields = ExceptHookArgs_fields,
1425 .n_in_sequence = 4
1426};
1427
1428
1429static PyObject *
1430thread_excepthook(PyObject *self, PyObject *args)
1431{
Andy Lester55728702020-03-06 16:53:17 -06001432 if (!Py_IS_TYPE(args, &ExceptHookArgsType)) {
Victor Stinnercd590a72019-05-28 00:39:52 +02001433 PyErr_SetString(PyExc_TypeError,
1434 "_thread.excepthook argument type "
1435 "must be ExceptHookArgs");
1436 return NULL;
1437 }
1438
1439 /* Borrowed reference */
1440 PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0);
1441 if (exc_type == PyExc_SystemExit) {
1442 /* silently ignore SystemExit */
1443 Py_RETURN_NONE;
1444 }
1445
1446 /* Borrowed references */
1447 PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1);
1448 PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
1449 PyObject *thread = PyStructSequence_GET_ITEM(args, 3);
1450
1451 PyObject *file = _PySys_GetObjectId(&PyId_stderr);
1452 if (file == NULL || file == Py_None) {
1453 if (thread == Py_None) {
1454 /* do nothing if sys.stderr is None and thread is None */
1455 Py_RETURN_NONE;
1456 }
1457
1458 file = PyObject_GetAttrString(thread, "_stderr");
1459 if (file == NULL) {
1460 return NULL;
1461 }
1462 if (file == Py_None) {
1463 Py_DECREF(file);
1464 /* do nothing if sys.stderr is None and sys.stderr was None
1465 when the thread was created */
1466 Py_RETURN_NONE;
1467 }
1468 }
1469 else {
1470 Py_INCREF(file);
1471 }
1472
1473 int res = thread_excepthook_file(file, exc_type, exc_value, exc_tb,
1474 thread);
1475 Py_DECREF(file);
1476 if (res < 0) {
1477 return NULL;
1478 }
1479
1480 Py_RETURN_NONE;
1481}
1482
1483PyDoc_STRVAR(excepthook_doc,
1484"excepthook(exc_type, exc_value, exc_traceback, thread)\n\
1485\n\
1486Handle uncaught Thread.run() exception.");
1487
Barry Warsawd0c10421996-12-17 00:05:22 +00001488static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001490 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001492 METH_VARARGS, start_new_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301493 {"allocate_lock", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301495 {"allocate", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301497 {"exit_thread", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301499 {"exit", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301501 {"interrupt_main", thread_PyThread_interrupt_main,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 METH_NOARGS, interrupt_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301503 {"get_ident", thread_get_ident,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 METH_NOARGS, get_ident_doc},
Jake Teslerb121f632019-05-22 08:43:17 -07001505#ifdef PY_HAVE_THREAD_NATIVE_ID
1506 {"get_native_id", thread_get_native_id,
1507 METH_NOARGS, get_native_id_doc},
1508#endif
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301509 {"_count", thread__count,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 METH_NOARGS, _count_doc},
1511 {"stack_size", (PyCFunction)thread_stack_size,
Victor Stinner754851f2011-04-19 23:58:51 +02001512 METH_VARARGS, stack_size_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301513 {"_set_sentinel", thread__set_sentinel,
Antoine Pitrou7b476992013-09-07 23:38:37 +02001514 METH_NOARGS, _set_sentinel_doc},
Victor Stinnercd590a72019-05-28 00:39:52 +02001515 {"_excepthook", thread_excepthook,
1516 METH_O, excepthook_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001518};
1519
1520
1521/* Initialization function */
1522
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001523PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001524"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001525The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001526
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001527PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001528"A lock object is a synchronization primitive. To create a lock,\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001529call threading.Lock(). Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001530\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001531acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1532release() -- unlock of the lock\n\
1533locked() -- test whether the lock is currently locked\n\
1534\n\
1535A lock is not owned by the thread that locked it; another thread may\n\
1536unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001537will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001538
Martin v. Löwis1a214512008-06-11 05:26:20 +00001539static struct PyModuleDef threadmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 PyModuleDef_HEAD_INIT,
1541 "_thread",
1542 thread_doc,
1543 -1,
1544 thread_methods,
1545 NULL,
1546 NULL,
1547 NULL,
1548 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001549};
1550
1551
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001552PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001553PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001554{
Victor Stinnerf5faad22015-03-28 03:52:05 +01001555 PyObject *m, *d, *v;
1556 double time_max;
1557 double timeout_max;
Victor Stinner81a7be32020-04-14 15:14:01 +02001558 PyInterpreterState *interp = _PyInterpreterState_GET();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 /* Initialize types: */
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001561 if (PyType_Ready(&localdummytype) < 0)
1562 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001563 if (PyType_Ready(&localtype) < 0)
1564 return NULL;
1565 if (PyType_Ready(&Locktype) < 0)
1566 return NULL;
1567 if (PyType_Ready(&RLocktype) < 0)
1568 return NULL;
Victor Stinnercd590a72019-05-28 00:39:52 +02001569 if (ExceptHookArgsType.tp_name == NULL) {
1570 if (PyStructSequence_InitType2(&ExceptHookArgsType,
1571 &ExceptHookArgs_desc) < 0) {
1572 return NULL;
1573 }
1574 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001575
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 /* Create the module and add the functions */
1577 m = PyModule_Create(&threadmodule);
1578 if (m == NULL)
1579 return NULL;
Antoine Pitrou7c3e5772010-04-14 15:44:10 +00001580
Victor Stinnerc319eee2017-11-30 23:03:47 +01001581 timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6;
Victor Stinner850a18e2017-10-24 16:53:32 -07001582 time_max = _PyTime_AsSecondsDouble(_PyTime_MAX);
Victor Stinnerf5faad22015-03-28 03:52:05 +01001583 timeout_max = Py_MIN(timeout_max, time_max);
Victor Stinner850a18e2017-10-24 16:53:32 -07001584 /* Round towards minus infinity */
1585 timeout_max = floor(timeout_max);
Victor Stinnerf5faad22015-03-28 03:52:05 +01001586
1587 v = PyFloat_FromDouble(timeout_max);
1588 if (!v)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 return NULL;
Victor Stinnerf5faad22015-03-28 03:52:05 +01001590 if (PyModule_AddObject(m, "TIMEOUT_MAX", v) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 /* Add a symbolic constant */
1594 d = PyModule_GetDict(m);
Antoine Pitroufcf81fd2011-02-28 22:03:34 +00001595 ThreadError = PyExc_RuntimeError;
1596 Py_INCREF(ThreadError);
Victor Stinner754851f2011-04-19 23:58:51 +02001597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598 PyDict_SetItemString(d, "error", ThreadError);
1599 Locktype.tp_doc = lock_doc;
1600 Py_INCREF(&Locktype);
1601 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Antoine Pitrou434736a2009-11-10 18:46:01 +00001602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 Py_INCREF(&RLocktype);
1604 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1605 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 Py_INCREF(&localtype);
1608 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1609 return NULL;
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001610
Victor Stinnercd590a72019-05-28 00:39:52 +02001611 Py_INCREF(&ExceptHookArgsType);
1612 if (PyModule_AddObject(m, "_ExceptHookArgs",
1613 (PyObject *)&ExceptHookArgsType) < 0)
1614 return NULL;
1615
Victor Stinnercaba55b2018-08-03 15:33:52 +02001616 interp->num_threads = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001617
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +00001618 str_dict = PyUnicode_InternFromString("__dict__");
1619 if (str_dict == NULL)
1620 return NULL;
1621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 /* Initialize the C thread library */
1623 PyThread_init_thread();
1624 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001625}