blob: 77baba4847897b08c89b67ce00fb9d349d18ba52 [file] [log] [blame]
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001
2/* Thread module */
3/* Interface to Sjoerd's portable C thread library */
4
Barry Warsawd0c10421996-12-17 00:05:22 +00005#include "Python.h"
Victor Stinnercd590a72019-05-28 00:39:52 +02006#include "pycore_pylifecycle.h"
Victor Stinner4a21e572020-04-15 02:35:41 +02007#include "pycore_interp.h" // _PyInterpreterState.num_threads
8#include "pycore_pystate.h" // _PyThreadState_Init()
9#include <stddef.h> // offsetof()
Guido van Rossum1984f1e1992-08-04 12:41:02 +000010
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
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000590/* Quick overview:
591
592 We need to be able to reclaim reference cycles as soon as possible
593 (both when a thread is being terminated, or a thread-local object
594 becomes unreachable from user data). Constraints:
595 - it must not be possible for thread-state dicts to be involved in
596 reference cycles (otherwise the cyclic GC will refuse to consider
597 objects referenced from a reachable thread-state dict, even though
598 local_dealloc would clear them)
599 - the death of a thread-state dict must still imply destruction of the
600 corresponding local dicts in all thread-local objects.
601
602 Our implementation uses small "localdummy" objects in order to break
603 the reference chain. These trivial objects are hashable (using the
604 default scheme of identity hashing) and weakrefable.
605 Each thread-state holds a separate localdummy for each local object
606 (as a /strong reference/),
607 and each thread-local object holds a dict mapping /weak references/
608 of localdummies to local dicts.
609
610 Therefore:
611 - only the thread-state dict holds a strong reference to the dummies
612 - only the thread-local object holds a strong reference to the local dicts
613 - only outside objects (application- or library-level) hold strong
614 references to the thread-local objects
615 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
616 dummies attached to that thread are called, and destroy the corresponding
617 local dicts from thread-local objects
618 - as soon as a thread-local object is destroyed, its local dicts are
619 destroyed and its dummies are manually removed from all thread states
620 - the GC can do its work correctly when a thread-local object is dangling,
621 without any interference from the thread-state dicts
622
623 As an additional optimization, each localdummy holds a borrowed reference
624 to the corresponding localdict. This borrowed reference is only used
625 by the thread-local object which has created the localdummy, which should
626 guarantee that the localdict still exists when accessed.
627*/
628
629typedef struct {
630 PyObject_HEAD
631 PyObject *localdict; /* Borrowed reference! */
632 PyObject *weakreflist; /* List of weak references to self */
633} localdummyobject;
634
635static void
636localdummy_dealloc(localdummyobject *self)
637{
638 if (self->weakreflist != NULL)
639 PyObject_ClearWeakRefs((PyObject *) self);
640 Py_TYPE(self)->tp_free((PyObject*)self);
641}
642
643static PyTypeObject localdummytype = {
644 PyVarObject_HEAD_INIT(NULL, 0)
645 /* tp_name */ "_thread._localdummy",
646 /* tp_basicsize */ sizeof(localdummyobject),
647 /* tp_itemsize */ 0,
648 /* tp_dealloc */ (destructor)localdummy_dealloc,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200649 /* tp_vectorcall_offset */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000650 /* tp_getattr */ 0,
651 /* tp_setattr */ 0,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200652 /* tp_as_async */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000653 /* tp_repr */ 0,
654 /* tp_as_number */ 0,
655 /* tp_as_sequence */ 0,
656 /* tp_as_mapping */ 0,
657 /* tp_hash */ 0,
658 /* tp_call */ 0,
659 /* tp_str */ 0,
660 /* tp_getattro */ 0,
661 /* tp_setattro */ 0,
662 /* tp_as_buffer */ 0,
663 /* tp_flags */ Py_TPFLAGS_DEFAULT,
664 /* tp_doc */ "Thread-local dummy",
665 /* tp_traverse */ 0,
666 /* tp_clear */ 0,
667 /* tp_richcompare */ 0,
668 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
669};
670
671
Jim Fultond15dc062004-07-14 19:11:50 +0000672typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 PyObject_HEAD
674 PyObject *key;
675 PyObject *args;
676 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000677 PyObject *weakreflist; /* List of weak references to self */
678 /* A {localdummy weakref -> localdict} dict */
679 PyObject *dummies;
680 /* The callback for weakrefs to localdummies */
681 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000682} localobject;
683
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000684/* Forward declaration */
685static PyObject *_ldict(localobject *self);
686static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
687
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000688/* Create and register the dummy for the current thread.
689 Returns a borrowed reference of the corresponding local dict */
690static PyObject *
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000691_local_create_dummy(localobject *self)
692{
693 PyObject *tdict, *ldict = NULL, *wr = NULL;
694 localdummyobject *dummy = NULL;
695 int r;
696
697 tdict = PyThreadState_GetDict();
698 if (tdict == NULL) {
699 PyErr_SetString(PyExc_SystemError,
700 "Couldn't get thread-state dictionary");
701 goto err;
702 }
703
704 ldict = PyDict_New();
705 if (ldict == NULL)
706 goto err;
707 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
708 if (dummy == NULL)
709 goto err;
710 dummy->localdict = ldict;
711 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
712 if (wr == NULL)
713 goto err;
714
715 /* As a side-effect, this will cache the weakref's hash before the
716 dummy gets deleted */
717 r = PyDict_SetItem(self->dummies, wr, ldict);
718 if (r < 0)
719 goto err;
720 Py_CLEAR(wr);
721 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
722 if (r < 0)
723 goto err;
724 Py_CLEAR(dummy);
725
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000726 Py_DECREF(ldict);
727 return ldict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000728
729err:
730 Py_XDECREF(ldict);
731 Py_XDECREF(wr);
732 Py_XDECREF(dummy);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000733 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000734}
735
Jim Fultond15dc062004-07-14 19:11:50 +0000736static PyObject *
737local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
738{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 localobject *self;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000740 PyObject *wr;
741 static PyMethodDef wr_callback_def = {
742 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
743 };
Jim Fultond15dc062004-07-14 19:11:50 +0000744
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300745 if (type->tp_init == PyBaseObject_Type.tp_init) {
746 int rc = 0;
747 if (args != NULL)
748 rc = PyObject_IsTrue(args);
749 if (rc == 0 && kw != NULL)
750 rc = PyObject_IsTrue(kw);
751 if (rc != 0) {
752 if (rc > 0)
753 PyErr_SetString(PyExc_TypeError,
754 "Initialization arguments are not supported");
755 return NULL;
756 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000757 }
Jim Fultond15dc062004-07-14 19:11:50 +0000758
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 self = (localobject *)type->tp_alloc(type, 0);
760 if (self == NULL)
761 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000762
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000763 Py_XINCREF(args);
764 self->args = args;
765 Py_XINCREF(kw);
766 self->kw = kw;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000767 self->key = PyUnicode_FromFormat("thread.local.%p", self);
768 if (self->key == NULL)
769 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000770
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000771 self->dummies = PyDict_New();
772 if (self->dummies == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000773 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000774
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000775 /* We use a weak reference to self in the callback closure
776 in order to avoid spurious reference cycles */
777 wr = PyWeakref_NewRef((PyObject *) self, NULL);
778 if (wr == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779 goto err;
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200780 self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000781 Py_DECREF(wr);
782 if (self->wr_callback == NULL)
783 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000784
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000785 if (_local_create_dummy(self) == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000786 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000788 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000789
790 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000791 Py_DECREF(self);
792 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000793}
794
795static int
796local_traverse(localobject *self, visitproc visit, void *arg)
797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 Py_VISIT(self->args);
799 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000800 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000802}
803
804static int
805local_clear(localobject *self)
806{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000807 PyThreadState *tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 Py_CLEAR(self->args);
809 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000810 Py_CLEAR(self->dummies);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000811 Py_CLEAR(self->wr_callback);
812 /* Remove all strong references to dummies from the thread states */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000813 if (self->key
814 && (tstate = PyThreadState_Get())
815 && tstate->interp) {
816 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
817 tstate;
818 tstate = PyThreadState_Next(tstate))
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200819 if (tstate->dict && PyDict_GetItem(tstate->dict, self->key)) {
820 if (PyDict_DelItem(tstate->dict, self->key)) {
821 PyErr_Clear();
822 }
823 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000824 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000825 return 0;
826}
Jim Fultond15dc062004-07-14 19:11:50 +0000827
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000828static void
829local_dealloc(localobject *self)
830{
831 /* Weakrefs must be invalidated right now, otherwise they can be used
832 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
833 if (self->weakreflist != NULL)
834 PyObject_ClearWeakRefs((PyObject *) self);
835
836 PyObject_GC_UnTrack(self);
837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000838 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000839 Py_XDECREF(self->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000840 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000841}
842
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000843/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000844static PyObject *
845_ldict(localobject *self)
846{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000847 PyObject *tdict, *ldict, *dummy;
Jim Fultond15dc062004-07-14 19:11:50 +0000848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000849 tdict = PyThreadState_GetDict();
850 if (tdict == NULL) {
851 PyErr_SetString(PyExc_SystemError,
852 "Couldn't get thread-state dictionary");
853 return NULL;
854 }
Jim Fultond15dc062004-07-14 19:11:50 +0000855
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200856 dummy = PyDict_GetItemWithError(tdict, self->key);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000857 if (dummy == NULL) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200858 if (PyErr_Occurred()) {
859 return NULL;
860 }
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000861 ldict = _local_create_dummy(self);
862 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
866 Py_TYPE(self)->tp_init((PyObject*)self,
867 self->args, self->kw) < 0) {
868 /* we need to get rid of ldict from thread so
869 we create a new one the next time we do an attr
Ezio Melotti42da6632011-03-15 05:18:48 +0200870 access */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000871 PyDict_DelItem(tdict, self->key);
872 return NULL;
873 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000874 }
875 else {
Andy Lesterdffe4c02020-03-04 07:15:20 -0600876 assert(Py_IS_TYPE(dummy, &localdummytype));
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000877 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000878 }
Jim Fultond15dc062004-07-14 19:11:50 +0000879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000881}
882
Jim Fultond15dc062004-07-14 19:11:50 +0000883static int
884local_setattro(localobject *self, PyObject *name, PyObject *v)
885{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 PyObject *ldict;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000887 int r;
Jim Fultond15dc062004-07-14 19:11:50 +0000888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 ldict = _ldict(self);
890 if (ldict == NULL)
891 return -1;
892
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000893 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
894 if (r == 1) {
895 PyErr_Format(PyExc_AttributeError,
896 "'%.50s' object attribute '%U' is read-only",
897 Py_TYPE(self)->tp_name, name);
898 return -1;
899 }
900 if (r == -1)
901 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000902
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000903 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000904}
905
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000906static PyObject *local_getattro(localobject *, PyObject *);
907
Jim Fultond15dc062004-07-14 19:11:50 +0000908static PyTypeObject localtype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000909 PyVarObject_HEAD_INIT(NULL, 0)
910 /* tp_name */ "_thread._local",
911 /* tp_basicsize */ sizeof(localobject),
912 /* tp_itemsize */ 0,
913 /* tp_dealloc */ (destructor)local_dealloc,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200914 /* tp_vectorcall_offset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000915 /* tp_getattr */ 0,
916 /* tp_setattr */ 0,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200917 /* tp_as_async */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000918 /* tp_repr */ 0,
919 /* tp_as_number */ 0,
920 /* tp_as_sequence */ 0,
921 /* tp_as_mapping */ 0,
922 /* tp_hash */ 0,
923 /* tp_call */ 0,
924 /* tp_str */ 0,
925 /* tp_getattro */ (getattrofunc)local_getattro,
926 /* tp_setattro */ (setattrofunc)local_setattro,
927 /* tp_as_buffer */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000928 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
929 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 /* tp_doc */ "Thread-local data",
931 /* tp_traverse */ (traverseproc)local_traverse,
932 /* tp_clear */ (inquiry)local_clear,
933 /* tp_richcompare */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000934 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000935 /* tp_iter */ 0,
936 /* tp_iternext */ 0,
937 /* tp_methods */ 0,
938 /* tp_members */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000939 /* tp_getset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 /* tp_base */ 0,
941 /* tp_dict */ 0, /* internal use */
942 /* tp_descr_get */ 0,
943 /* tp_descr_set */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000944 /* tp_dictoffset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000945 /* tp_init */ 0,
946 /* tp_alloc */ 0,
947 /* tp_new */ local_new,
948 /* tp_free */ 0, /* Low-level free-mem routine */
949 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000950};
951
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000952static PyObject *
953local_getattro(localobject *self, PyObject *name)
954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000955 PyObject *ldict, *value;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000956 int r;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 ldict = _ldict(self);
959 if (ldict == NULL)
960 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000961
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000962 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
963 if (r == 1) {
964 Py_INCREF(ldict);
965 return ldict;
966 }
967 if (r == -1)
968 return NULL;
969
Andy Lester55728702020-03-06 16:53:17 -0600970 if (!Py_IS_TYPE(self, &localtype))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 /* use generic lookup for subtypes */
INADA Naoki378edee2018-01-16 20:52:41 +0900972 return _PyObject_GenericGetAttrWithDict(
973 (PyObject *)self, name, ldict, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 /* Optimization: just look in dict ourselves */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200976 value = PyDict_GetItemWithError(ldict, name);
977 if (value != NULL) {
978 Py_INCREF(value);
979 return value;
980 }
981 else if (PyErr_Occurred()) {
982 return NULL;
983 }
984 /* Fall back on generic to get __class__ and __dict__ */
985 return _PyObject_GenericGetAttrWithDict(
986 (PyObject *)self, name, ldict, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000987}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000988
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000989/* Called when a dummy is destroyed. */
990static PyObject *
991_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
992{
993 PyObject *obj;
994 localobject *self;
995 assert(PyWeakref_CheckRef(localweakref));
996 obj = PyWeakref_GET_OBJECT(localweakref);
997 if (obj == Py_None)
998 Py_RETURN_NONE;
999 Py_INCREF(obj);
1000 assert(PyObject_TypeCheck(obj, &localtype));
1001 /* If the thread-local object is still alive and not being cleared,
1002 remove the corresponding local dict */
1003 self = (localobject *) obj;
1004 if (self->dummies != NULL) {
1005 PyObject *ldict;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001006 ldict = PyDict_GetItemWithError(self->dummies, dummyweakref);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001007 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001008 PyDict_DelItem(self->dummies, dummyweakref);
1009 }
1010 if (PyErr_Occurred())
1011 PyErr_WriteUnraisable(obj);
1012 }
1013 Py_DECREF(obj);
1014 Py_RETURN_NONE;
1015}
1016
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001017/* Module functions */
1018
Guido van Rossuma027efa1997-05-05 20:56:21 +00001019struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 PyInterpreterState *interp;
1021 PyObject *func;
1022 PyObject *args;
1023 PyObject *keyw;
1024 PyThreadState *tstate;
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001025 _PyRuntimeState *runtime;
Guido van Rossuma027efa1997-05-05 20:56:21 +00001026};
1027
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001028static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001029t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001030{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 struct bootstate *boot = (struct bootstate *) boot_raw;
1032 PyThreadState *tstate;
1033 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 tstate = boot->tstate;
1036 tstate->thread_id = PyThread_get_thread_ident();
Victor Stinner01b1cc12019-11-20 02:27:56 +01001037 _PyThreadState_Init(tstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 PyEval_AcquireThread(tstate);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001039 tstate->interp->num_threads++;
INADA Naoki72dccde2017-02-16 09:26:01 +09001040 res = PyObject_Call(boot->func, boot->args, boot->keyw);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 if (res == NULL) {
1042 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Victor Stinner8b095002019-05-29 02:57:56 +02001043 /* SystemExit is ignored silently */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 PyErr_Clear();
1045 else {
Victor Stinner8b095002019-05-29 02:57:56 +02001046 _PyErr_WriteUnraisableMsg("in thread started by", boot->func);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 }
1048 }
Victor Stinner8b095002019-05-29 02:57:56 +02001049 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001050 Py_DECREF(res);
Victor Stinner8b095002019-05-29 02:57:56 +02001051 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001052 Py_DECREF(boot->func);
1053 Py_DECREF(boot->args);
1054 Py_XDECREF(boot->keyw);
1055 PyMem_DEL(boot_raw);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001056 tstate->interp->num_threads--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 PyThreadState_Clear(tstate);
Victor Stinner23ef89d2020-03-18 02:26:04 +01001058 _PyThreadState_DeleteCurrent(tstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001060}
1061
Barry Warsawd0c10421996-12-17 00:05:22 +00001062static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001063thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001064{
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001065 _PyRuntimeState *runtime = &_PyRuntime;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 PyObject *func, *args, *keyw = NULL;
1067 struct bootstate *boot;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001068 unsigned long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
1071 &func, &args, &keyw))
1072 return NULL;
1073 if (!PyCallable_Check(func)) {
1074 PyErr_SetString(PyExc_TypeError,
1075 "first arg must be callable");
1076 return NULL;
1077 }
1078 if (!PyTuple_Check(args)) {
1079 PyErr_SetString(PyExc_TypeError,
1080 "2nd arg must be a tuple");
1081 return NULL;
1082 }
1083 if (keyw != NULL && !PyDict_Check(keyw)) {
1084 PyErr_SetString(PyExc_TypeError,
1085 "optional 3rd arg must be a dictionary");
1086 return NULL;
1087 }
Victor Stinner252346a2020-05-01 11:33:44 +02001088
1089 PyInterpreterState *interp = _PyInterpreterState_GET();
1090 if (interp->config._isolated_interpreter) {
1091 PyErr_SetString(PyExc_RuntimeError,
1092 "thread is not supported for isolated subinterpreters");
1093 return NULL;
1094 }
1095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 boot = PyMem_NEW(struct bootstate, 1);
1097 if (boot == NULL)
1098 return PyErr_NoMemory();
Victor Stinner81a7be32020-04-14 15:14:01 +02001099 boot->interp = _PyInterpreterState_GET();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 boot->func = func;
1101 boot->args = args;
1102 boot->keyw = keyw;
1103 boot->tstate = _PyThreadState_Prealloc(boot->interp);
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001104 boot->runtime = runtime;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001105 if (boot->tstate == NULL) {
1106 PyMem_DEL(boot);
1107 return PyErr_NoMemory();
1108 }
1109 Py_INCREF(func);
1110 Py_INCREF(args);
1111 Py_XINCREF(keyw);
Victor Stinner3225b9f2020-03-09 20:56:57 +01001112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001114 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 PyErr_SetString(ThreadError, "can't start new thread");
1116 Py_DECREF(func);
1117 Py_DECREF(args);
1118 Py_XDECREF(keyw);
1119 PyThreadState_Clear(boot->tstate);
1120 PyMem_DEL(boot);
1121 return NULL;
1122 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001123 return PyLong_FromUnsignedLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001124}
1125
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001126PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001127"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001128(start_new() is an obsolete synonym)\n\
1129\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001130Start a new thread and return its identifier. The thread will call the\n\
1131function with positional arguments from the tuple args and keyword arguments\n\
1132taken from the optional dictionary kwargs. The thread exits when the\n\
1133function returns; the return value is ignored. The thread will also exit\n\
1134when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001135printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001136
Barry Warsawd0c10421996-12-17 00:05:22 +00001137static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301138thread_PyThread_exit_thread(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001139{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 PyErr_SetNone(PyExc_SystemExit);
1141 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001142}
1143
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001144PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001145"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001146(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001147\n\
1148This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001149thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001150
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001151static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301152thread_PyThread_interrupt_main(PyObject * self, PyObject *Py_UNUSED(ignored))
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001153{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 PyErr_SetInterrupt();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001155 Py_RETURN_NONE;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001156}
1157
1158PyDoc_STRVAR(interrupt_doc,
1159"interrupt_main()\n\
1160\n\
1161Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001162A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001163);
1164
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001165static lockobject *newlockobject(void);
1166
Barry Warsawd0c10421996-12-17 00:05:22 +00001167static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301168thread_PyThread_allocate_lock(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001169{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001171}
1172
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001173PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001174"allocate_lock() -> lock object\n\
1175(allocate() is an obsolete synonym)\n\
1176\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001177Create a new lock object. See help(type(threading.Lock())) for\n\
1178information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001179
Barry Warsawd0c10421996-12-17 00:05:22 +00001180static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301181thread_get_ident(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001182{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001183 unsigned long ident = PyThread_get_thread_ident();
1184 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 PyErr_SetString(ThreadError, "no current thread ident");
1186 return NULL;
1187 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001188 return PyLong_FromUnsignedLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001189}
1190
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001191PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001192"get_ident() -> integer\n\
1193\n\
1194Return a non-zero integer that uniquely identifies the current thread\n\
1195amongst other threads that exist simultaneously.\n\
1196This may be used to identify per-thread resources.\n\
1197Even though on some platforms threads identities may appear to be\n\
1198allocated consecutive numbers starting at 1, this behavior should not\n\
1199be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001200A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001201
Jake Teslerb121f632019-05-22 08:43:17 -07001202#ifdef PY_HAVE_THREAD_NATIVE_ID
1203static PyObject *
1204thread_get_native_id(PyObject *self, PyObject *Py_UNUSED(ignored))
1205{
1206 unsigned long native_id = PyThread_get_thread_native_id();
1207 return PyLong_FromUnsignedLong(native_id);
1208}
1209
1210PyDoc_STRVAR(get_native_id_doc,
1211"get_native_id() -> integer\n\
1212\n\
1213Return a non-negative integer identifying the thread as reported\n\
1214by the OS (kernel). This may be used to uniquely identify a\n\
1215particular thread within a system.");
1216#endif
1217
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001218static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301219thread__count(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001220{
Victor Stinner81a7be32020-04-14 15:14:01 +02001221 PyInterpreterState *interp = _PyInterpreterState_GET();
Victor Stinnercaba55b2018-08-03 15:33:52 +02001222 return PyLong_FromLong(interp->num_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001223}
1224
1225PyDoc_STRVAR(_count_doc,
1226"_count() -> integer\n\
1227\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001228\
oldkaa0735f2018-02-02 16:52:55 +08001229Return the number of currently running Python threads, excluding\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001230the main thread. The returned number comprises all threads created\n\
1231through `start_new_thread()` as well as `threading.Thread`, and not\n\
1232yet finished.\n\
1233\n\
1234This function is meant for internal and specialized purposes only.\n\
1235In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001236
Antoine Pitrou7b476992013-09-07 23:38:37 +02001237static void
Victor Stinnera42de742018-11-22 10:25:22 +01001238release_sentinel(void *wr_raw)
Antoine Pitrou7b476992013-09-07 23:38:37 +02001239{
Victor Stinnera42de742018-11-22 10:25:22 +01001240 PyObject *wr = _PyObject_CAST(wr_raw);
Antoine Pitrou7b476992013-09-07 23:38:37 +02001241 /* Tricky: this function is called when the current thread state
1242 is being deleted. Therefore, only simple C code can safely
1243 execute here. */
1244 PyObject *obj = PyWeakref_GET_OBJECT(wr);
1245 lockobject *lock;
1246 if (obj != Py_None) {
Andy Lesterdffe4c02020-03-04 07:15:20 -06001247 assert(Py_IS_TYPE(obj, &Locktype));
Antoine Pitrou7b476992013-09-07 23:38:37 +02001248 lock = (lockobject *) obj;
1249 if (lock->locked) {
1250 PyThread_release_lock(lock->lock_lock);
1251 lock->locked = 0;
1252 }
1253 }
1254 /* Deallocating a weakref with a NULL callback only calls
1255 PyObject_GC_Del(), which can't call any Python code. */
1256 Py_DECREF(wr);
1257}
1258
1259static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301260thread__set_sentinel(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou7b476992013-09-07 23:38:37 +02001261{
1262 PyObject *wr;
1263 PyThreadState *tstate = PyThreadState_Get();
1264 lockobject *lock;
1265
1266 if (tstate->on_delete_data != NULL) {
1267 /* We must support the re-creation of the lock from a
1268 fork()ed child. */
1269 assert(tstate->on_delete == &release_sentinel);
1270 wr = (PyObject *) tstate->on_delete_data;
1271 tstate->on_delete = NULL;
1272 tstate->on_delete_data = NULL;
1273 Py_DECREF(wr);
1274 }
1275 lock = newlockobject();
1276 if (lock == NULL)
1277 return NULL;
1278 /* The lock is owned by whoever called _set_sentinel(), but the weakref
1279 hangs to the thread state. */
1280 wr = PyWeakref_NewRef((PyObject *) lock, NULL);
1281 if (wr == NULL) {
1282 Py_DECREF(lock);
1283 return NULL;
1284 }
1285 tstate->on_delete_data = (void *) wr;
1286 tstate->on_delete = &release_sentinel;
1287 return (PyObject *) lock;
1288}
1289
1290PyDoc_STRVAR(_set_sentinel_doc,
1291"_set_sentinel() -> lock\n\
1292\n\
1293Set a sentinel lock that will be released when the current thread\n\
1294state is finalized (after it is untied from the interpreter).\n\
1295\n\
1296This is a private API for the threading module.");
1297
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001298static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001299thread_stack_size(PyObject *self, PyObject *args)
1300{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 size_t old_size;
1302 Py_ssize_t new_size = 0;
1303 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1306 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 if (new_size < 0) {
1309 PyErr_SetString(PyExc_ValueError,
1310 "size must be 0 or a positive value");
1311 return NULL;
1312 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 rc = PyThread_set_stacksize((size_t) new_size);
1317 if (rc == -1) {
1318 PyErr_Format(PyExc_ValueError,
1319 "size not valid: %zd bytes",
1320 new_size);
1321 return NULL;
1322 }
1323 if (rc == -2) {
1324 PyErr_SetString(ThreadError,
1325 "setting stack size not supported");
1326 return NULL;
1327 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001330}
1331
1332PyDoc_STRVAR(stack_size_doc,
1333"stack_size([size]) -> size\n\
1334\n\
1335Return the thread stack size used when creating new threads. The\n\
1336optional size argument specifies the stack size (in bytes) to be used\n\
1337for subsequently created threads, and must be 0 (use platform or\n\
1338configured default) or a positive integer value of at least 32,768 (32k).\n\
1339If changing the thread stack size is unsupported, a ThreadError\n\
1340exception is raised. If the specified size is invalid, a ValueError\n\
1341exception is raised, and the stack size is unmodified. 32k bytes\n\
1342 currently the minimum supported stack size value to guarantee\n\
1343sufficient stack space for the interpreter itself.\n\
1344\n\
1345Note that some platforms may have particular restrictions on values for\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001346the stack size, such as requiring a minimum stack size larger than 32 KiB or\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001347requiring allocation in multiples of the system memory page size\n\
1348- platform documentation should be referred to for more information\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001349(4 KiB pages are common; using multiples of 4096 for the stack size is\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001350the suggested approach in the absence of more specific information).");
1351
Victor Stinnercd590a72019-05-28 00:39:52 +02001352static int
1353thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value,
1354 PyObject *exc_traceback, PyObject *thread)
1355{
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001356 _Py_IDENTIFIER(name);
Victor Stinnercd590a72019-05-28 00:39:52 +02001357 /* print(f"Exception in thread {thread.name}:", file=file) */
1358 if (PyFile_WriteString("Exception in thread ", file) < 0) {
1359 return -1;
1360 }
1361
1362 PyObject *name = NULL;
1363 if (thread != Py_None) {
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001364 if (_PyObject_LookupAttrId(thread, &PyId_name, &name) < 0) {
1365 return -1;
1366 }
Victor Stinnercd590a72019-05-28 00:39:52 +02001367 }
1368 if (name != NULL) {
1369 if (PyFile_WriteObject(name, file, Py_PRINT_RAW) < 0) {
1370 Py_DECREF(name);
1371 return -1;
1372 }
1373 Py_DECREF(name);
1374 }
1375 else {
Victor Stinnercd590a72019-05-28 00:39:52 +02001376 unsigned long ident = PyThread_get_thread_ident();
1377 PyObject *str = PyUnicode_FromFormat("%lu", ident);
1378 if (str != NULL) {
1379 if (PyFile_WriteObject(str, file, Py_PRINT_RAW) < 0) {
1380 Py_DECREF(str);
1381 return -1;
1382 }
1383 Py_DECREF(str);
1384 }
1385 else {
1386 PyErr_Clear();
1387
1388 if (PyFile_WriteString("<failed to get thread name>", file) < 0) {
1389 return -1;
1390 }
1391 }
1392 }
1393
1394 if (PyFile_WriteString(":\n", file) < 0) {
1395 return -1;
1396 }
1397
1398 /* Display the traceback */
1399 _PyErr_Display(file, exc_type, exc_value, exc_traceback);
1400
1401 /* Call file.flush() */
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001402 PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
Victor Stinnercd590a72019-05-28 00:39:52 +02001403 if (!res) {
1404 return -1;
1405 }
1406 Py_DECREF(res);
1407
1408 return 0;
1409}
1410
1411
1412PyDoc_STRVAR(ExceptHookArgs__doc__,
1413"ExceptHookArgs\n\
1414\n\
1415Type used to pass arguments to threading.excepthook.");
1416
1417static PyTypeObject ExceptHookArgsType;
1418
1419static PyStructSequence_Field ExceptHookArgs_fields[] = {
1420 {"exc_type", "Exception type"},
1421 {"exc_value", "Exception value"},
1422 {"exc_traceback", "Exception traceback"},
1423 {"thread", "Thread"},
1424 {0}
1425};
1426
1427static PyStructSequence_Desc ExceptHookArgs_desc = {
1428 .name = "_thread.ExceptHookArgs",
1429 .doc = ExceptHookArgs__doc__,
1430 .fields = ExceptHookArgs_fields,
1431 .n_in_sequence = 4
1432};
1433
1434
1435static PyObject *
1436thread_excepthook(PyObject *self, PyObject *args)
1437{
Andy Lester55728702020-03-06 16:53:17 -06001438 if (!Py_IS_TYPE(args, &ExceptHookArgsType)) {
Victor Stinnercd590a72019-05-28 00:39:52 +02001439 PyErr_SetString(PyExc_TypeError,
1440 "_thread.excepthook argument type "
1441 "must be ExceptHookArgs");
1442 return NULL;
1443 }
1444
1445 /* Borrowed reference */
1446 PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0);
1447 if (exc_type == PyExc_SystemExit) {
1448 /* silently ignore SystemExit */
1449 Py_RETURN_NONE;
1450 }
1451
1452 /* Borrowed references */
1453 PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1);
1454 PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
1455 PyObject *thread = PyStructSequence_GET_ITEM(args, 3);
1456
1457 PyObject *file = _PySys_GetObjectId(&PyId_stderr);
1458 if (file == NULL || file == Py_None) {
1459 if (thread == Py_None) {
1460 /* do nothing if sys.stderr is None and thread is None */
1461 Py_RETURN_NONE;
1462 }
1463
1464 file = PyObject_GetAttrString(thread, "_stderr");
1465 if (file == NULL) {
1466 return NULL;
1467 }
1468 if (file == Py_None) {
1469 Py_DECREF(file);
1470 /* do nothing if sys.stderr is None and sys.stderr was None
1471 when the thread was created */
1472 Py_RETURN_NONE;
1473 }
1474 }
1475 else {
1476 Py_INCREF(file);
1477 }
1478
1479 int res = thread_excepthook_file(file, exc_type, exc_value, exc_tb,
1480 thread);
1481 Py_DECREF(file);
1482 if (res < 0) {
1483 return NULL;
1484 }
1485
1486 Py_RETURN_NONE;
1487}
1488
1489PyDoc_STRVAR(excepthook_doc,
1490"excepthook(exc_type, exc_value, exc_traceback, thread)\n\
1491\n\
1492Handle uncaught Thread.run() exception.");
1493
Barry Warsawd0c10421996-12-17 00:05:22 +00001494static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001496 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001497 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001498 METH_VARARGS, start_new_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301499 {"allocate_lock", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301501 {"allocate", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301503 {"exit_thread", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301505 {"exit", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301507 {"interrupt_main", thread_PyThread_interrupt_main,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 METH_NOARGS, interrupt_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301509 {"get_ident", thread_get_ident,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 METH_NOARGS, get_ident_doc},
Jake Teslerb121f632019-05-22 08:43:17 -07001511#ifdef PY_HAVE_THREAD_NATIVE_ID
1512 {"get_native_id", thread_get_native_id,
1513 METH_NOARGS, get_native_id_doc},
1514#endif
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301515 {"_count", thread__count,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 METH_NOARGS, _count_doc},
1517 {"stack_size", (PyCFunction)thread_stack_size,
Victor Stinner754851f2011-04-19 23:58:51 +02001518 METH_VARARGS, stack_size_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301519 {"_set_sentinel", thread__set_sentinel,
Antoine Pitrou7b476992013-09-07 23:38:37 +02001520 METH_NOARGS, _set_sentinel_doc},
Victor Stinnercd590a72019-05-28 00:39:52 +02001521 {"_excepthook", thread_excepthook,
1522 METH_O, excepthook_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001524};
1525
1526
1527/* Initialization function */
1528
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001529PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001530"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001531The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001532
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001533PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001534"A lock object is a synchronization primitive. To create a lock,\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001535call threading.Lock(). Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001536\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001537acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1538release() -- unlock of the lock\n\
1539locked() -- test whether the lock is currently locked\n\
1540\n\
1541A lock is not owned by the thread that locked it; another thread may\n\
1542unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001543will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001544
Martin v. Löwis1a214512008-06-11 05:26:20 +00001545static struct PyModuleDef threadmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 PyModuleDef_HEAD_INIT,
1547 "_thread",
1548 thread_doc,
1549 -1,
1550 thread_methods,
1551 NULL,
1552 NULL,
1553 NULL,
1554 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001555};
1556
1557
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001558PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001559PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001560{
Victor Stinnerf5faad22015-03-28 03:52:05 +01001561 PyObject *m, *d, *v;
1562 double time_max;
1563 double timeout_max;
Victor Stinner81a7be32020-04-14 15:14:01 +02001564 PyInterpreterState *interp = _PyInterpreterState_GET();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 /* Initialize types: */
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001567 if (PyType_Ready(&localdummytype) < 0)
1568 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001569 if (PyType_Ready(&localtype) < 0)
1570 return NULL;
1571 if (PyType_Ready(&Locktype) < 0)
1572 return NULL;
1573 if (PyType_Ready(&RLocktype) < 0)
1574 return NULL;
Victor Stinnercd590a72019-05-28 00:39:52 +02001575 if (ExceptHookArgsType.tp_name == NULL) {
1576 if (PyStructSequence_InitType2(&ExceptHookArgsType,
1577 &ExceptHookArgs_desc) < 0) {
1578 return NULL;
1579 }
1580 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001581
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 /* Create the module and add the functions */
1583 m = PyModule_Create(&threadmodule);
1584 if (m == NULL)
1585 return NULL;
Antoine Pitrou7c3e5772010-04-14 15:44:10 +00001586
Victor Stinnerc319eee2017-11-30 23:03:47 +01001587 timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6;
Victor Stinner850a18e2017-10-24 16:53:32 -07001588 time_max = _PyTime_AsSecondsDouble(_PyTime_MAX);
Victor Stinnerf5faad22015-03-28 03:52:05 +01001589 timeout_max = Py_MIN(timeout_max, time_max);
Victor Stinner850a18e2017-10-24 16:53:32 -07001590 /* Round towards minus infinity */
1591 timeout_max = floor(timeout_max);
Victor Stinnerf5faad22015-03-28 03:52:05 +01001592
1593 v = PyFloat_FromDouble(timeout_max);
1594 if (!v)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 return NULL;
Victor Stinnerf5faad22015-03-28 03:52:05 +01001596 if (PyModule_AddObject(m, "TIMEOUT_MAX", v) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001598
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 /* Add a symbolic constant */
1600 d = PyModule_GetDict(m);
Antoine Pitroufcf81fd2011-02-28 22:03:34 +00001601 ThreadError = PyExc_RuntimeError;
1602 Py_INCREF(ThreadError);
Victor Stinner754851f2011-04-19 23:58:51 +02001603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 PyDict_SetItemString(d, "error", ThreadError);
1605 Locktype.tp_doc = lock_doc;
1606 Py_INCREF(&Locktype);
1607 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Antoine Pitrou434736a2009-11-10 18:46:01 +00001608
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 Py_INCREF(&RLocktype);
1610 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1611 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 Py_INCREF(&localtype);
1614 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1615 return NULL;
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001616
Victor Stinnercd590a72019-05-28 00:39:52 +02001617 Py_INCREF(&ExceptHookArgsType);
1618 if (PyModule_AddObject(m, "_ExceptHookArgs",
1619 (PyObject *)&ExceptHookArgsType) < 0)
1620 return NULL;
1621
Victor Stinnercaba55b2018-08-03 15:33:52 +02001622 interp->num_threads = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +00001624 str_dict = PyUnicode_InternFromString("__dict__");
1625 if (str_dict == NULL)
1626 return NULL;
1627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 /* Initialize the C thread library */
1629 PyThread_init_thread();
1630 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001631}