blob: b3d90b22c5a665b75b4bf1d0fb9cb05aaa347ab2 [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 }
1088 boot = PyMem_NEW(struct bootstate, 1);
1089 if (boot == NULL)
1090 return PyErr_NoMemory();
Victor Stinner81a7be32020-04-14 15:14:01 +02001091 boot->interp = _PyInterpreterState_GET();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 boot->func = func;
1093 boot->args = args;
1094 boot->keyw = keyw;
1095 boot->tstate = _PyThreadState_Prealloc(boot->interp);
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001096 boot->runtime = runtime;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001097 if (boot->tstate == NULL) {
1098 PyMem_DEL(boot);
1099 return PyErr_NoMemory();
1100 }
1101 Py_INCREF(func);
1102 Py_INCREF(args);
1103 Py_XINCREF(keyw);
Victor Stinner3225b9f2020-03-09 20:56:57 +01001104
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001105 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001106 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 PyErr_SetString(ThreadError, "can't start new thread");
1108 Py_DECREF(func);
1109 Py_DECREF(args);
1110 Py_XDECREF(keyw);
1111 PyThreadState_Clear(boot->tstate);
1112 PyMem_DEL(boot);
1113 return NULL;
1114 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001115 return PyLong_FromUnsignedLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001116}
1117
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001118PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001119"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001120(start_new() is an obsolete synonym)\n\
1121\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001122Start a new thread and return its identifier. The thread will call the\n\
1123function with positional arguments from the tuple args and keyword arguments\n\
1124taken from the optional dictionary kwargs. The thread exits when the\n\
1125function returns; the return value is ignored. The thread will also exit\n\
1126when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001127printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001128
Barry Warsawd0c10421996-12-17 00:05:22 +00001129static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301130thread_PyThread_exit_thread(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001131{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001132 PyErr_SetNone(PyExc_SystemExit);
1133 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001134}
1135
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001136PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001137"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001138(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001139\n\
1140This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001141thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001142
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001143static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301144thread_PyThread_interrupt_main(PyObject * self, PyObject *Py_UNUSED(ignored))
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001145{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 PyErr_SetInterrupt();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001147 Py_RETURN_NONE;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001148}
1149
1150PyDoc_STRVAR(interrupt_doc,
1151"interrupt_main()\n\
1152\n\
1153Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001154A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001155);
1156
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001157static lockobject *newlockobject(void);
1158
Barry Warsawd0c10421996-12-17 00:05:22 +00001159static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301160thread_PyThread_allocate_lock(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001161{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001163}
1164
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001165PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001166"allocate_lock() -> lock object\n\
1167(allocate() is an obsolete synonym)\n\
1168\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001169Create a new lock object. See help(type(threading.Lock())) for\n\
1170information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001171
Barry Warsawd0c10421996-12-17 00:05:22 +00001172static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301173thread_get_ident(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001174{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001175 unsigned long ident = PyThread_get_thread_ident();
1176 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 PyErr_SetString(ThreadError, "no current thread ident");
1178 return NULL;
1179 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001180 return PyLong_FromUnsignedLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001181}
1182
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001183PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001184"get_ident() -> integer\n\
1185\n\
1186Return a non-zero integer that uniquely identifies the current thread\n\
1187amongst other threads that exist simultaneously.\n\
1188This may be used to identify per-thread resources.\n\
1189Even though on some platforms threads identities may appear to be\n\
1190allocated consecutive numbers starting at 1, this behavior should not\n\
1191be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001192A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001193
Jake Teslerb121f632019-05-22 08:43:17 -07001194#ifdef PY_HAVE_THREAD_NATIVE_ID
1195static PyObject *
1196thread_get_native_id(PyObject *self, PyObject *Py_UNUSED(ignored))
1197{
1198 unsigned long native_id = PyThread_get_thread_native_id();
1199 return PyLong_FromUnsignedLong(native_id);
1200}
1201
1202PyDoc_STRVAR(get_native_id_doc,
1203"get_native_id() -> integer\n\
1204\n\
1205Return a non-negative integer identifying the thread as reported\n\
1206by the OS (kernel). This may be used to uniquely identify a\n\
1207particular thread within a system.");
1208#endif
1209
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001210static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301211thread__count(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001212{
Victor Stinner81a7be32020-04-14 15:14:01 +02001213 PyInterpreterState *interp = _PyInterpreterState_GET();
Victor Stinnercaba55b2018-08-03 15:33:52 +02001214 return PyLong_FromLong(interp->num_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001215}
1216
1217PyDoc_STRVAR(_count_doc,
1218"_count() -> integer\n\
1219\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001220\
oldkaa0735f2018-02-02 16:52:55 +08001221Return the number of currently running Python threads, excluding\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001222the main thread. The returned number comprises all threads created\n\
1223through `start_new_thread()` as well as `threading.Thread`, and not\n\
1224yet finished.\n\
1225\n\
1226This function is meant for internal and specialized purposes only.\n\
1227In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001228
Antoine Pitrou7b476992013-09-07 23:38:37 +02001229static void
Victor Stinnera42de742018-11-22 10:25:22 +01001230release_sentinel(void *wr_raw)
Antoine Pitrou7b476992013-09-07 23:38:37 +02001231{
Victor Stinnera42de742018-11-22 10:25:22 +01001232 PyObject *wr = _PyObject_CAST(wr_raw);
Antoine Pitrou7b476992013-09-07 23:38:37 +02001233 /* Tricky: this function is called when the current thread state
1234 is being deleted. Therefore, only simple C code can safely
1235 execute here. */
1236 PyObject *obj = PyWeakref_GET_OBJECT(wr);
1237 lockobject *lock;
1238 if (obj != Py_None) {
Andy Lesterdffe4c02020-03-04 07:15:20 -06001239 assert(Py_IS_TYPE(obj, &Locktype));
Antoine Pitrou7b476992013-09-07 23:38:37 +02001240 lock = (lockobject *) obj;
1241 if (lock->locked) {
1242 PyThread_release_lock(lock->lock_lock);
1243 lock->locked = 0;
1244 }
1245 }
1246 /* Deallocating a weakref with a NULL callback only calls
1247 PyObject_GC_Del(), which can't call any Python code. */
1248 Py_DECREF(wr);
1249}
1250
1251static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301252thread__set_sentinel(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou7b476992013-09-07 23:38:37 +02001253{
1254 PyObject *wr;
1255 PyThreadState *tstate = PyThreadState_Get();
1256 lockobject *lock;
1257
1258 if (tstate->on_delete_data != NULL) {
1259 /* We must support the re-creation of the lock from a
1260 fork()ed child. */
1261 assert(tstate->on_delete == &release_sentinel);
1262 wr = (PyObject *) tstate->on_delete_data;
1263 tstate->on_delete = NULL;
1264 tstate->on_delete_data = NULL;
1265 Py_DECREF(wr);
1266 }
1267 lock = newlockobject();
1268 if (lock == NULL)
1269 return NULL;
1270 /* The lock is owned by whoever called _set_sentinel(), but the weakref
1271 hangs to the thread state. */
1272 wr = PyWeakref_NewRef((PyObject *) lock, NULL);
1273 if (wr == NULL) {
1274 Py_DECREF(lock);
1275 return NULL;
1276 }
1277 tstate->on_delete_data = (void *) wr;
1278 tstate->on_delete = &release_sentinel;
1279 return (PyObject *) lock;
1280}
1281
1282PyDoc_STRVAR(_set_sentinel_doc,
1283"_set_sentinel() -> lock\n\
1284\n\
1285Set a sentinel lock that will be released when the current thread\n\
1286state is finalized (after it is untied from the interpreter).\n\
1287\n\
1288This is a private API for the threading module.");
1289
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001290static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001291thread_stack_size(PyObject *self, PyObject *args)
1292{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 size_t old_size;
1294 Py_ssize_t new_size = 0;
1295 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1298 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 if (new_size < 0) {
1301 PyErr_SetString(PyExc_ValueError,
1302 "size must be 0 or a positive value");
1303 return NULL;
1304 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 rc = PyThread_set_stacksize((size_t) new_size);
1309 if (rc == -1) {
1310 PyErr_Format(PyExc_ValueError,
1311 "size not valid: %zd bytes",
1312 new_size);
1313 return NULL;
1314 }
1315 if (rc == -2) {
1316 PyErr_SetString(ThreadError,
1317 "setting stack size not supported");
1318 return NULL;
1319 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001322}
1323
1324PyDoc_STRVAR(stack_size_doc,
1325"stack_size([size]) -> size\n\
1326\n\
1327Return the thread stack size used when creating new threads. The\n\
1328optional size argument specifies the stack size (in bytes) to be used\n\
1329for subsequently created threads, and must be 0 (use platform or\n\
1330configured default) or a positive integer value of at least 32,768 (32k).\n\
1331If changing the thread stack size is unsupported, a ThreadError\n\
1332exception is raised. If the specified size is invalid, a ValueError\n\
1333exception is raised, and the stack size is unmodified. 32k bytes\n\
1334 currently the minimum supported stack size value to guarantee\n\
1335sufficient stack space for the interpreter itself.\n\
1336\n\
1337Note that some platforms may have particular restrictions on values for\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001338the stack size, such as requiring a minimum stack size larger than 32 KiB or\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001339requiring allocation in multiples of the system memory page size\n\
1340- platform documentation should be referred to for more information\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001341(4 KiB pages are common; using multiples of 4096 for the stack size is\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001342the suggested approach in the absence of more specific information).");
1343
Victor Stinnercd590a72019-05-28 00:39:52 +02001344static int
1345thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value,
1346 PyObject *exc_traceback, PyObject *thread)
1347{
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001348 _Py_IDENTIFIER(name);
Victor Stinnercd590a72019-05-28 00:39:52 +02001349 /* print(f"Exception in thread {thread.name}:", file=file) */
1350 if (PyFile_WriteString("Exception in thread ", file) < 0) {
1351 return -1;
1352 }
1353
1354 PyObject *name = NULL;
1355 if (thread != Py_None) {
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001356 if (_PyObject_LookupAttrId(thread, &PyId_name, &name) < 0) {
1357 return -1;
1358 }
Victor Stinnercd590a72019-05-28 00:39:52 +02001359 }
1360 if (name != NULL) {
1361 if (PyFile_WriteObject(name, file, Py_PRINT_RAW) < 0) {
1362 Py_DECREF(name);
1363 return -1;
1364 }
1365 Py_DECREF(name);
1366 }
1367 else {
Victor Stinnercd590a72019-05-28 00:39:52 +02001368 unsigned long ident = PyThread_get_thread_ident();
1369 PyObject *str = PyUnicode_FromFormat("%lu", ident);
1370 if (str != NULL) {
1371 if (PyFile_WriteObject(str, file, Py_PRINT_RAW) < 0) {
1372 Py_DECREF(str);
1373 return -1;
1374 }
1375 Py_DECREF(str);
1376 }
1377 else {
1378 PyErr_Clear();
1379
1380 if (PyFile_WriteString("<failed to get thread name>", file) < 0) {
1381 return -1;
1382 }
1383 }
1384 }
1385
1386 if (PyFile_WriteString(":\n", file) < 0) {
1387 return -1;
1388 }
1389
1390 /* Display the traceback */
1391 _PyErr_Display(file, exc_type, exc_value, exc_traceback);
1392
1393 /* Call file.flush() */
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001394 PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
Victor Stinnercd590a72019-05-28 00:39:52 +02001395 if (!res) {
1396 return -1;
1397 }
1398 Py_DECREF(res);
1399
1400 return 0;
1401}
1402
1403
1404PyDoc_STRVAR(ExceptHookArgs__doc__,
1405"ExceptHookArgs\n\
1406\n\
1407Type used to pass arguments to threading.excepthook.");
1408
1409static PyTypeObject ExceptHookArgsType;
1410
1411static PyStructSequence_Field ExceptHookArgs_fields[] = {
1412 {"exc_type", "Exception type"},
1413 {"exc_value", "Exception value"},
1414 {"exc_traceback", "Exception traceback"},
1415 {"thread", "Thread"},
1416 {0}
1417};
1418
1419static PyStructSequence_Desc ExceptHookArgs_desc = {
1420 .name = "_thread.ExceptHookArgs",
1421 .doc = ExceptHookArgs__doc__,
1422 .fields = ExceptHookArgs_fields,
1423 .n_in_sequence = 4
1424};
1425
1426
1427static PyObject *
1428thread_excepthook(PyObject *self, PyObject *args)
1429{
Andy Lester55728702020-03-06 16:53:17 -06001430 if (!Py_IS_TYPE(args, &ExceptHookArgsType)) {
Victor Stinnercd590a72019-05-28 00:39:52 +02001431 PyErr_SetString(PyExc_TypeError,
1432 "_thread.excepthook argument type "
1433 "must be ExceptHookArgs");
1434 return NULL;
1435 }
1436
1437 /* Borrowed reference */
1438 PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0);
1439 if (exc_type == PyExc_SystemExit) {
1440 /* silently ignore SystemExit */
1441 Py_RETURN_NONE;
1442 }
1443
1444 /* Borrowed references */
1445 PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1);
1446 PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
1447 PyObject *thread = PyStructSequence_GET_ITEM(args, 3);
1448
1449 PyObject *file = _PySys_GetObjectId(&PyId_stderr);
1450 if (file == NULL || file == Py_None) {
1451 if (thread == Py_None) {
1452 /* do nothing if sys.stderr is None and thread is None */
1453 Py_RETURN_NONE;
1454 }
1455
1456 file = PyObject_GetAttrString(thread, "_stderr");
1457 if (file == NULL) {
1458 return NULL;
1459 }
1460 if (file == Py_None) {
1461 Py_DECREF(file);
1462 /* do nothing if sys.stderr is None and sys.stderr was None
1463 when the thread was created */
1464 Py_RETURN_NONE;
1465 }
1466 }
1467 else {
1468 Py_INCREF(file);
1469 }
1470
1471 int res = thread_excepthook_file(file, exc_type, exc_value, exc_tb,
1472 thread);
1473 Py_DECREF(file);
1474 if (res < 0) {
1475 return NULL;
1476 }
1477
1478 Py_RETURN_NONE;
1479}
1480
1481PyDoc_STRVAR(excepthook_doc,
1482"excepthook(exc_type, exc_value, exc_traceback, thread)\n\
1483\n\
1484Handle uncaught Thread.run() exception.");
1485
Barry Warsawd0c10421996-12-17 00:05:22 +00001486static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001488 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001490 METH_VARARGS, start_new_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301491 {"allocate_lock", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301493 {"allocate", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301495 {"exit_thread", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301497 {"exit", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301499 {"interrupt_main", thread_PyThread_interrupt_main,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 METH_NOARGS, interrupt_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301501 {"get_ident", thread_get_ident,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 METH_NOARGS, get_ident_doc},
Jake Teslerb121f632019-05-22 08:43:17 -07001503#ifdef PY_HAVE_THREAD_NATIVE_ID
1504 {"get_native_id", thread_get_native_id,
1505 METH_NOARGS, get_native_id_doc},
1506#endif
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301507 {"_count", thread__count,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 METH_NOARGS, _count_doc},
1509 {"stack_size", (PyCFunction)thread_stack_size,
Victor Stinner754851f2011-04-19 23:58:51 +02001510 METH_VARARGS, stack_size_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301511 {"_set_sentinel", thread__set_sentinel,
Antoine Pitrou7b476992013-09-07 23:38:37 +02001512 METH_NOARGS, _set_sentinel_doc},
Victor Stinnercd590a72019-05-28 00:39:52 +02001513 {"_excepthook", thread_excepthook,
1514 METH_O, excepthook_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001516};
1517
1518
1519/* Initialization function */
1520
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001521PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001522"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001523The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001524
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001525PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001526"A lock object is a synchronization primitive. To create a lock,\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001527call threading.Lock(). Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001528\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001529acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1530release() -- unlock of the lock\n\
1531locked() -- test whether the lock is currently locked\n\
1532\n\
1533A lock is not owned by the thread that locked it; another thread may\n\
1534unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001535will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001536
Martin v. Löwis1a214512008-06-11 05:26:20 +00001537static struct PyModuleDef threadmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 PyModuleDef_HEAD_INIT,
1539 "_thread",
1540 thread_doc,
1541 -1,
1542 thread_methods,
1543 NULL,
1544 NULL,
1545 NULL,
1546 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001547};
1548
1549
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001550PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001551PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001552{
Victor Stinnerf5faad22015-03-28 03:52:05 +01001553 PyObject *m, *d, *v;
1554 double time_max;
1555 double timeout_max;
Victor Stinner81a7be32020-04-14 15:14:01 +02001556 PyInterpreterState *interp = _PyInterpreterState_GET();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 /* Initialize types: */
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001559 if (PyType_Ready(&localdummytype) < 0)
1560 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 if (PyType_Ready(&localtype) < 0)
1562 return NULL;
1563 if (PyType_Ready(&Locktype) < 0)
1564 return NULL;
1565 if (PyType_Ready(&RLocktype) < 0)
1566 return NULL;
Victor Stinnercd590a72019-05-28 00:39:52 +02001567 if (ExceptHookArgsType.tp_name == NULL) {
1568 if (PyStructSequence_InitType2(&ExceptHookArgsType,
1569 &ExceptHookArgs_desc) < 0) {
1570 return NULL;
1571 }
1572 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 /* Create the module and add the functions */
1575 m = PyModule_Create(&threadmodule);
1576 if (m == NULL)
1577 return NULL;
Antoine Pitrou7c3e5772010-04-14 15:44:10 +00001578
Victor Stinnerc319eee2017-11-30 23:03:47 +01001579 timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6;
Victor Stinner850a18e2017-10-24 16:53:32 -07001580 time_max = _PyTime_AsSecondsDouble(_PyTime_MAX);
Victor Stinnerf5faad22015-03-28 03:52:05 +01001581 timeout_max = Py_MIN(timeout_max, time_max);
Victor Stinner850a18e2017-10-24 16:53:32 -07001582 /* Round towards minus infinity */
1583 timeout_max = floor(timeout_max);
Victor Stinnerf5faad22015-03-28 03:52:05 +01001584
1585 v = PyFloat_FromDouble(timeout_max);
1586 if (!v)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001587 return NULL;
Victor Stinnerf5faad22015-03-28 03:52:05 +01001588 if (PyModule_AddObject(m, "TIMEOUT_MAX", v) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 /* Add a symbolic constant */
1592 d = PyModule_GetDict(m);
Antoine Pitroufcf81fd2011-02-28 22:03:34 +00001593 ThreadError = PyExc_RuntimeError;
1594 Py_INCREF(ThreadError);
Victor Stinner754851f2011-04-19 23:58:51 +02001595
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001596 PyDict_SetItemString(d, "error", ThreadError);
1597 Locktype.tp_doc = lock_doc;
1598 Py_INCREF(&Locktype);
1599 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Antoine Pitrou434736a2009-11-10 18:46:01 +00001600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 Py_INCREF(&RLocktype);
1602 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1603 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 Py_INCREF(&localtype);
1606 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1607 return NULL;
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001608
Victor Stinnercd590a72019-05-28 00:39:52 +02001609 Py_INCREF(&ExceptHookArgsType);
1610 if (PyModule_AddObject(m, "_ExceptHookArgs",
1611 (PyObject *)&ExceptHookArgsType) < 0)
1612 return NULL;
1613
Victor Stinnercaba55b2018-08-03 15:33:52 +02001614 interp->num_threads = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +00001616 str_dict = PyUnicode_InternFromString("__dict__");
1617 if (str_dict == NULL)
1618 return NULL;
1619
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 /* Initialize the C thread library */
1621 PyThread_init_thread();
1622 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001623}