blob: 9853699771a7542a3cd1b49870dba175d9d3b843 [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 Stinner621cebe2018-11-12 16:53:38 +01008#include "pycore_pystate.h"
Guido van Rossum49b56061998-10-01 20:42:43 +00009#include "pythread.h"
Victor Stinner4a3fe082020-04-14 14:26:24 +020010#include <stddef.h> // offsetof()
Guido van Rossum1984f1e1992-08-04 12:41:02 +000011
Barry Warsawd0c10421996-12-17 00:05:22 +000012static PyObject *ThreadError;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +000013static PyObject *str_dict;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000014
Victor Stinnerbd303c12013-11-07 23:07:29 +010015_Py_IDENTIFIER(stderr);
Victor Stinnercd590a72019-05-28 00:39:52 +020016_Py_IDENTIFIER(flush);
Victor Stinnerbd303c12013-11-07 23:07:29 +010017
Guido van Rossum1984f1e1992-08-04 12:41:02 +000018/* Lock objects */
19
20typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000021 PyObject_HEAD
22 PyThread_type_lock lock_lock;
23 PyObject *in_weakreflist;
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000024 char locked; /* for sanity checking */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000025} lockobject;
26
Guido van Rossum1984f1e1992-08-04 12:41:02 +000027static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000028lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000029{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000030 if (self->in_weakreflist != NULL)
31 PyObject_ClearWeakRefs((PyObject *) self);
32 if (self->lock_lock != NULL) {
33 /* Unlock the lock so it's safe to free it */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000034 if (self->locked)
35 PyThread_release_lock(self->lock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000036 PyThread_free_lock(self->lock_lock);
37 }
38 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000039}
40
Antoine Pitrou810023d2010-12-15 22:59:16 +000041/* Helper to acquire an interruptible lock with a timeout. If the lock acquire
42 * is interrupted, signal handlers are run, and if they raise an exception,
43 * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE
Raymond Hettinger15f44ab2016-08-30 10:47:49 -070044 * are returned, depending on whether the lock can be acquired within the
Antoine Pitrou810023d2010-12-15 22:59:16 +000045 * timeout.
46 */
47static PyLockStatus
Victor Stinnerf5faad22015-03-28 03:52:05 +010048acquire_timed(PyThread_type_lock lock, _PyTime_t timeout)
Antoine Pitrou810023d2010-12-15 22:59:16 +000049{
50 PyLockStatus r;
Victor Stinnerf5faad22015-03-28 03:52:05 +010051 _PyTime_t endtime = 0;
52 _PyTime_t microseconds;
Antoine Pitrou810023d2010-12-15 22:59:16 +000053
Victor Stinnerf5faad22015-03-28 03:52:05 +010054 if (timeout > 0)
55 endtime = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrou810023d2010-12-15 22:59:16 +000056
57 do {
Victor Stinner869e1772015-03-30 03:49:14 +020058 microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING);
Victor Stinnerf5faad22015-03-28 03:52:05 +010059
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000060 /* first a simple non-blocking try without releasing the GIL */
61 r = PyThread_acquire_lock_timed(lock, 0, 0);
62 if (r == PY_LOCK_FAILURE && microseconds != 0) {
63 Py_BEGIN_ALLOW_THREADS
64 r = PyThread_acquire_lock_timed(lock, microseconds, 1);
65 Py_END_ALLOW_THREADS
Victor Stinner357f5152013-11-05 15:10:19 +010066 }
Antoine Pitrou810023d2010-12-15 22:59:16 +000067
68 if (r == PY_LOCK_INTR) {
69 /* Run signal handlers if we were interrupted. Propagate
70 * exceptions from signal handlers, such as KeyboardInterrupt, by
71 * passing up PY_LOCK_INTR. */
72 if (Py_MakePendingCalls() < 0) {
73 return PY_LOCK_INTR;
74 }
75
76 /* If we're using a timeout, recompute the timeout after processing
77 * signals, since those can take time. */
Victor Stinnerf5faad22015-03-28 03:52:05 +010078 if (timeout > 0) {
79 timeout = endtime - _PyTime_GetMonotonicClock();
Antoine Pitrou810023d2010-12-15 22:59:16 +000080
81 /* Check for negative values, since those mean block forever.
82 */
Victor Stinner6aa446c2015-03-30 21:33:51 +020083 if (timeout < 0) {
Antoine Pitrou810023d2010-12-15 22:59:16 +000084 r = PY_LOCK_FAILURE;
85 }
86 }
87 }
88 } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */
89
90 return r;
91}
92
Victor Stinnerf5faad22015-03-28 03:52:05 +010093static int
94lock_acquire_parse_args(PyObject *args, PyObject *kwds,
95 _PyTime_t *timeout)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000096{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000097 char *kwlist[] = {"blocking", "timeout", NULL};
98 int blocking = 1;
Victor Stinnerf5faad22015-03-28 03:52:05 +010099 PyObject *timeout_obj = NULL;
Victor Stinner13019fd2015-04-03 13:10:54 +0200100 const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000101
Victor Stinnerf5faad22015-03-28 03:52:05 +0100102 *timeout = unset_timeout ;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000103
Victor Stinnerf5faad22015-03-28 03:52:05 +0100104 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:acquire", kwlist,
105 &blocking, &timeout_obj))
106 return -1;
107
108 if (timeout_obj
Victor Stinner869e1772015-03-30 03:49:14 +0200109 && _PyTime_FromSecondsObject(timeout,
Pablo Galindo59af94f2017-10-18 08:13:09 +0100110 timeout_obj, _PyTime_ROUND_TIMEOUT) < 0)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100111 return -1;
112
113 if (!blocking && *timeout != unset_timeout ) {
114 PyErr_SetString(PyExc_ValueError,
115 "can't specify a timeout for a non-blocking call");
116 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100118 if (*timeout < 0 && *timeout != unset_timeout) {
119 PyErr_SetString(PyExc_ValueError,
120 "timeout value must be positive");
121 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000122 }
123 if (!blocking)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100124 *timeout = 0;
125 else if (*timeout != unset_timeout) {
126 _PyTime_t microseconds;
127
Pablo Galindo59af94f2017-10-18 08:13:09 +0100128 microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinnerf5faad22015-03-28 03:52:05 +0100129 if (microseconds >= PY_TIMEOUT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 PyErr_SetString(PyExc_OverflowError,
131 "timeout value is too large");
Victor Stinnerf5faad22015-03-28 03:52:05 +0100132 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000134 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100135 return 0;
136}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000137
Victor Stinnerf5faad22015-03-28 03:52:05 +0100138static PyObject *
139lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
140{
141 _PyTime_t timeout;
142 PyLockStatus r;
143
144 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
145 return NULL;
146
147 r = acquire_timed(self->lock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000148 if (r == PY_LOCK_INTR) {
149 return NULL;
150 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000152 if (r == PY_LOCK_ACQUIRED)
153 self->locked = 1;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000154 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000155}
156
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000157PyDoc_STRVAR(acquire_doc,
Berker Peksag720e6552016-05-02 12:25:35 +0300158"acquire(blocking=True, timeout=-1) -> bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000159(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000160\n\
161Lock the lock. Without argument, this blocks if the lock is already\n\
162locked (even by the same thread), waiting for another thread to release\n\
R David Murray95b71102013-02-04 10:15:58 -0500163the lock, and return True once the lock is acquired.\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000164With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000165and the return value reflects whether the lock is acquired.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000166The blocking operation is interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000167
Barry Warsawd0c10421996-12-17 00:05:22 +0000168static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530169lock_PyThread_release_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 /* Sanity check: the lock must be locked */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000172 if (!self->locked) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 PyErr_SetString(ThreadError, "release unlocked lock");
174 return NULL;
175 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 PyThread_release_lock(self->lock_lock);
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000178 self->locked = 0;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200179 Py_RETURN_NONE;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000180}
181
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000182PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000183"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000184(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000185\n\
186Release the lock, allowing another thread that is blocked waiting for\n\
187the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000188but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000189
Barry Warsawd0c10421996-12-17 00:05:22 +0000190static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530191lock_locked_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000192{
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000193 return PyBool_FromLong((long)self->locked);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000194}
195
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000196PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000197"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000198(locked_lock() is an obsolete synonym)\n\
199\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000200Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000201
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700202static PyObject *
203lock_repr(lockobject *self)
204{
205 return PyUnicode_FromFormat("<%s %s object at %p>",
206 self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
207}
208
Victor Stinner87255be2020-04-07 23:11:49 +0200209#ifdef HAVE_FORK
210static PyObject *
211lock__at_fork_reinit(lockobject *self, PyObject *Py_UNUSED(args))
212{
213 if (_PyThread_at_fork_reinit(&self->lock_lock) < 0) {
214 PyErr_SetString(ThreadError, "failed to reinitialize lock at fork");
215 return NULL;
216 }
217
218 self->locked = 0;
219
220 Py_RETURN_NONE;
221}
222#endif /* HAVE_FORK */
223
224
Barry Warsawd0c10421996-12-17 00:05:22 +0000225static PyMethodDef lock_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200226 {"acquire_lock", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 METH_VARARGS | METH_KEYWORDS, acquire_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200228 {"acquire", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 METH_VARARGS | METH_KEYWORDS, acquire_doc},
230 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
231 METH_NOARGS, release_doc},
232 {"release", (PyCFunction)lock_PyThread_release_lock,
233 METH_NOARGS, release_doc},
234 {"locked_lock", (PyCFunction)lock_locked_lock,
235 METH_NOARGS, locked_doc},
236 {"locked", (PyCFunction)lock_locked_lock,
237 METH_NOARGS, locked_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200238 {"__enter__", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 METH_VARARGS | METH_KEYWORDS, acquire_doc},
240 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
241 METH_VARARGS, release_doc},
Victor Stinner87255be2020-04-07 23:11:49 +0200242#ifdef HAVE_FORK
243 {"_at_fork_reinit", (PyCFunction)lock__at_fork_reinit,
244 METH_NOARGS, NULL},
245#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000247};
248
Barry Warsawd0c10421996-12-17 00:05:22 +0000249static PyTypeObject Locktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 PyVarObject_HEAD_INIT(&PyType_Type, 0)
251 "_thread.lock", /*tp_name*/
Peter Eisentraut0e0bc4e2018-09-10 18:46:08 +0200252 sizeof(lockobject), /*tp_basicsize*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 0, /*tp_itemsize*/
254 /* methods */
255 (destructor)lock_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200256 0, /*tp_vectorcall_offset*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 0, /*tp_getattr*/
258 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200259 0, /*tp_as_async*/
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700260 (reprfunc)lock_repr, /*tp_repr*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 0, /*tp_as_number*/
262 0, /*tp_as_sequence*/
263 0, /*tp_as_mapping*/
264 0, /*tp_hash*/
265 0, /*tp_call*/
266 0, /*tp_str*/
267 0, /*tp_getattro*/
268 0, /*tp_setattro*/
269 0, /*tp_as_buffer*/
270 Py_TPFLAGS_DEFAULT, /*tp_flags*/
271 0, /*tp_doc*/
272 0, /*tp_traverse*/
273 0, /*tp_clear*/
274 0, /*tp_richcompare*/
275 offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
276 0, /*tp_iter*/
277 0, /*tp_iternext*/
278 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000279};
280
Antoine Pitrou434736a2009-11-10 18:46:01 +0000281/* Recursive lock objects */
282
283typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 PyObject_HEAD
285 PyThread_type_lock rlock_lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200286 unsigned long rlock_owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 unsigned long rlock_count;
288 PyObject *in_weakreflist;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000289} rlockobject;
290
291static void
292rlock_dealloc(rlockobject *self)
293{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 if (self->in_weakreflist != NULL)
295 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner357f5152013-11-05 15:10:19 +0100296 /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed
297 in rlock_new() */
298 if (self->rlock_lock != NULL) {
299 /* Unlock the lock so it's safe to free it */
300 if (self->rlock_count > 0)
301 PyThread_release_lock(self->rlock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302
Victor Stinner357f5152013-11-05 15:10:19 +0100303 PyThread_free_lock(self->rlock_lock);
304 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 Py_TYPE(self)->tp_free(self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000306}
307
308static PyObject *
309rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
310{
Victor Stinnerf5faad22015-03-28 03:52:05 +0100311 _PyTime_t timeout;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200312 unsigned long tid;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000313 PyLockStatus r = PY_LOCK_ACQUIRED;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000314
Victor Stinnerf5faad22015-03-28 03:52:05 +0100315 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 tid = PyThread_get_thread_ident();
319 if (self->rlock_count > 0 && tid == self->rlock_owner) {
320 unsigned long count = self->rlock_count + 1;
321 if (count <= self->rlock_count) {
322 PyErr_SetString(PyExc_OverflowError,
323 "Internal lock count overflowed");
324 return NULL;
325 }
326 self->rlock_count = count;
327 Py_RETURN_TRUE;
328 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100329 r = acquire_timed(self->rlock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000330 if (r == PY_LOCK_ACQUIRED) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 assert(self->rlock_count == 0);
332 self->rlock_owner = tid;
333 self->rlock_count = 1;
334 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000335 else if (r == PY_LOCK_INTR) {
336 return NULL;
337 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338
Antoine Pitrou810023d2010-12-15 22:59:16 +0000339 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000340}
341
342PyDoc_STRVAR(rlock_acquire_doc,
343"acquire(blocking=True) -> bool\n\
344\n\
345Lock the lock. `blocking` indicates whether we should wait\n\
346for the lock to be available or not. If `blocking` is False\n\
347and another thread holds the lock, the method will return False\n\
348immediately. If `blocking` is True and another thread holds\n\
349the lock, the method will wait for the lock to be released,\n\
350take it and then return True.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000351(note: the blocking operation is interruptible.)\n\
Antoine Pitrou434736a2009-11-10 18:46:01 +0000352\n\
353In all other cases, the method will return True immediately.\n\
354Precisely, if the current thread already holds the lock, its\n\
355internal counter is simply incremented. If nobody holds the lock,\n\
356the lock is taken and its internal counter initialized to 1.");
357
358static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530359rlock_release(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000360{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200361 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrou434736a2009-11-10 18:46:01 +0000362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 if (self->rlock_count == 0 || self->rlock_owner != tid) {
364 PyErr_SetString(PyExc_RuntimeError,
365 "cannot release un-acquired lock");
366 return NULL;
367 }
368 if (--self->rlock_count == 0) {
369 self->rlock_owner = 0;
370 PyThread_release_lock(self->rlock_lock);
371 }
372 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000373}
374
375PyDoc_STRVAR(rlock_release_doc,
376"release()\n\
377\n\
378Release the lock, allowing another thread that is blocked waiting for\n\
379the lock to acquire the lock. The lock must be in the locked state,\n\
380and must be locked by the same thread that unlocks it; otherwise a\n\
381`RuntimeError` is raised.\n\
382\n\
383Do note that if the lock was acquire()d several times in a row by the\n\
384current thread, release() needs to be called as many times for the lock\n\
385to be available for other threads.");
386
387static PyObject *
Victor Stinnere8794522014-01-02 12:47:24 +0100388rlock_acquire_restore(rlockobject *self, PyObject *args)
Antoine Pitrou434736a2009-11-10 18:46:01 +0000389{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200390 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 unsigned long count;
392 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000393
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200394 if (!PyArg_ParseTuple(args, "(kk):_acquire_restore", &count, &owner))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
398 Py_BEGIN_ALLOW_THREADS
399 r = PyThread_acquire_lock(self->rlock_lock, 1);
400 Py_END_ALLOW_THREADS
401 }
402 if (!r) {
403 PyErr_SetString(ThreadError, "couldn't acquire lock");
404 return NULL;
405 }
406 assert(self->rlock_count == 0);
407 self->rlock_owner = owner;
408 self->rlock_count = count;
409 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000410}
411
412PyDoc_STRVAR(rlock_acquire_restore_doc,
413"_acquire_restore(state) -> None\n\
414\n\
415For internal use by `threading.Condition`.");
416
417static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530418rlock_release_save(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000419{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200420 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 unsigned long count;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000422
Victor Stinnerc2824d42011-04-24 23:41:33 +0200423 if (self->rlock_count == 0) {
424 PyErr_SetString(PyExc_RuntimeError,
425 "cannot release un-acquired lock");
426 return NULL;
427 }
428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 owner = self->rlock_owner;
430 count = self->rlock_count;
431 self->rlock_count = 0;
432 self->rlock_owner = 0;
433 PyThread_release_lock(self->rlock_lock);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200434 return Py_BuildValue("kk", count, owner);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000435}
436
437PyDoc_STRVAR(rlock_release_save_doc,
438"_release_save() -> tuple\n\
439\n\
440For internal use by `threading.Condition`.");
441
442
443static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530444rlock_is_owned(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000445{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200446 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447
448 if (self->rlock_count > 0 && self->rlock_owner == tid) {
449 Py_RETURN_TRUE;
450 }
451 Py_RETURN_FALSE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000452}
453
454PyDoc_STRVAR(rlock_is_owned_doc,
455"_is_owned() -> bool\n\
456\n\
457For internal use by `threading.Condition`.");
458
459static PyObject *
460rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
461{
Victor Stinner87255be2020-04-07 23:11:49 +0200462 rlockobject *self = (rlockobject *) type->tp_alloc(type, 0);
463 if (self == NULL) {
464 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 }
Victor Stinner87255be2020-04-07 23:11:49 +0200466 self->in_weakreflist = NULL;
467 self->rlock_owner = 0;
468 self->rlock_count = 0;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000469
Victor Stinner87255be2020-04-07 23:11:49 +0200470 self->rlock_lock = PyThread_allocate_lock();
471 if (self->rlock_lock == NULL) {
472 Py_DECREF(self);
473 PyErr_SetString(ThreadError, "can't allocate lock");
474 return NULL;
475 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 return (PyObject *) self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000477}
478
479static PyObject *
480rlock_repr(rlockobject *self)
481{
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700482 return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>",
483 self->rlock_count ? "locked" : "unlocked",
484 Py_TYPE(self)->tp_name, self->rlock_owner,
485 self->rlock_count, self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000486}
487
488
Victor Stinner87255be2020-04-07 23:11:49 +0200489#ifdef HAVE_FORK
490static PyObject *
491rlock__at_fork_reinit(rlockobject *self, PyObject *Py_UNUSED(args))
492{
493 if (_PyThread_at_fork_reinit(&self->rlock_lock) < 0) {
494 PyErr_SetString(ThreadError, "failed to reinitialize lock at fork");
495 return NULL;
496 }
497
498 self->rlock_owner = 0;
499 self->rlock_count = 0;
500
501 Py_RETURN_NONE;
502}
503#endif /* HAVE_FORK */
504
505
Antoine Pitrou434736a2009-11-10 18:46:01 +0000506static PyMethodDef rlock_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200507 {"acquire", (PyCFunction)(void(*)(void))rlock_acquire,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
509 {"release", (PyCFunction)rlock_release,
510 METH_NOARGS, rlock_release_doc},
511 {"_is_owned", (PyCFunction)rlock_is_owned,
512 METH_NOARGS, rlock_is_owned_doc},
513 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
Victor Stinnere8794522014-01-02 12:47:24 +0100514 METH_VARARGS, rlock_acquire_restore_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 {"_release_save", (PyCFunction)rlock_release_save,
516 METH_NOARGS, rlock_release_save_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200517 {"__enter__", (PyCFunction)(void(*)(void))rlock_acquire,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
519 {"__exit__", (PyCFunction)rlock_release,
520 METH_VARARGS, rlock_release_doc},
Victor Stinner87255be2020-04-07 23:11:49 +0200521#ifdef HAVE_FORK
522 {"_at_fork_reinit", (PyCFunction)rlock__at_fork_reinit,
523 METH_NOARGS, NULL},
524#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000525 {NULL, NULL} /* sentinel */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000526};
527
528
529static PyTypeObject RLocktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 PyVarObject_HEAD_INIT(&PyType_Type, 0)
531 "_thread.RLock", /*tp_name*/
Peter Eisentraut0e0bc4e2018-09-10 18:46:08 +0200532 sizeof(rlockobject), /*tp_basicsize*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 0, /*tp_itemsize*/
534 /* methods */
535 (destructor)rlock_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200536 0, /*tp_vectorcall_offset*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 0, /*tp_getattr*/
538 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200539 0, /*tp_as_async*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 (reprfunc)rlock_repr, /*tp_repr*/
541 0, /*tp_as_number*/
542 0, /*tp_as_sequence*/
543 0, /*tp_as_mapping*/
544 0, /*tp_hash*/
545 0, /*tp_call*/
546 0, /*tp_str*/
547 0, /*tp_getattro*/
548 0, /*tp_setattro*/
549 0, /*tp_as_buffer*/
550 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
551 0, /*tp_doc*/
552 0, /*tp_traverse*/
553 0, /*tp_clear*/
554 0, /*tp_richcompare*/
555 offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
556 0, /*tp_iter*/
557 0, /*tp_iternext*/
558 rlock_methods, /*tp_methods*/
559 0, /* tp_members */
560 0, /* tp_getset */
561 0, /* tp_base */
562 0, /* tp_dict */
563 0, /* tp_descr_get */
564 0, /* tp_descr_set */
565 0, /* tp_dictoffset */
566 0, /* tp_init */
567 PyType_GenericAlloc, /* tp_alloc */
568 rlock_new /* tp_new */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000569};
570
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000571static lockobject *
572newlockobject(void)
573{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 lockobject *self;
575 self = PyObject_New(lockobject, &Locktype);
576 if (self == NULL)
577 return NULL;
578 self->lock_lock = PyThread_allocate_lock();
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000579 self->locked = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580 self->in_weakreflist = NULL;
581 if (self->lock_lock == NULL) {
582 Py_DECREF(self);
583 PyErr_SetString(ThreadError, "can't allocate lock");
584 return NULL;
585 }
586 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000587}
588
Jim Fultond15dc062004-07-14 19:11:50 +0000589/* Thread-local objects */
590
591#include "structmember.h"
592
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000593/* Quick overview:
594
595 We need to be able to reclaim reference cycles as soon as possible
596 (both when a thread is being terminated, or a thread-local object
597 becomes unreachable from user data). Constraints:
598 - it must not be possible for thread-state dicts to be involved in
599 reference cycles (otherwise the cyclic GC will refuse to consider
600 objects referenced from a reachable thread-state dict, even though
601 local_dealloc would clear them)
602 - the death of a thread-state dict must still imply destruction of the
603 corresponding local dicts in all thread-local objects.
604
605 Our implementation uses small "localdummy" objects in order to break
606 the reference chain. These trivial objects are hashable (using the
607 default scheme of identity hashing) and weakrefable.
608 Each thread-state holds a separate localdummy for each local object
609 (as a /strong reference/),
610 and each thread-local object holds a dict mapping /weak references/
611 of localdummies to local dicts.
612
613 Therefore:
614 - only the thread-state dict holds a strong reference to the dummies
615 - only the thread-local object holds a strong reference to the local dicts
616 - only outside objects (application- or library-level) hold strong
617 references to the thread-local objects
618 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
619 dummies attached to that thread are called, and destroy the corresponding
620 local dicts from thread-local objects
621 - as soon as a thread-local object is destroyed, its local dicts are
622 destroyed and its dummies are manually removed from all thread states
623 - the GC can do its work correctly when a thread-local object is dangling,
624 without any interference from the thread-state dicts
625
626 As an additional optimization, each localdummy holds a borrowed reference
627 to the corresponding localdict. This borrowed reference is only used
628 by the thread-local object which has created the localdummy, which should
629 guarantee that the localdict still exists when accessed.
630*/
631
632typedef struct {
633 PyObject_HEAD
634 PyObject *localdict; /* Borrowed reference! */
635 PyObject *weakreflist; /* List of weak references to self */
636} localdummyobject;
637
638static void
639localdummy_dealloc(localdummyobject *self)
640{
641 if (self->weakreflist != NULL)
642 PyObject_ClearWeakRefs((PyObject *) self);
643 Py_TYPE(self)->tp_free((PyObject*)self);
644}
645
646static PyTypeObject localdummytype = {
647 PyVarObject_HEAD_INIT(NULL, 0)
648 /* tp_name */ "_thread._localdummy",
649 /* tp_basicsize */ sizeof(localdummyobject),
650 /* tp_itemsize */ 0,
651 /* tp_dealloc */ (destructor)localdummy_dealloc,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200652 /* tp_vectorcall_offset */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000653 /* tp_getattr */ 0,
654 /* tp_setattr */ 0,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200655 /* tp_as_async */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000656 /* tp_repr */ 0,
657 /* tp_as_number */ 0,
658 /* tp_as_sequence */ 0,
659 /* tp_as_mapping */ 0,
660 /* tp_hash */ 0,
661 /* tp_call */ 0,
662 /* tp_str */ 0,
663 /* tp_getattro */ 0,
664 /* tp_setattro */ 0,
665 /* tp_as_buffer */ 0,
666 /* tp_flags */ Py_TPFLAGS_DEFAULT,
667 /* tp_doc */ "Thread-local dummy",
668 /* tp_traverse */ 0,
669 /* tp_clear */ 0,
670 /* tp_richcompare */ 0,
671 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
672};
673
674
Jim Fultond15dc062004-07-14 19:11:50 +0000675typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 PyObject_HEAD
677 PyObject *key;
678 PyObject *args;
679 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000680 PyObject *weakreflist; /* List of weak references to self */
681 /* A {localdummy weakref -> localdict} dict */
682 PyObject *dummies;
683 /* The callback for weakrefs to localdummies */
684 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000685} localobject;
686
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000687/* Forward declaration */
688static PyObject *_ldict(localobject *self);
689static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
690
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000691/* Create and register the dummy for the current thread.
692 Returns a borrowed reference of the corresponding local dict */
693static PyObject *
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000694_local_create_dummy(localobject *self)
695{
696 PyObject *tdict, *ldict = NULL, *wr = NULL;
697 localdummyobject *dummy = NULL;
698 int r;
699
700 tdict = PyThreadState_GetDict();
701 if (tdict == NULL) {
702 PyErr_SetString(PyExc_SystemError,
703 "Couldn't get thread-state dictionary");
704 goto err;
705 }
706
707 ldict = PyDict_New();
708 if (ldict == NULL)
709 goto err;
710 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
711 if (dummy == NULL)
712 goto err;
713 dummy->localdict = ldict;
714 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
715 if (wr == NULL)
716 goto err;
717
718 /* As a side-effect, this will cache the weakref's hash before the
719 dummy gets deleted */
720 r = PyDict_SetItem(self->dummies, wr, ldict);
721 if (r < 0)
722 goto err;
723 Py_CLEAR(wr);
724 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
725 if (r < 0)
726 goto err;
727 Py_CLEAR(dummy);
728
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000729 Py_DECREF(ldict);
730 return ldict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000731
732err:
733 Py_XDECREF(ldict);
734 Py_XDECREF(wr);
735 Py_XDECREF(dummy);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000736 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000737}
738
Jim Fultond15dc062004-07-14 19:11:50 +0000739static PyObject *
740local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
741{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 localobject *self;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000743 PyObject *wr;
744 static PyMethodDef wr_callback_def = {
745 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
746 };
Jim Fultond15dc062004-07-14 19:11:50 +0000747
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300748 if (type->tp_init == PyBaseObject_Type.tp_init) {
749 int rc = 0;
750 if (args != NULL)
751 rc = PyObject_IsTrue(args);
752 if (rc == 0 && kw != NULL)
753 rc = PyObject_IsTrue(kw);
754 if (rc != 0) {
755 if (rc > 0)
756 PyErr_SetString(PyExc_TypeError,
757 "Initialization arguments are not supported");
758 return NULL;
759 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000760 }
Jim Fultond15dc062004-07-14 19:11:50 +0000761
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 self = (localobject *)type->tp_alloc(type, 0);
763 if (self == NULL)
764 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000765
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000766 Py_XINCREF(args);
767 self->args = args;
768 Py_XINCREF(kw);
769 self->kw = kw;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000770 self->key = PyUnicode_FromFormat("thread.local.%p", self);
771 if (self->key == NULL)
772 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000773
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000774 self->dummies = PyDict_New();
775 if (self->dummies == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000777
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000778 /* We use a weak reference to self in the callback closure
779 in order to avoid spurious reference cycles */
780 wr = PyWeakref_NewRef((PyObject *) self, NULL);
781 if (wr == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000782 goto err;
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200783 self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000784 Py_DECREF(wr);
785 if (self->wr_callback == NULL)
786 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000787
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000788 if (_local_create_dummy(self) == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000789 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000791 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000792
793 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000794 Py_DECREF(self);
795 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000796}
797
798static int
799local_traverse(localobject *self, visitproc visit, void *arg)
800{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 Py_VISIT(self->args);
802 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000803 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000804 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000805}
806
807static int
808local_clear(localobject *self)
809{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000810 PyThreadState *tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000811 Py_CLEAR(self->args);
812 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000813 Py_CLEAR(self->dummies);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000814 Py_CLEAR(self->wr_callback);
815 /* Remove all strong references to dummies from the thread states */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000816 if (self->key
817 && (tstate = PyThreadState_Get())
818 && tstate->interp) {
819 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
820 tstate;
821 tstate = PyThreadState_Next(tstate))
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200822 if (tstate->dict && PyDict_GetItem(tstate->dict, self->key)) {
823 if (PyDict_DelItem(tstate->dict, self->key)) {
824 PyErr_Clear();
825 }
826 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000827 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000828 return 0;
829}
Jim Fultond15dc062004-07-14 19:11:50 +0000830
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000831static void
832local_dealloc(localobject *self)
833{
834 /* Weakrefs must be invalidated right now, otherwise they can be used
835 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
836 if (self->weakreflist != NULL)
837 PyObject_ClearWeakRefs((PyObject *) self);
838
839 PyObject_GC_UnTrack(self);
840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000842 Py_XDECREF(self->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000843 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000844}
845
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000846/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000847static PyObject *
848_ldict(localobject *self)
849{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000850 PyObject *tdict, *ldict, *dummy;
Jim Fultond15dc062004-07-14 19:11:50 +0000851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000852 tdict = PyThreadState_GetDict();
853 if (tdict == NULL) {
854 PyErr_SetString(PyExc_SystemError,
855 "Couldn't get thread-state dictionary");
856 return NULL;
857 }
Jim Fultond15dc062004-07-14 19:11:50 +0000858
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200859 dummy = PyDict_GetItemWithError(tdict, self->key);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000860 if (dummy == NULL) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200861 if (PyErr_Occurred()) {
862 return NULL;
863 }
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000864 ldict = _local_create_dummy(self);
865 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000866 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
869 Py_TYPE(self)->tp_init((PyObject*)self,
870 self->args, self->kw) < 0) {
871 /* we need to get rid of ldict from thread so
872 we create a new one the next time we do an attr
Ezio Melotti42da6632011-03-15 05:18:48 +0200873 access */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000874 PyDict_DelItem(tdict, self->key);
875 return NULL;
876 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000877 }
878 else {
Andy Lesterdffe4c02020-03-04 07:15:20 -0600879 assert(Py_IS_TYPE(dummy, &localdummytype));
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000880 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000881 }
Jim Fultond15dc062004-07-14 19:11:50 +0000882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000883 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000884}
885
Jim Fultond15dc062004-07-14 19:11:50 +0000886static int
887local_setattro(localobject *self, PyObject *name, PyObject *v)
888{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 PyObject *ldict;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000890 int r;
Jim Fultond15dc062004-07-14 19:11:50 +0000891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 ldict = _ldict(self);
893 if (ldict == NULL)
894 return -1;
895
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000896 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
897 if (r == 1) {
898 PyErr_Format(PyExc_AttributeError,
899 "'%.50s' object attribute '%U' is read-only",
900 Py_TYPE(self)->tp_name, name);
901 return -1;
902 }
903 if (r == -1)
904 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000905
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000906 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000907}
908
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000909static PyObject *local_getattro(localobject *, PyObject *);
910
Jim Fultond15dc062004-07-14 19:11:50 +0000911static PyTypeObject localtype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 PyVarObject_HEAD_INIT(NULL, 0)
913 /* tp_name */ "_thread._local",
914 /* tp_basicsize */ sizeof(localobject),
915 /* tp_itemsize */ 0,
916 /* tp_dealloc */ (destructor)local_dealloc,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200917 /* tp_vectorcall_offset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000918 /* tp_getattr */ 0,
919 /* tp_setattr */ 0,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200920 /* tp_as_async */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 /* tp_repr */ 0,
922 /* tp_as_number */ 0,
923 /* tp_as_sequence */ 0,
924 /* tp_as_mapping */ 0,
925 /* tp_hash */ 0,
926 /* tp_call */ 0,
927 /* tp_str */ 0,
928 /* tp_getattro */ (getattrofunc)local_getattro,
929 /* tp_setattro */ (setattrofunc)local_setattro,
930 /* tp_as_buffer */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000931 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
932 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 /* tp_doc */ "Thread-local data",
934 /* tp_traverse */ (traverseproc)local_traverse,
935 /* tp_clear */ (inquiry)local_clear,
936 /* tp_richcompare */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000937 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 /* tp_iter */ 0,
939 /* tp_iternext */ 0,
940 /* tp_methods */ 0,
941 /* tp_members */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000942 /* tp_getset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 /* tp_base */ 0,
944 /* tp_dict */ 0, /* internal use */
945 /* tp_descr_get */ 0,
946 /* tp_descr_set */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000947 /* tp_dictoffset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 /* tp_init */ 0,
949 /* tp_alloc */ 0,
950 /* tp_new */ local_new,
951 /* tp_free */ 0, /* Low-level free-mem routine */
952 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000953};
954
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000955static PyObject *
956local_getattro(localobject *self, PyObject *name)
957{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 PyObject *ldict, *value;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000959 int r;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 ldict = _ldict(self);
962 if (ldict == NULL)
963 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000964
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000965 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
966 if (r == 1) {
967 Py_INCREF(ldict);
968 return ldict;
969 }
970 if (r == -1)
971 return NULL;
972
Andy Lester55728702020-03-06 16:53:17 -0600973 if (!Py_IS_TYPE(self, &localtype))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 /* use generic lookup for subtypes */
INADA Naoki378edee2018-01-16 20:52:41 +0900975 return _PyObject_GenericGetAttrWithDict(
976 (PyObject *)self, name, ldict, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 /* Optimization: just look in dict ourselves */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200979 value = PyDict_GetItemWithError(ldict, name);
980 if (value != NULL) {
981 Py_INCREF(value);
982 return value;
983 }
984 else if (PyErr_Occurred()) {
985 return NULL;
986 }
987 /* Fall back on generic to get __class__ and __dict__ */
988 return _PyObject_GenericGetAttrWithDict(
989 (PyObject *)self, name, ldict, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000990}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000991
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000992/* Called when a dummy is destroyed. */
993static PyObject *
994_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
995{
996 PyObject *obj;
997 localobject *self;
998 assert(PyWeakref_CheckRef(localweakref));
999 obj = PyWeakref_GET_OBJECT(localweakref);
1000 if (obj == Py_None)
1001 Py_RETURN_NONE;
1002 Py_INCREF(obj);
1003 assert(PyObject_TypeCheck(obj, &localtype));
1004 /* If the thread-local object is still alive and not being cleared,
1005 remove the corresponding local dict */
1006 self = (localobject *) obj;
1007 if (self->dummies != NULL) {
1008 PyObject *ldict;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001009 ldict = PyDict_GetItemWithError(self->dummies, dummyweakref);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001010 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001011 PyDict_DelItem(self->dummies, dummyweakref);
1012 }
1013 if (PyErr_Occurred())
1014 PyErr_WriteUnraisable(obj);
1015 }
1016 Py_DECREF(obj);
1017 Py_RETURN_NONE;
1018}
1019
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001020/* Module functions */
1021
Guido van Rossuma027efa1997-05-05 20:56:21 +00001022struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 PyInterpreterState *interp;
1024 PyObject *func;
1025 PyObject *args;
1026 PyObject *keyw;
1027 PyThreadState *tstate;
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001028 _PyRuntimeState *runtime;
Guido van Rossuma027efa1997-05-05 20:56:21 +00001029};
1030
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001031static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001032t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 struct bootstate *boot = (struct bootstate *) boot_raw;
1035 PyThreadState *tstate;
1036 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 tstate = boot->tstate;
1039 tstate->thread_id = PyThread_get_thread_ident();
Victor Stinner01b1cc12019-11-20 02:27:56 +01001040 _PyThreadState_Init(tstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 PyEval_AcquireThread(tstate);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001042 tstate->interp->num_threads++;
INADA Naoki72dccde2017-02-16 09:26:01 +09001043 res = PyObject_Call(boot->func, boot->args, boot->keyw);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 if (res == NULL) {
1045 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Victor Stinner8b095002019-05-29 02:57:56 +02001046 /* SystemExit is ignored silently */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 PyErr_Clear();
1048 else {
Victor Stinner8b095002019-05-29 02:57:56 +02001049 _PyErr_WriteUnraisableMsg("in thread started by", boot->func);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001050 }
1051 }
Victor Stinner8b095002019-05-29 02:57:56 +02001052 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 Py_DECREF(res);
Victor Stinner8b095002019-05-29 02:57:56 +02001054 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 Py_DECREF(boot->func);
1056 Py_DECREF(boot->args);
1057 Py_XDECREF(boot->keyw);
1058 PyMem_DEL(boot_raw);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001059 tstate->interp->num_threads--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 PyThreadState_Clear(tstate);
Victor Stinner23ef89d2020-03-18 02:26:04 +01001061 _PyThreadState_DeleteCurrent(tstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001063}
1064
Barry Warsawd0c10421996-12-17 00:05:22 +00001065static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001066thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001067{
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001068 _PyRuntimeState *runtime = &_PyRuntime;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 PyObject *func, *args, *keyw = NULL;
1070 struct bootstate *boot;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001071 unsigned long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
1074 &func, &args, &keyw))
1075 return NULL;
1076 if (!PyCallable_Check(func)) {
1077 PyErr_SetString(PyExc_TypeError,
1078 "first arg must be callable");
1079 return NULL;
1080 }
1081 if (!PyTuple_Check(args)) {
1082 PyErr_SetString(PyExc_TypeError,
1083 "2nd arg must be a tuple");
1084 return NULL;
1085 }
1086 if (keyw != NULL && !PyDict_Check(keyw)) {
1087 PyErr_SetString(PyExc_TypeError,
1088 "optional 3rd arg must be a dictionary");
1089 return NULL;
1090 }
1091 boot = PyMem_NEW(struct bootstate, 1);
1092 if (boot == NULL)
1093 return PyErr_NoMemory();
Victor Stinnerff4584c2020-03-13 18:03:56 +01001094 boot->interp = _PyInterpreterState_GET_UNSAFE();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 boot->func = func;
1096 boot->args = args;
1097 boot->keyw = keyw;
1098 boot->tstate = _PyThreadState_Prealloc(boot->interp);
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001099 boot->runtime = runtime;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 if (boot->tstate == NULL) {
1101 PyMem_DEL(boot);
1102 return PyErr_NoMemory();
1103 }
1104 Py_INCREF(func);
1105 Py_INCREF(args);
1106 Py_XINCREF(keyw);
Victor Stinner3225b9f2020-03-09 20:56:57 +01001107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001108 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001109 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001110 PyErr_SetString(ThreadError, "can't start new thread");
1111 Py_DECREF(func);
1112 Py_DECREF(args);
1113 Py_XDECREF(keyw);
1114 PyThreadState_Clear(boot->tstate);
1115 PyMem_DEL(boot);
1116 return NULL;
1117 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001118 return PyLong_FromUnsignedLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001119}
1120
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001121PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001122"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001123(start_new() is an obsolete synonym)\n\
1124\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001125Start a new thread and return its identifier. The thread will call the\n\
1126function with positional arguments from the tuple args and keyword arguments\n\
1127taken from the optional dictionary kwargs. The thread exits when the\n\
1128function returns; the return value is ignored. The thread will also exit\n\
1129when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001130printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001131
Barry Warsawd0c10421996-12-17 00:05:22 +00001132static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301133thread_PyThread_exit_thread(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 PyErr_SetNone(PyExc_SystemExit);
1136 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001137}
1138
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001139PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001140"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001141(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001142\n\
1143This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001144thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001145
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001146static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301147thread_PyThread_interrupt_main(PyObject * self, PyObject *Py_UNUSED(ignored))
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 PyErr_SetInterrupt();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001150 Py_RETURN_NONE;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001151}
1152
1153PyDoc_STRVAR(interrupt_doc,
1154"interrupt_main()\n\
1155\n\
1156Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001157A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001158);
1159
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001160static lockobject *newlockobject(void);
1161
Barry Warsawd0c10421996-12-17 00:05:22 +00001162static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301163thread_PyThread_allocate_lock(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001166}
1167
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001168PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001169"allocate_lock() -> lock object\n\
1170(allocate() is an obsolete synonym)\n\
1171\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001172Create a new lock object. See help(type(threading.Lock())) for\n\
1173information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001174
Barry Warsawd0c10421996-12-17 00:05:22 +00001175static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301176thread_get_ident(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001177{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001178 unsigned long ident = PyThread_get_thread_ident();
1179 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 PyErr_SetString(ThreadError, "no current thread ident");
1181 return NULL;
1182 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001183 return PyLong_FromUnsignedLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001184}
1185
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001186PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001187"get_ident() -> integer\n\
1188\n\
1189Return a non-zero integer that uniquely identifies the current thread\n\
1190amongst other threads that exist simultaneously.\n\
1191This may be used to identify per-thread resources.\n\
1192Even though on some platforms threads identities may appear to be\n\
1193allocated consecutive numbers starting at 1, this behavior should not\n\
1194be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001195A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001196
Jake Teslerb121f632019-05-22 08:43:17 -07001197#ifdef PY_HAVE_THREAD_NATIVE_ID
1198static PyObject *
1199thread_get_native_id(PyObject *self, PyObject *Py_UNUSED(ignored))
1200{
1201 unsigned long native_id = PyThread_get_thread_native_id();
1202 return PyLong_FromUnsignedLong(native_id);
1203}
1204
1205PyDoc_STRVAR(get_native_id_doc,
1206"get_native_id() -> integer\n\
1207\n\
1208Return a non-negative integer identifying the thread as reported\n\
1209by the OS (kernel). This may be used to uniquely identify a\n\
1210particular thread within a system.");
1211#endif
1212
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001213static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301214thread__count(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001215{
Victor Stinnerff4584c2020-03-13 18:03:56 +01001216 PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
Victor Stinnercaba55b2018-08-03 15:33:52 +02001217 return PyLong_FromLong(interp->num_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001218}
1219
1220PyDoc_STRVAR(_count_doc,
1221"_count() -> integer\n\
1222\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001223\
oldkaa0735f2018-02-02 16:52:55 +08001224Return the number of currently running Python threads, excluding\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001225the main thread. The returned number comprises all threads created\n\
1226through `start_new_thread()` as well as `threading.Thread`, and not\n\
1227yet finished.\n\
1228\n\
1229This function is meant for internal and specialized purposes only.\n\
1230In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001231
Antoine Pitrou7b476992013-09-07 23:38:37 +02001232static void
Victor Stinnera42de742018-11-22 10:25:22 +01001233release_sentinel(void *wr_raw)
Antoine Pitrou7b476992013-09-07 23:38:37 +02001234{
Victor Stinnera42de742018-11-22 10:25:22 +01001235 PyObject *wr = _PyObject_CAST(wr_raw);
Antoine Pitrou7b476992013-09-07 23:38:37 +02001236 /* Tricky: this function is called when the current thread state
1237 is being deleted. Therefore, only simple C code can safely
1238 execute here. */
1239 PyObject *obj = PyWeakref_GET_OBJECT(wr);
1240 lockobject *lock;
1241 if (obj != Py_None) {
Andy Lesterdffe4c02020-03-04 07:15:20 -06001242 assert(Py_IS_TYPE(obj, &Locktype));
Antoine Pitrou7b476992013-09-07 23:38:37 +02001243 lock = (lockobject *) obj;
1244 if (lock->locked) {
1245 PyThread_release_lock(lock->lock_lock);
1246 lock->locked = 0;
1247 }
1248 }
1249 /* Deallocating a weakref with a NULL callback only calls
1250 PyObject_GC_Del(), which can't call any Python code. */
1251 Py_DECREF(wr);
1252}
1253
1254static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301255thread__set_sentinel(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou7b476992013-09-07 23:38:37 +02001256{
1257 PyObject *wr;
1258 PyThreadState *tstate = PyThreadState_Get();
1259 lockobject *lock;
1260
1261 if (tstate->on_delete_data != NULL) {
1262 /* We must support the re-creation of the lock from a
1263 fork()ed child. */
1264 assert(tstate->on_delete == &release_sentinel);
1265 wr = (PyObject *) tstate->on_delete_data;
1266 tstate->on_delete = NULL;
1267 tstate->on_delete_data = NULL;
1268 Py_DECREF(wr);
1269 }
1270 lock = newlockobject();
1271 if (lock == NULL)
1272 return NULL;
1273 /* The lock is owned by whoever called _set_sentinel(), but the weakref
1274 hangs to the thread state. */
1275 wr = PyWeakref_NewRef((PyObject *) lock, NULL);
1276 if (wr == NULL) {
1277 Py_DECREF(lock);
1278 return NULL;
1279 }
1280 tstate->on_delete_data = (void *) wr;
1281 tstate->on_delete = &release_sentinel;
1282 return (PyObject *) lock;
1283}
1284
1285PyDoc_STRVAR(_set_sentinel_doc,
1286"_set_sentinel() -> lock\n\
1287\n\
1288Set a sentinel lock that will be released when the current thread\n\
1289state is finalized (after it is untied from the interpreter).\n\
1290\n\
1291This is a private API for the threading module.");
1292
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001293static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001294thread_stack_size(PyObject *self, PyObject *args)
1295{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 size_t old_size;
1297 Py_ssize_t new_size = 0;
1298 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1301 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 if (new_size < 0) {
1304 PyErr_SetString(PyExc_ValueError,
1305 "size must be 0 or a positive value");
1306 return NULL;
1307 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 rc = PyThread_set_stacksize((size_t) new_size);
1312 if (rc == -1) {
1313 PyErr_Format(PyExc_ValueError,
1314 "size not valid: %zd bytes",
1315 new_size);
1316 return NULL;
1317 }
1318 if (rc == -2) {
1319 PyErr_SetString(ThreadError,
1320 "setting stack size not supported");
1321 return NULL;
1322 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001325}
1326
1327PyDoc_STRVAR(stack_size_doc,
1328"stack_size([size]) -> size\n\
1329\n\
1330Return the thread stack size used when creating new threads. The\n\
1331optional size argument specifies the stack size (in bytes) to be used\n\
1332for subsequently created threads, and must be 0 (use platform or\n\
1333configured default) or a positive integer value of at least 32,768 (32k).\n\
1334If changing the thread stack size is unsupported, a ThreadError\n\
1335exception is raised. If the specified size is invalid, a ValueError\n\
1336exception is raised, and the stack size is unmodified. 32k bytes\n\
1337 currently the minimum supported stack size value to guarantee\n\
1338sufficient stack space for the interpreter itself.\n\
1339\n\
1340Note that some platforms may have particular restrictions on values for\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001341the stack size, such as requiring a minimum stack size larger than 32 KiB or\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001342requiring allocation in multiples of the system memory page size\n\
1343- platform documentation should be referred to for more information\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001344(4 KiB pages are common; using multiples of 4096 for the stack size is\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001345the suggested approach in the absence of more specific information).");
1346
Victor Stinnercd590a72019-05-28 00:39:52 +02001347static int
1348thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value,
1349 PyObject *exc_traceback, PyObject *thread)
1350{
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001351 _Py_IDENTIFIER(name);
Victor Stinnercd590a72019-05-28 00:39:52 +02001352 /* print(f"Exception in thread {thread.name}:", file=file) */
1353 if (PyFile_WriteString("Exception in thread ", file) < 0) {
1354 return -1;
1355 }
1356
1357 PyObject *name = NULL;
1358 if (thread != Py_None) {
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001359 if (_PyObject_LookupAttrId(thread, &PyId_name, &name) < 0) {
1360 return -1;
1361 }
Victor Stinnercd590a72019-05-28 00:39:52 +02001362 }
1363 if (name != NULL) {
1364 if (PyFile_WriteObject(name, file, Py_PRINT_RAW) < 0) {
1365 Py_DECREF(name);
1366 return -1;
1367 }
1368 Py_DECREF(name);
1369 }
1370 else {
Victor Stinnercd590a72019-05-28 00:39:52 +02001371 unsigned long ident = PyThread_get_thread_ident();
1372 PyObject *str = PyUnicode_FromFormat("%lu", ident);
1373 if (str != NULL) {
1374 if (PyFile_WriteObject(str, file, Py_PRINT_RAW) < 0) {
1375 Py_DECREF(str);
1376 return -1;
1377 }
1378 Py_DECREF(str);
1379 }
1380 else {
1381 PyErr_Clear();
1382
1383 if (PyFile_WriteString("<failed to get thread name>", file) < 0) {
1384 return -1;
1385 }
1386 }
1387 }
1388
1389 if (PyFile_WriteString(":\n", file) < 0) {
1390 return -1;
1391 }
1392
1393 /* Display the traceback */
1394 _PyErr_Display(file, exc_type, exc_value, exc_traceback);
1395
1396 /* Call file.flush() */
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001397 PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
Victor Stinnercd590a72019-05-28 00:39:52 +02001398 if (!res) {
1399 return -1;
1400 }
1401 Py_DECREF(res);
1402
1403 return 0;
1404}
1405
1406
1407PyDoc_STRVAR(ExceptHookArgs__doc__,
1408"ExceptHookArgs\n\
1409\n\
1410Type used to pass arguments to threading.excepthook.");
1411
1412static PyTypeObject ExceptHookArgsType;
1413
1414static PyStructSequence_Field ExceptHookArgs_fields[] = {
1415 {"exc_type", "Exception type"},
1416 {"exc_value", "Exception value"},
1417 {"exc_traceback", "Exception traceback"},
1418 {"thread", "Thread"},
1419 {0}
1420};
1421
1422static PyStructSequence_Desc ExceptHookArgs_desc = {
1423 .name = "_thread.ExceptHookArgs",
1424 .doc = ExceptHookArgs__doc__,
1425 .fields = ExceptHookArgs_fields,
1426 .n_in_sequence = 4
1427};
1428
1429
1430static PyObject *
1431thread_excepthook(PyObject *self, PyObject *args)
1432{
Andy Lester55728702020-03-06 16:53:17 -06001433 if (!Py_IS_TYPE(args, &ExceptHookArgsType)) {
Victor Stinnercd590a72019-05-28 00:39:52 +02001434 PyErr_SetString(PyExc_TypeError,
1435 "_thread.excepthook argument type "
1436 "must be ExceptHookArgs");
1437 return NULL;
1438 }
1439
1440 /* Borrowed reference */
1441 PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0);
1442 if (exc_type == PyExc_SystemExit) {
1443 /* silently ignore SystemExit */
1444 Py_RETURN_NONE;
1445 }
1446
1447 /* Borrowed references */
1448 PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1);
1449 PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
1450 PyObject *thread = PyStructSequence_GET_ITEM(args, 3);
1451
1452 PyObject *file = _PySys_GetObjectId(&PyId_stderr);
1453 if (file == NULL || file == Py_None) {
1454 if (thread == Py_None) {
1455 /* do nothing if sys.stderr is None and thread is None */
1456 Py_RETURN_NONE;
1457 }
1458
1459 file = PyObject_GetAttrString(thread, "_stderr");
1460 if (file == NULL) {
1461 return NULL;
1462 }
1463 if (file == Py_None) {
1464 Py_DECREF(file);
1465 /* do nothing if sys.stderr is None and sys.stderr was None
1466 when the thread was created */
1467 Py_RETURN_NONE;
1468 }
1469 }
1470 else {
1471 Py_INCREF(file);
1472 }
1473
1474 int res = thread_excepthook_file(file, exc_type, exc_value, exc_tb,
1475 thread);
1476 Py_DECREF(file);
1477 if (res < 0) {
1478 return NULL;
1479 }
1480
1481 Py_RETURN_NONE;
1482}
1483
1484PyDoc_STRVAR(excepthook_doc,
1485"excepthook(exc_type, exc_value, exc_traceback, thread)\n\
1486\n\
1487Handle uncaught Thread.run() exception.");
1488
Barry Warsawd0c10421996-12-17 00:05:22 +00001489static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001491 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001493 METH_VARARGS, start_new_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301494 {"allocate_lock", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301496 {"allocate", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001497 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301498 {"exit_thread", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301500 {"exit", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301502 {"interrupt_main", thread_PyThread_interrupt_main,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 METH_NOARGS, interrupt_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301504 {"get_ident", thread_get_ident,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 METH_NOARGS, get_ident_doc},
Jake Teslerb121f632019-05-22 08:43:17 -07001506#ifdef PY_HAVE_THREAD_NATIVE_ID
1507 {"get_native_id", thread_get_native_id,
1508 METH_NOARGS, get_native_id_doc},
1509#endif
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301510 {"_count", thread__count,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 METH_NOARGS, _count_doc},
1512 {"stack_size", (PyCFunction)thread_stack_size,
Victor Stinner754851f2011-04-19 23:58:51 +02001513 METH_VARARGS, stack_size_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301514 {"_set_sentinel", thread__set_sentinel,
Antoine Pitrou7b476992013-09-07 23:38:37 +02001515 METH_NOARGS, _set_sentinel_doc},
Victor Stinnercd590a72019-05-28 00:39:52 +02001516 {"_excepthook", thread_excepthook,
1517 METH_O, excepthook_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001519};
1520
1521
1522/* Initialization function */
1523
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001524PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001525"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001526The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001527
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001528PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001529"A lock object is a synchronization primitive. To create a lock,\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001530call threading.Lock(). Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001531\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001532acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1533release() -- unlock of the lock\n\
1534locked() -- test whether the lock is currently locked\n\
1535\n\
1536A lock is not owned by the thread that locked it; another thread may\n\
1537unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001538will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001539
Martin v. Löwis1a214512008-06-11 05:26:20 +00001540static struct PyModuleDef threadmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 PyModuleDef_HEAD_INIT,
1542 "_thread",
1543 thread_doc,
1544 -1,
1545 thread_methods,
1546 NULL,
1547 NULL,
1548 NULL,
1549 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001550};
1551
1552
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001553PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001554PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001555{
Victor Stinnerf5faad22015-03-28 03:52:05 +01001556 PyObject *m, *d, *v;
1557 double time_max;
1558 double timeout_max;
Victor Stinnerff4584c2020-03-13 18:03:56 +01001559 PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 /* Initialize types: */
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001562 if (PyType_Ready(&localdummytype) < 0)
1563 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001564 if (PyType_Ready(&localtype) < 0)
1565 return NULL;
1566 if (PyType_Ready(&Locktype) < 0)
1567 return NULL;
1568 if (PyType_Ready(&RLocktype) < 0)
1569 return NULL;
Victor Stinnercd590a72019-05-28 00:39:52 +02001570 if (ExceptHookArgsType.tp_name == NULL) {
1571 if (PyStructSequence_InitType2(&ExceptHookArgsType,
1572 &ExceptHookArgs_desc) < 0) {
1573 return NULL;
1574 }
1575 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 /* Create the module and add the functions */
1578 m = PyModule_Create(&threadmodule);
1579 if (m == NULL)
1580 return NULL;
Antoine Pitrou7c3e5772010-04-14 15:44:10 +00001581
Victor Stinnerc319eee2017-11-30 23:03:47 +01001582 timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6;
Victor Stinner850a18e2017-10-24 16:53:32 -07001583 time_max = _PyTime_AsSecondsDouble(_PyTime_MAX);
Victor Stinnerf5faad22015-03-28 03:52:05 +01001584 timeout_max = Py_MIN(timeout_max, time_max);
Victor Stinner850a18e2017-10-24 16:53:32 -07001585 /* Round towards minus infinity */
1586 timeout_max = floor(timeout_max);
Victor Stinnerf5faad22015-03-28 03:52:05 +01001587
1588 v = PyFloat_FromDouble(timeout_max);
1589 if (!v)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 return NULL;
Victor Stinnerf5faad22015-03-28 03:52:05 +01001591 if (PyModule_AddObject(m, "TIMEOUT_MAX", v) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 /* Add a symbolic constant */
1595 d = PyModule_GetDict(m);
Antoine Pitroufcf81fd2011-02-28 22:03:34 +00001596 ThreadError = PyExc_RuntimeError;
1597 Py_INCREF(ThreadError);
Victor Stinner754851f2011-04-19 23:58:51 +02001598
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 PyDict_SetItemString(d, "error", ThreadError);
1600 Locktype.tp_doc = lock_doc;
1601 Py_INCREF(&Locktype);
1602 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Antoine Pitrou434736a2009-11-10 18:46:01 +00001603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 Py_INCREF(&RLocktype);
1605 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1606 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 Py_INCREF(&localtype);
1609 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1610 return NULL;
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001611
Victor Stinnercd590a72019-05-28 00:39:52 +02001612 Py_INCREF(&ExceptHookArgsType);
1613 if (PyModule_AddObject(m, "_ExceptHookArgs",
1614 (PyObject *)&ExceptHookArgsType) < 0)
1615 return NULL;
1616
Victor Stinnercaba55b2018-08-03 15:33:52 +02001617 interp->num_threads = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +00001619 str_dict = PyUnicode_InternFromString("__dict__");
1620 if (str_dict == NULL)
1621 return NULL;
1622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 /* Initialize the C thread library */
1624 PyThread_init_thread();
1625 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001626}