blob: 86d5f544fcf0fa594c4277a7b149f68433d6f803 [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 }
Victor Stinner32bd68c2020-12-01 10:37:39 +010037 PyObject_Free(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 Storchakafb5db7e2020-10-26 08:43:39 +0200819 if (tstate->dict) {
820 PyObject *v = _PyDict_Pop(tstate->dict, self->key, Py_None);
821 if (v == NULL) {
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200822 PyErr_Clear();
823 }
Serhiy Storchakafb5db7e2020-10-26 08:43:39 +0200824 else {
825 Py_DECREF(v);
826 }
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200827 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000828 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000829 return 0;
830}
Jim Fultond15dc062004-07-14 19:11:50 +0000831
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000832static void
833local_dealloc(localobject *self)
834{
835 /* Weakrefs must be invalidated right now, otherwise they can be used
836 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
837 if (self->weakreflist != NULL)
838 PyObject_ClearWeakRefs((PyObject *) self);
839
840 PyObject_GC_UnTrack(self);
841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000843 Py_XDECREF(self->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000844 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000845}
846
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000847/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000848static PyObject *
849_ldict(localobject *self)
850{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000851 PyObject *tdict, *ldict, *dummy;
Jim Fultond15dc062004-07-14 19:11:50 +0000852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 tdict = PyThreadState_GetDict();
854 if (tdict == NULL) {
855 PyErr_SetString(PyExc_SystemError,
856 "Couldn't get thread-state dictionary");
857 return NULL;
858 }
Jim Fultond15dc062004-07-14 19:11:50 +0000859
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200860 dummy = PyDict_GetItemWithError(tdict, self->key);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000861 if (dummy == NULL) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200862 if (PyErr_Occurred()) {
863 return NULL;
864 }
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000865 ldict = _local_create_dummy(self);
866 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000867 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000869 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
870 Py_TYPE(self)->tp_init((PyObject*)self,
871 self->args, self->kw) < 0) {
872 /* we need to get rid of ldict from thread so
873 we create a new one the next time we do an attr
Ezio Melotti42da6632011-03-15 05:18:48 +0200874 access */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000875 PyDict_DelItem(tdict, self->key);
876 return NULL;
877 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000878 }
879 else {
Andy Lesterdffe4c02020-03-04 07:15:20 -0600880 assert(Py_IS_TYPE(dummy, &localdummytype));
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000881 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000882 }
Jim Fultond15dc062004-07-14 19:11:50 +0000883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000884 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000885}
886
Jim Fultond15dc062004-07-14 19:11:50 +0000887static int
888local_setattro(localobject *self, PyObject *name, PyObject *v)
889{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000890 PyObject *ldict;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000891 int r;
Jim Fultond15dc062004-07-14 19:11:50 +0000892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000893 ldict = _ldict(self);
894 if (ldict == NULL)
895 return -1;
896
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000897 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
898 if (r == 1) {
899 PyErr_Format(PyExc_AttributeError,
900 "'%.50s' object attribute '%U' is read-only",
901 Py_TYPE(self)->tp_name, name);
902 return -1;
903 }
904 if (r == -1)
905 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000906
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000907 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000908}
909
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000910static PyObject *local_getattro(localobject *, PyObject *);
911
Jim Fultond15dc062004-07-14 19:11:50 +0000912static PyTypeObject localtype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 PyVarObject_HEAD_INIT(NULL, 0)
914 /* tp_name */ "_thread._local",
915 /* tp_basicsize */ sizeof(localobject),
916 /* tp_itemsize */ 0,
917 /* tp_dealloc */ (destructor)local_dealloc,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200918 /* tp_vectorcall_offset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000919 /* tp_getattr */ 0,
920 /* tp_setattr */ 0,
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200921 /* tp_as_async */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 /* tp_repr */ 0,
923 /* tp_as_number */ 0,
924 /* tp_as_sequence */ 0,
925 /* tp_as_mapping */ 0,
926 /* tp_hash */ 0,
927 /* tp_call */ 0,
928 /* tp_str */ 0,
929 /* tp_getattro */ (getattrofunc)local_getattro,
930 /* tp_setattro */ (setattrofunc)local_setattro,
931 /* tp_as_buffer */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000932 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
933 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000934 /* tp_doc */ "Thread-local data",
935 /* tp_traverse */ (traverseproc)local_traverse,
936 /* tp_clear */ (inquiry)local_clear,
937 /* tp_richcompare */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000938 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000939 /* tp_iter */ 0,
940 /* tp_iternext */ 0,
941 /* tp_methods */ 0,
942 /* tp_members */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000943 /* tp_getset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000944 /* tp_base */ 0,
945 /* tp_dict */ 0, /* internal use */
946 /* tp_descr_get */ 0,
947 /* tp_descr_set */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000948 /* tp_dictoffset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 /* tp_init */ 0,
950 /* tp_alloc */ 0,
951 /* tp_new */ local_new,
952 /* tp_free */ 0, /* Low-level free-mem routine */
953 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000954};
955
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000956static PyObject *
957local_getattro(localobject *self, PyObject *name)
958{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959 PyObject *ldict, *value;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000960 int r;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000961
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 ldict = _ldict(self);
963 if (ldict == NULL)
964 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000965
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000966 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
967 if (r == 1) {
968 Py_INCREF(ldict);
969 return ldict;
970 }
971 if (r == -1)
972 return NULL;
973
Andy Lester55728702020-03-06 16:53:17 -0600974 if (!Py_IS_TYPE(self, &localtype))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 /* use generic lookup for subtypes */
INADA Naoki378edee2018-01-16 20:52:41 +0900976 return _PyObject_GenericGetAttrWithDict(
977 (PyObject *)self, name, ldict, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 /* Optimization: just look in dict ourselves */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200980 value = PyDict_GetItemWithError(ldict, name);
981 if (value != NULL) {
982 Py_INCREF(value);
983 return value;
984 }
985 else if (PyErr_Occurred()) {
986 return NULL;
987 }
988 /* Fall back on generic to get __class__ and __dict__ */
989 return _PyObject_GenericGetAttrWithDict(
990 (PyObject *)self, name, ldict, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000991}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000992
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000993/* Called when a dummy is destroyed. */
994static PyObject *
995_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
996{
997 PyObject *obj;
998 localobject *self;
999 assert(PyWeakref_CheckRef(localweakref));
1000 obj = PyWeakref_GET_OBJECT(localweakref);
1001 if (obj == Py_None)
1002 Py_RETURN_NONE;
1003 Py_INCREF(obj);
1004 assert(PyObject_TypeCheck(obj, &localtype));
1005 /* If the thread-local object is still alive and not being cleared,
1006 remove the corresponding local dict */
1007 self = (localobject *) obj;
1008 if (self->dummies != NULL) {
1009 PyObject *ldict;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001010 ldict = PyDict_GetItemWithError(self->dummies, dummyweakref);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001011 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001012 PyDict_DelItem(self->dummies, dummyweakref);
1013 }
1014 if (PyErr_Occurred())
1015 PyErr_WriteUnraisable(obj);
1016 }
1017 Py_DECREF(obj);
1018 Py_RETURN_NONE;
1019}
1020
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001021/* Module functions */
1022
Guido van Rossuma027efa1997-05-05 20:56:21 +00001023struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024 PyInterpreterState *interp;
1025 PyObject *func;
1026 PyObject *args;
1027 PyObject *keyw;
1028 PyThreadState *tstate;
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001029 _PyRuntimeState *runtime;
Guido van Rossuma027efa1997-05-05 20:56:21 +00001030};
1031
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001032static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001033t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001034{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 struct bootstate *boot = (struct bootstate *) boot_raw;
1036 PyThreadState *tstate;
1037 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 tstate = boot->tstate;
1040 tstate->thread_id = PyThread_get_thread_ident();
Victor Stinner01b1cc12019-11-20 02:27:56 +01001041 _PyThreadState_Init(tstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 PyEval_AcquireThread(tstate);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001043 tstate->interp->num_threads++;
INADA Naoki72dccde2017-02-16 09:26:01 +09001044 res = PyObject_Call(boot->func, boot->args, boot->keyw);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 if (res == NULL) {
1046 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Victor Stinner8b095002019-05-29 02:57:56 +02001047 /* SystemExit is ignored silently */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 PyErr_Clear();
1049 else {
Victor Stinner8b095002019-05-29 02:57:56 +02001050 _PyErr_WriteUnraisableMsg("in thread started by", boot->func);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 }
1052 }
Victor Stinner8b095002019-05-29 02:57:56 +02001053 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 Py_DECREF(res);
Victor Stinner8b095002019-05-29 02:57:56 +02001055 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 Py_DECREF(boot->func);
1057 Py_DECREF(boot->args);
1058 Py_XDECREF(boot->keyw);
Victor Stinner00d7abd2020-12-01 09:56:42 +01001059 PyMem_Free(boot_raw);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001060 tstate->interp->num_threads--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 PyThreadState_Clear(tstate);
Victor Stinner23ef89d2020-03-18 02:26:04 +01001062 _PyThreadState_DeleteCurrent(tstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001064}
1065
Barry Warsawd0c10421996-12-17 00:05:22 +00001066static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001067thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001068{
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001069 _PyRuntimeState *runtime = &_PyRuntime;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 PyObject *func, *args, *keyw = NULL;
1071 struct bootstate *boot;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001072 unsigned long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
1075 &func, &args, &keyw))
1076 return NULL;
1077 if (!PyCallable_Check(func)) {
1078 PyErr_SetString(PyExc_TypeError,
1079 "first arg must be callable");
1080 return NULL;
1081 }
1082 if (!PyTuple_Check(args)) {
1083 PyErr_SetString(PyExc_TypeError,
1084 "2nd arg must be a tuple");
1085 return NULL;
1086 }
1087 if (keyw != NULL && !PyDict_Check(keyw)) {
1088 PyErr_SetString(PyExc_TypeError,
1089 "optional 3rd arg must be a dictionary");
1090 return NULL;
1091 }
Victor Stinner252346a2020-05-01 11:33:44 +02001092
1093 PyInterpreterState *interp = _PyInterpreterState_GET();
1094 if (interp->config._isolated_interpreter) {
1095 PyErr_SetString(PyExc_RuntimeError,
1096 "thread is not supported for isolated subinterpreters");
1097 return NULL;
1098 }
1099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 boot = PyMem_NEW(struct bootstate, 1);
1101 if (boot == NULL)
1102 return PyErr_NoMemory();
Victor Stinner81a7be32020-04-14 15:14:01 +02001103 boot->interp = _PyInterpreterState_GET();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 boot->func = func;
1105 boot->args = args;
1106 boot->keyw = keyw;
1107 boot->tstate = _PyThreadState_Prealloc(boot->interp);
Joannah Nanjekye2bc43cd2019-09-05 13:06:49 -03001108 boot->runtime = runtime;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001109 if (boot->tstate == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01001110 PyMem_Free(boot);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001111 return PyErr_NoMemory();
1112 }
1113 Py_INCREF(func);
1114 Py_INCREF(args);
1115 Py_XINCREF(keyw);
Victor Stinner3225b9f2020-03-09 20:56:57 +01001116
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001118 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001119 PyErr_SetString(ThreadError, "can't start new thread");
1120 Py_DECREF(func);
1121 Py_DECREF(args);
1122 Py_XDECREF(keyw);
1123 PyThreadState_Clear(boot->tstate);
Victor Stinner00d7abd2020-12-01 09:56:42 +01001124 PyMem_Free(boot);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 return NULL;
1126 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001127 return PyLong_FromUnsignedLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001128}
1129
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001130PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001131"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001132(start_new() is an obsolete synonym)\n\
1133\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001134Start a new thread and return its identifier. The thread will call the\n\
1135function with positional arguments from the tuple args and keyword arguments\n\
1136taken from the optional dictionary kwargs. The thread exits when the\n\
1137function returns; the return value is ignored. The thread will also exit\n\
1138when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001139printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001140
Barry Warsawd0c10421996-12-17 00:05:22 +00001141static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301142thread_PyThread_exit_thread(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001143{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 PyErr_SetNone(PyExc_SystemExit);
1145 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001146}
1147
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001148PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001149"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001150(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001151\n\
1152This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001153thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001154
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001155static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301156thread_PyThread_interrupt_main(PyObject * self, PyObject *Py_UNUSED(ignored))
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001157{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 PyErr_SetInterrupt();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001159 Py_RETURN_NONE;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001160}
1161
1162PyDoc_STRVAR(interrupt_doc,
1163"interrupt_main()\n\
1164\n\
1165Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001166A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001167);
1168
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001169static lockobject *newlockobject(void);
1170
Barry Warsawd0c10421996-12-17 00:05:22 +00001171static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301172thread_PyThread_allocate_lock(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001175}
1176
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001177PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001178"allocate_lock() -> lock object\n\
1179(allocate() is an obsolete synonym)\n\
1180\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001181Create a new lock object. See help(type(threading.Lock())) for\n\
1182information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001183
Barry Warsawd0c10421996-12-17 00:05:22 +00001184static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301185thread_get_ident(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001186{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001187 unsigned long ident = PyThread_get_thread_ident();
1188 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 PyErr_SetString(ThreadError, "no current thread ident");
1190 return NULL;
1191 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001192 return PyLong_FromUnsignedLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001193}
1194
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001195PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001196"get_ident() -> integer\n\
1197\n\
1198Return a non-zero integer that uniquely identifies the current thread\n\
1199amongst other threads that exist simultaneously.\n\
1200This may be used to identify per-thread resources.\n\
1201Even though on some platforms threads identities may appear to be\n\
1202allocated consecutive numbers starting at 1, this behavior should not\n\
1203be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001204A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001205
Jake Teslerb121f632019-05-22 08:43:17 -07001206#ifdef PY_HAVE_THREAD_NATIVE_ID
1207static PyObject *
1208thread_get_native_id(PyObject *self, PyObject *Py_UNUSED(ignored))
1209{
1210 unsigned long native_id = PyThread_get_thread_native_id();
1211 return PyLong_FromUnsignedLong(native_id);
1212}
1213
1214PyDoc_STRVAR(get_native_id_doc,
1215"get_native_id() -> integer\n\
1216\n\
1217Return a non-negative integer identifying the thread as reported\n\
1218by the OS (kernel). This may be used to uniquely identify a\n\
1219particular thread within a system.");
1220#endif
1221
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001222static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301223thread__count(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001224{
Victor Stinner81a7be32020-04-14 15:14:01 +02001225 PyInterpreterState *interp = _PyInterpreterState_GET();
Victor Stinnercaba55b2018-08-03 15:33:52 +02001226 return PyLong_FromLong(interp->num_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001227}
1228
1229PyDoc_STRVAR(_count_doc,
1230"_count() -> integer\n\
1231\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001232\
oldkaa0735f2018-02-02 16:52:55 +08001233Return the number of currently running Python threads, excluding\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001234the main thread. The returned number comprises all threads created\n\
1235through `start_new_thread()` as well as `threading.Thread`, and not\n\
1236yet finished.\n\
1237\n\
1238This function is meant for internal and specialized purposes only.\n\
1239In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001240
Antoine Pitrou7b476992013-09-07 23:38:37 +02001241static void
Victor Stinnera42de742018-11-22 10:25:22 +01001242release_sentinel(void *wr_raw)
Antoine Pitrou7b476992013-09-07 23:38:37 +02001243{
Victor Stinnera42de742018-11-22 10:25:22 +01001244 PyObject *wr = _PyObject_CAST(wr_raw);
Antoine Pitrou7b476992013-09-07 23:38:37 +02001245 /* Tricky: this function is called when the current thread state
1246 is being deleted. Therefore, only simple C code can safely
1247 execute here. */
1248 PyObject *obj = PyWeakref_GET_OBJECT(wr);
1249 lockobject *lock;
1250 if (obj != Py_None) {
Andy Lesterdffe4c02020-03-04 07:15:20 -06001251 assert(Py_IS_TYPE(obj, &Locktype));
Antoine Pitrou7b476992013-09-07 23:38:37 +02001252 lock = (lockobject *) obj;
1253 if (lock->locked) {
1254 PyThread_release_lock(lock->lock_lock);
1255 lock->locked = 0;
1256 }
1257 }
1258 /* Deallocating a weakref with a NULL callback only calls
1259 PyObject_GC_Del(), which can't call any Python code. */
1260 Py_DECREF(wr);
1261}
1262
1263static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301264thread__set_sentinel(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou7b476992013-09-07 23:38:37 +02001265{
1266 PyObject *wr;
1267 PyThreadState *tstate = PyThreadState_Get();
1268 lockobject *lock;
1269
1270 if (tstate->on_delete_data != NULL) {
1271 /* We must support the re-creation of the lock from a
1272 fork()ed child. */
1273 assert(tstate->on_delete == &release_sentinel);
1274 wr = (PyObject *) tstate->on_delete_data;
1275 tstate->on_delete = NULL;
1276 tstate->on_delete_data = NULL;
1277 Py_DECREF(wr);
1278 }
1279 lock = newlockobject();
1280 if (lock == NULL)
1281 return NULL;
1282 /* The lock is owned by whoever called _set_sentinel(), but the weakref
1283 hangs to the thread state. */
1284 wr = PyWeakref_NewRef((PyObject *) lock, NULL);
1285 if (wr == NULL) {
1286 Py_DECREF(lock);
1287 return NULL;
1288 }
1289 tstate->on_delete_data = (void *) wr;
1290 tstate->on_delete = &release_sentinel;
1291 return (PyObject *) lock;
1292}
1293
1294PyDoc_STRVAR(_set_sentinel_doc,
1295"_set_sentinel() -> lock\n\
1296\n\
1297Set a sentinel lock that will be released when the current thread\n\
1298state is finalized (after it is untied from the interpreter).\n\
1299\n\
1300This is a private API for the threading module.");
1301
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001302static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001303thread_stack_size(PyObject *self, PyObject *args)
1304{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 size_t old_size;
1306 Py_ssize_t new_size = 0;
1307 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1310 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 if (new_size < 0) {
1313 PyErr_SetString(PyExc_ValueError,
1314 "size must be 0 or a positive value");
1315 return NULL;
1316 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 rc = PyThread_set_stacksize((size_t) new_size);
1321 if (rc == -1) {
1322 PyErr_Format(PyExc_ValueError,
1323 "size not valid: %zd bytes",
1324 new_size);
1325 return NULL;
1326 }
1327 if (rc == -2) {
1328 PyErr_SetString(ThreadError,
1329 "setting stack size not supported");
1330 return NULL;
1331 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001334}
1335
1336PyDoc_STRVAR(stack_size_doc,
1337"stack_size([size]) -> size\n\
1338\n\
1339Return the thread stack size used when creating new threads. The\n\
1340optional size argument specifies the stack size (in bytes) to be used\n\
1341for subsequently created threads, and must be 0 (use platform or\n\
1342configured default) or a positive integer value of at least 32,768 (32k).\n\
1343If changing the thread stack size is unsupported, a ThreadError\n\
1344exception is raised. If the specified size is invalid, a ValueError\n\
1345exception is raised, and the stack size is unmodified. 32k bytes\n\
1346 currently the minimum supported stack size value to guarantee\n\
1347sufficient stack space for the interpreter itself.\n\
1348\n\
1349Note that some platforms may have particular restrictions on values for\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001350the stack size, such as requiring a minimum stack size larger than 32 KiB or\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001351requiring allocation in multiples of the system memory page size\n\
1352- platform documentation should be referred to for more information\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001353(4 KiB pages are common; using multiples of 4096 for the stack size is\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001354the suggested approach in the absence of more specific information).");
1355
Victor Stinnercd590a72019-05-28 00:39:52 +02001356static int
1357thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value,
1358 PyObject *exc_traceback, PyObject *thread)
1359{
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001360 _Py_IDENTIFIER(name);
Victor Stinnercd590a72019-05-28 00:39:52 +02001361 /* print(f"Exception in thread {thread.name}:", file=file) */
1362 if (PyFile_WriteString("Exception in thread ", file) < 0) {
1363 return -1;
1364 }
1365
1366 PyObject *name = NULL;
1367 if (thread != Py_None) {
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03001368 if (_PyObject_LookupAttrId(thread, &PyId_name, &name) < 0) {
1369 return -1;
1370 }
Victor Stinnercd590a72019-05-28 00:39:52 +02001371 }
1372 if (name != NULL) {
1373 if (PyFile_WriteObject(name, file, Py_PRINT_RAW) < 0) {
1374 Py_DECREF(name);
1375 return -1;
1376 }
1377 Py_DECREF(name);
1378 }
1379 else {
Victor Stinnercd590a72019-05-28 00:39:52 +02001380 unsigned long ident = PyThread_get_thread_ident();
1381 PyObject *str = PyUnicode_FromFormat("%lu", ident);
1382 if (str != NULL) {
1383 if (PyFile_WriteObject(str, file, Py_PRINT_RAW) < 0) {
1384 Py_DECREF(str);
1385 return -1;
1386 }
1387 Py_DECREF(str);
1388 }
1389 else {
1390 PyErr_Clear();
1391
1392 if (PyFile_WriteString("<failed to get thread name>", file) < 0) {
1393 return -1;
1394 }
1395 }
1396 }
1397
1398 if (PyFile_WriteString(":\n", file) < 0) {
1399 return -1;
1400 }
1401
1402 /* Display the traceback */
1403 _PyErr_Display(file, exc_type, exc_value, exc_traceback);
1404
1405 /* Call file.flush() */
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001406 PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
Victor Stinnercd590a72019-05-28 00:39:52 +02001407 if (!res) {
1408 return -1;
1409 }
1410 Py_DECREF(res);
1411
1412 return 0;
1413}
1414
1415
1416PyDoc_STRVAR(ExceptHookArgs__doc__,
1417"ExceptHookArgs\n\
1418\n\
1419Type used to pass arguments to threading.excepthook.");
1420
1421static PyTypeObject ExceptHookArgsType;
1422
1423static PyStructSequence_Field ExceptHookArgs_fields[] = {
1424 {"exc_type", "Exception type"},
1425 {"exc_value", "Exception value"},
1426 {"exc_traceback", "Exception traceback"},
1427 {"thread", "Thread"},
1428 {0}
1429};
1430
1431static PyStructSequence_Desc ExceptHookArgs_desc = {
1432 .name = "_thread.ExceptHookArgs",
1433 .doc = ExceptHookArgs__doc__,
1434 .fields = ExceptHookArgs_fields,
1435 .n_in_sequence = 4
1436};
1437
1438
1439static PyObject *
1440thread_excepthook(PyObject *self, PyObject *args)
1441{
Andy Lester55728702020-03-06 16:53:17 -06001442 if (!Py_IS_TYPE(args, &ExceptHookArgsType)) {
Victor Stinnercd590a72019-05-28 00:39:52 +02001443 PyErr_SetString(PyExc_TypeError,
1444 "_thread.excepthook argument type "
1445 "must be ExceptHookArgs");
1446 return NULL;
1447 }
1448
1449 /* Borrowed reference */
1450 PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0);
1451 if (exc_type == PyExc_SystemExit) {
1452 /* silently ignore SystemExit */
1453 Py_RETURN_NONE;
1454 }
1455
1456 /* Borrowed references */
1457 PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1);
1458 PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
1459 PyObject *thread = PyStructSequence_GET_ITEM(args, 3);
1460
1461 PyObject *file = _PySys_GetObjectId(&PyId_stderr);
1462 if (file == NULL || file == Py_None) {
1463 if (thread == Py_None) {
1464 /* do nothing if sys.stderr is None and thread is None */
1465 Py_RETURN_NONE;
1466 }
1467
1468 file = PyObject_GetAttrString(thread, "_stderr");
1469 if (file == NULL) {
1470 return NULL;
1471 }
1472 if (file == Py_None) {
1473 Py_DECREF(file);
1474 /* do nothing if sys.stderr is None and sys.stderr was None
1475 when the thread was created */
1476 Py_RETURN_NONE;
1477 }
1478 }
1479 else {
1480 Py_INCREF(file);
1481 }
1482
1483 int res = thread_excepthook_file(file, exc_type, exc_value, exc_tb,
1484 thread);
1485 Py_DECREF(file);
1486 if (res < 0) {
1487 return NULL;
1488 }
1489
1490 Py_RETURN_NONE;
1491}
1492
1493PyDoc_STRVAR(excepthook_doc,
1494"excepthook(exc_type, exc_value, exc_traceback, thread)\n\
1495\n\
1496Handle uncaught Thread.run() exception.");
1497
Barry Warsawd0c10421996-12-17 00:05:22 +00001498static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001500 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001502 METH_VARARGS, start_new_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301503 {"allocate_lock", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301505 {"allocate", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301507 {"exit_thread", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301509 {"exit", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301511 {"interrupt_main", thread_PyThread_interrupt_main,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 METH_NOARGS, interrupt_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301513 {"get_ident", thread_get_ident,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 METH_NOARGS, get_ident_doc},
Jake Teslerb121f632019-05-22 08:43:17 -07001515#ifdef PY_HAVE_THREAD_NATIVE_ID
1516 {"get_native_id", thread_get_native_id,
1517 METH_NOARGS, get_native_id_doc},
1518#endif
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301519 {"_count", thread__count,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 METH_NOARGS, _count_doc},
1521 {"stack_size", (PyCFunction)thread_stack_size,
Victor Stinner754851f2011-04-19 23:58:51 +02001522 METH_VARARGS, stack_size_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301523 {"_set_sentinel", thread__set_sentinel,
Antoine Pitrou7b476992013-09-07 23:38:37 +02001524 METH_NOARGS, _set_sentinel_doc},
Victor Stinnercd590a72019-05-28 00:39:52 +02001525 {"_excepthook", thread_excepthook,
1526 METH_O, excepthook_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001528};
1529
1530
1531/* Initialization function */
1532
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001533PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001534"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001535The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001536
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001537PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001538"A lock object is a synchronization primitive. To create a lock,\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001539call threading.Lock(). Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001540\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001541acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1542release() -- unlock of the lock\n\
1543locked() -- test whether the lock is currently locked\n\
1544\n\
1545A lock is not owned by the thread that locked it; another thread may\n\
1546unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001547will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001548
Martin v. Löwis1a214512008-06-11 05:26:20 +00001549static struct PyModuleDef threadmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001550 PyModuleDef_HEAD_INIT,
1551 "_thread",
1552 thread_doc,
1553 -1,
1554 thread_methods,
1555 NULL,
1556 NULL,
1557 NULL,
1558 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001559};
1560
1561
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001562PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001563PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001564{
Victor Stinnerf5faad22015-03-28 03:52:05 +01001565 PyObject *m, *d, *v;
1566 double time_max;
1567 double timeout_max;
Victor Stinner81a7be32020-04-14 15:14:01 +02001568 PyInterpreterState *interp = _PyInterpreterState_GET();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001569
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 /* Initialize types: */
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001571 if (PyType_Ready(&localdummytype) < 0)
1572 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 if (PyType_Ready(&localtype) < 0)
1574 return NULL;
1575 if (PyType_Ready(&Locktype) < 0)
1576 return NULL;
1577 if (PyType_Ready(&RLocktype) < 0)
1578 return NULL;
Victor Stinnercd590a72019-05-28 00:39:52 +02001579 if (ExceptHookArgsType.tp_name == NULL) {
1580 if (PyStructSequence_InitType2(&ExceptHookArgsType,
1581 &ExceptHookArgs_desc) < 0) {
1582 return NULL;
1583 }
1584 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 /* Create the module and add the functions */
1587 m = PyModule_Create(&threadmodule);
1588 if (m == NULL)
1589 return NULL;
Antoine Pitrou7c3e5772010-04-14 15:44:10 +00001590
Victor Stinnerc319eee2017-11-30 23:03:47 +01001591 timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6;
Victor Stinner850a18e2017-10-24 16:53:32 -07001592 time_max = _PyTime_AsSecondsDouble(_PyTime_MAX);
Victor Stinnerf5faad22015-03-28 03:52:05 +01001593 timeout_max = Py_MIN(timeout_max, time_max);
Victor Stinner850a18e2017-10-24 16:53:32 -07001594 /* Round towards minus infinity */
1595 timeout_max = floor(timeout_max);
Victor Stinnerf5faad22015-03-28 03:52:05 +01001596
1597 v = PyFloat_FromDouble(timeout_max);
1598 if (!v)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 return NULL;
Victor Stinnerf5faad22015-03-28 03:52:05 +01001600 if (PyModule_AddObject(m, "TIMEOUT_MAX", v) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 /* Add a symbolic constant */
1604 d = PyModule_GetDict(m);
Antoine Pitroufcf81fd2011-02-28 22:03:34 +00001605 ThreadError = PyExc_RuntimeError;
1606 Py_INCREF(ThreadError);
Victor Stinner754851f2011-04-19 23:58:51 +02001607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 PyDict_SetItemString(d, "error", ThreadError);
1609 Locktype.tp_doc = lock_doc;
1610 Py_INCREF(&Locktype);
1611 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Antoine Pitrou434736a2009-11-10 18:46:01 +00001612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 Py_INCREF(&RLocktype);
1614 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1615 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001617 Py_INCREF(&localtype);
1618 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1619 return NULL;
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001620
Victor Stinnercd590a72019-05-28 00:39:52 +02001621 Py_INCREF(&ExceptHookArgsType);
1622 if (PyModule_AddObject(m, "_ExceptHookArgs",
1623 (PyObject *)&ExceptHookArgsType) < 0)
1624 return NULL;
1625
Victor Stinnercaba55b2018-08-03 15:33:52 +02001626 interp->num_threads = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +00001628 str_dict = PyUnicode_InternFromString("__dict__");
1629 if (str_dict == NULL)
1630 return NULL;
1631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 /* Initialize the C thread library */
1633 PyThread_init_thread();
1634 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001635}