blob: 3c02d8dd5145717ab8ff599161d4e189e784ce6f [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 Stinner621cebe2018-11-12 16:53:38 +01006#include "pycore_pystate.h"
Benjamin Petersonbec4d572009-10-10 01:16:07 +00007#include "structmember.h" /* offsetof */
Guido van Rossum49b56061998-10-01 20:42:43 +00008#include "pythread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +00009
Barry Warsawd0c10421996-12-17 00:05:22 +000010static PyObject *ThreadError;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +000011static PyObject *str_dict;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000012
Victor Stinnerbd303c12013-11-07 23:07:29 +010013_Py_IDENTIFIER(stderr);
14
Guido van Rossum1984f1e1992-08-04 12:41:02 +000015/* Lock objects */
16
17typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000018 PyObject_HEAD
19 PyThread_type_lock lock_lock;
20 PyObject *in_weakreflist;
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000021 char locked; /* for sanity checking */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000022} lockobject;
23
Guido van Rossum1984f1e1992-08-04 12:41:02 +000024static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000025lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000026{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000027 if (self->in_weakreflist != NULL)
28 PyObject_ClearWeakRefs((PyObject *) self);
29 if (self->lock_lock != NULL) {
30 /* Unlock the lock so it's safe to free it */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000031 if (self->locked)
32 PyThread_release_lock(self->lock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000033 PyThread_free_lock(self->lock_lock);
34 }
35 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000036}
37
Antoine Pitrou810023d2010-12-15 22:59:16 +000038/* Helper to acquire an interruptible lock with a timeout. If the lock acquire
39 * is interrupted, signal handlers are run, and if they raise an exception,
40 * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE
Raymond Hettinger15f44ab2016-08-30 10:47:49 -070041 * are returned, depending on whether the lock can be acquired within the
Antoine Pitrou810023d2010-12-15 22:59:16 +000042 * timeout.
43 */
44static PyLockStatus
Victor Stinnerf5faad22015-03-28 03:52:05 +010045acquire_timed(PyThread_type_lock lock, _PyTime_t timeout)
Antoine Pitrou810023d2010-12-15 22:59:16 +000046{
47 PyLockStatus r;
Victor Stinnerf5faad22015-03-28 03:52:05 +010048 _PyTime_t endtime = 0;
49 _PyTime_t microseconds;
Antoine Pitrou810023d2010-12-15 22:59:16 +000050
Victor Stinnerf5faad22015-03-28 03:52:05 +010051 if (timeout > 0)
52 endtime = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrou810023d2010-12-15 22:59:16 +000053
54 do {
Victor Stinner869e1772015-03-30 03:49:14 +020055 microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING);
Victor Stinnerf5faad22015-03-28 03:52:05 +010056
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000057 /* first a simple non-blocking try without releasing the GIL */
58 r = PyThread_acquire_lock_timed(lock, 0, 0);
59 if (r == PY_LOCK_FAILURE && microseconds != 0) {
60 Py_BEGIN_ALLOW_THREADS
61 r = PyThread_acquire_lock_timed(lock, microseconds, 1);
62 Py_END_ALLOW_THREADS
Victor Stinner357f5152013-11-05 15:10:19 +010063 }
Antoine Pitrou810023d2010-12-15 22:59:16 +000064
65 if (r == PY_LOCK_INTR) {
66 /* Run signal handlers if we were interrupted. Propagate
67 * exceptions from signal handlers, such as KeyboardInterrupt, by
68 * passing up PY_LOCK_INTR. */
69 if (Py_MakePendingCalls() < 0) {
70 return PY_LOCK_INTR;
71 }
72
73 /* If we're using a timeout, recompute the timeout after processing
74 * signals, since those can take time. */
Victor Stinnerf5faad22015-03-28 03:52:05 +010075 if (timeout > 0) {
76 timeout = endtime - _PyTime_GetMonotonicClock();
Antoine Pitrou810023d2010-12-15 22:59:16 +000077
78 /* Check for negative values, since those mean block forever.
79 */
Victor Stinner6aa446c2015-03-30 21:33:51 +020080 if (timeout < 0) {
Antoine Pitrou810023d2010-12-15 22:59:16 +000081 r = PY_LOCK_FAILURE;
82 }
83 }
84 }
85 } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */
86
87 return r;
88}
89
Victor Stinnerf5faad22015-03-28 03:52:05 +010090static int
91lock_acquire_parse_args(PyObject *args, PyObject *kwds,
92 _PyTime_t *timeout)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000093{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000094 char *kwlist[] = {"blocking", "timeout", NULL};
95 int blocking = 1;
Victor Stinnerf5faad22015-03-28 03:52:05 +010096 PyObject *timeout_obj = NULL;
Victor Stinner13019fd2015-04-03 13:10:54 +020097 const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000098
Victor Stinnerf5faad22015-03-28 03:52:05 +010099 *timeout = unset_timeout ;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000100
Victor Stinnerf5faad22015-03-28 03:52:05 +0100101 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:acquire", kwlist,
102 &blocking, &timeout_obj))
103 return -1;
104
105 if (timeout_obj
Victor Stinner869e1772015-03-30 03:49:14 +0200106 && _PyTime_FromSecondsObject(timeout,
Pablo Galindo59af94f2017-10-18 08:13:09 +0100107 timeout_obj, _PyTime_ROUND_TIMEOUT) < 0)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100108 return -1;
109
110 if (!blocking && *timeout != unset_timeout ) {
111 PyErr_SetString(PyExc_ValueError,
112 "can't specify a timeout for a non-blocking call");
113 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100115 if (*timeout < 0 && *timeout != unset_timeout) {
116 PyErr_SetString(PyExc_ValueError,
117 "timeout value must be positive");
118 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 }
120 if (!blocking)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100121 *timeout = 0;
122 else if (*timeout != unset_timeout) {
123 _PyTime_t microseconds;
124
Pablo Galindo59af94f2017-10-18 08:13:09 +0100125 microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinnerf5faad22015-03-28 03:52:05 +0100126 if (microseconds >= PY_TIMEOUT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 PyErr_SetString(PyExc_OverflowError,
128 "timeout value is too large");
Victor Stinnerf5faad22015-03-28 03:52:05 +0100129 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000131 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100132 return 0;
133}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000134
Victor Stinnerf5faad22015-03-28 03:52:05 +0100135static PyObject *
136lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
137{
138 _PyTime_t timeout;
139 PyLockStatus r;
140
141 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
142 return NULL;
143
144 r = acquire_timed(self->lock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000145 if (r == PY_LOCK_INTR) {
146 return NULL;
147 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000149 if (r == PY_LOCK_ACQUIRED)
150 self->locked = 1;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000151 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000152}
153
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000154PyDoc_STRVAR(acquire_doc,
Berker Peksag720e6552016-05-02 12:25:35 +0300155"acquire(blocking=True, timeout=-1) -> bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000156(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000157\n\
158Lock the lock. Without argument, this blocks if the lock is already\n\
159locked (even by the same thread), waiting for another thread to release\n\
R David Murray95b71102013-02-04 10:15:58 -0500160the lock, and return True once the lock is acquired.\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000161With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000162and the return value reflects whether the lock is acquired.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000163The blocking operation is interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000164
Barry Warsawd0c10421996-12-17 00:05:22 +0000165static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530166lock_PyThread_release_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 /* Sanity check: the lock must be locked */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000169 if (!self->locked) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000170 PyErr_SetString(ThreadError, "release unlocked lock");
171 return NULL;
172 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000174 PyThread_release_lock(self->lock_lock);
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000175 self->locked = 0;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200176 Py_RETURN_NONE;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000177}
178
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000179PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000180"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000181(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000182\n\
183Release the lock, allowing another thread that is blocked waiting for\n\
184the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000185but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000186
Barry Warsawd0c10421996-12-17 00:05:22 +0000187static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530188lock_locked_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000189{
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000190 return PyBool_FromLong((long)self->locked);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000191}
192
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000193PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000194"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000195(locked_lock() is an obsolete synonym)\n\
196\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000197Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000198
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700199static PyObject *
200lock_repr(lockobject *self)
201{
202 return PyUnicode_FromFormat("<%s %s object at %p>",
203 self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
204}
205
Barry Warsawd0c10421996-12-17 00:05:22 +0000206static PyMethodDef lock_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200207 {"acquire_lock", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208 METH_VARARGS | METH_KEYWORDS, acquire_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200209 {"acquire", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 METH_VARARGS | METH_KEYWORDS, acquire_doc},
211 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
212 METH_NOARGS, release_doc},
213 {"release", (PyCFunction)lock_PyThread_release_lock,
214 METH_NOARGS, release_doc},
215 {"locked_lock", (PyCFunction)lock_locked_lock,
216 METH_NOARGS, locked_doc},
217 {"locked", (PyCFunction)lock_locked_lock,
218 METH_NOARGS, locked_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200219 {"__enter__", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 METH_VARARGS | METH_KEYWORDS, acquire_doc},
221 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
222 METH_VARARGS, release_doc},
223 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000224};
225
Barry Warsawd0c10421996-12-17 00:05:22 +0000226static PyTypeObject Locktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 PyVarObject_HEAD_INIT(&PyType_Type, 0)
228 "_thread.lock", /*tp_name*/
Peter Eisentraut0e0bc4e2018-09-10 18:46:08 +0200229 sizeof(lockobject), /*tp_basicsize*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 0, /*tp_itemsize*/
231 /* methods */
232 (destructor)lock_dealloc, /*tp_dealloc*/
233 0, /*tp_print*/
234 0, /*tp_getattr*/
235 0, /*tp_setattr*/
236 0, /*tp_reserved*/
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700237 (reprfunc)lock_repr, /*tp_repr*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 0, /*tp_as_number*/
239 0, /*tp_as_sequence*/
240 0, /*tp_as_mapping*/
241 0, /*tp_hash*/
242 0, /*tp_call*/
243 0, /*tp_str*/
244 0, /*tp_getattro*/
245 0, /*tp_setattro*/
246 0, /*tp_as_buffer*/
247 Py_TPFLAGS_DEFAULT, /*tp_flags*/
248 0, /*tp_doc*/
249 0, /*tp_traverse*/
250 0, /*tp_clear*/
251 0, /*tp_richcompare*/
252 offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
253 0, /*tp_iter*/
254 0, /*tp_iternext*/
255 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000256};
257
Antoine Pitrou434736a2009-11-10 18:46:01 +0000258/* Recursive lock objects */
259
260typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 PyObject_HEAD
262 PyThread_type_lock rlock_lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200263 unsigned long rlock_owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 unsigned long rlock_count;
265 PyObject *in_weakreflist;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000266} rlockobject;
267
268static void
269rlock_dealloc(rlockobject *self)
270{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 if (self->in_weakreflist != NULL)
272 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner357f5152013-11-05 15:10:19 +0100273 /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed
274 in rlock_new() */
275 if (self->rlock_lock != NULL) {
276 /* Unlock the lock so it's safe to free it */
277 if (self->rlock_count > 0)
278 PyThread_release_lock(self->rlock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279
Victor Stinner357f5152013-11-05 15:10:19 +0100280 PyThread_free_lock(self->rlock_lock);
281 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 Py_TYPE(self)->tp_free(self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000283}
284
285static PyObject *
286rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
287{
Victor Stinnerf5faad22015-03-28 03:52:05 +0100288 _PyTime_t timeout;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200289 unsigned long tid;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000290 PyLockStatus r = PY_LOCK_ACQUIRED;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000291
Victor Stinnerf5faad22015-03-28 03:52:05 +0100292 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 tid = PyThread_get_thread_ident();
296 if (self->rlock_count > 0 && tid == self->rlock_owner) {
297 unsigned long count = self->rlock_count + 1;
298 if (count <= self->rlock_count) {
299 PyErr_SetString(PyExc_OverflowError,
300 "Internal lock count overflowed");
301 return NULL;
302 }
303 self->rlock_count = count;
304 Py_RETURN_TRUE;
305 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100306 r = acquire_timed(self->rlock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000307 if (r == PY_LOCK_ACQUIRED) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 assert(self->rlock_count == 0);
309 self->rlock_owner = tid;
310 self->rlock_count = 1;
311 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000312 else if (r == PY_LOCK_INTR) {
313 return NULL;
314 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315
Antoine Pitrou810023d2010-12-15 22:59:16 +0000316 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000317}
318
319PyDoc_STRVAR(rlock_acquire_doc,
320"acquire(blocking=True) -> bool\n\
321\n\
322Lock the lock. `blocking` indicates whether we should wait\n\
323for the lock to be available or not. If `blocking` is False\n\
324and another thread holds the lock, the method will return False\n\
325immediately. If `blocking` is True and another thread holds\n\
326the lock, the method will wait for the lock to be released,\n\
327take it and then return True.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000328(note: the blocking operation is interruptible.)\n\
Antoine Pitrou434736a2009-11-10 18:46:01 +0000329\n\
330In all other cases, the method will return True immediately.\n\
331Precisely, if the current thread already holds the lock, its\n\
332internal counter is simply incremented. If nobody holds the lock,\n\
333the lock is taken and its internal counter initialized to 1.");
334
335static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530336rlock_release(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000337{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200338 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrou434736a2009-11-10 18:46:01 +0000339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 if (self->rlock_count == 0 || self->rlock_owner != tid) {
341 PyErr_SetString(PyExc_RuntimeError,
342 "cannot release un-acquired lock");
343 return NULL;
344 }
345 if (--self->rlock_count == 0) {
346 self->rlock_owner = 0;
347 PyThread_release_lock(self->rlock_lock);
348 }
349 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000350}
351
352PyDoc_STRVAR(rlock_release_doc,
353"release()\n\
354\n\
355Release the lock, allowing another thread that is blocked waiting for\n\
356the lock to acquire the lock. The lock must be in the locked state,\n\
357and must be locked by the same thread that unlocks it; otherwise a\n\
358`RuntimeError` is raised.\n\
359\n\
360Do note that if the lock was acquire()d several times in a row by the\n\
361current thread, release() needs to be called as many times for the lock\n\
362to be available for other threads.");
363
364static PyObject *
Victor Stinnere8794522014-01-02 12:47:24 +0100365rlock_acquire_restore(rlockobject *self, PyObject *args)
Antoine Pitrou434736a2009-11-10 18:46:01 +0000366{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200367 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 unsigned long count;
369 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000370
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200371 if (!PyArg_ParseTuple(args, "(kk):_acquire_restore", &count, &owner))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
375 Py_BEGIN_ALLOW_THREADS
376 r = PyThread_acquire_lock(self->rlock_lock, 1);
377 Py_END_ALLOW_THREADS
378 }
379 if (!r) {
380 PyErr_SetString(ThreadError, "couldn't acquire lock");
381 return NULL;
382 }
383 assert(self->rlock_count == 0);
384 self->rlock_owner = owner;
385 self->rlock_count = count;
386 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000387}
388
389PyDoc_STRVAR(rlock_acquire_restore_doc,
390"_acquire_restore(state) -> None\n\
391\n\
392For internal use by `threading.Condition`.");
393
394static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530395rlock_release_save(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000396{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200397 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 unsigned long count;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000399
Victor Stinnerc2824d42011-04-24 23:41:33 +0200400 if (self->rlock_count == 0) {
401 PyErr_SetString(PyExc_RuntimeError,
402 "cannot release un-acquired lock");
403 return NULL;
404 }
405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 owner = self->rlock_owner;
407 count = self->rlock_count;
408 self->rlock_count = 0;
409 self->rlock_owner = 0;
410 PyThread_release_lock(self->rlock_lock);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200411 return Py_BuildValue("kk", count, owner);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000412}
413
414PyDoc_STRVAR(rlock_release_save_doc,
415"_release_save() -> tuple\n\
416\n\
417For internal use by `threading.Condition`.");
418
419
420static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530421rlock_is_owned(rlockobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou434736a2009-11-10 18:46:01 +0000422{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200423 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424
425 if (self->rlock_count > 0 && self->rlock_owner == tid) {
426 Py_RETURN_TRUE;
427 }
428 Py_RETURN_FALSE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000429}
430
431PyDoc_STRVAR(rlock_is_owned_doc,
432"_is_owned() -> bool\n\
433\n\
434For internal use by `threading.Condition`.");
435
436static PyObject *
437rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
438{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000439 rlockobject *self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 self = (rlockobject *) type->tp_alloc(type, 0);
442 if (self != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 self->in_weakreflist = NULL;
444 self->rlock_owner = 0;
445 self->rlock_count = 0;
Victor Stinner357f5152013-11-05 15:10:19 +0100446
447 self->rlock_lock = PyThread_allocate_lock();
448 if (self->rlock_lock == NULL) {
449 Py_DECREF(self);
450 PyErr_SetString(ThreadError, "can't allocate lock");
451 return NULL;
452 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 return (PyObject *) self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000456}
457
458static PyObject *
459rlock_repr(rlockobject *self)
460{
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700461 return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>",
462 self->rlock_count ? "locked" : "unlocked",
463 Py_TYPE(self)->tp_name, self->rlock_owner,
464 self->rlock_count, self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000465}
466
467
468static PyMethodDef rlock_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200469 {"acquire", (PyCFunction)(void(*)(void))rlock_acquire,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
471 {"release", (PyCFunction)rlock_release,
472 METH_NOARGS, rlock_release_doc},
473 {"_is_owned", (PyCFunction)rlock_is_owned,
474 METH_NOARGS, rlock_is_owned_doc},
475 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
Victor Stinnere8794522014-01-02 12:47:24 +0100476 METH_VARARGS, rlock_acquire_restore_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 {"_release_save", (PyCFunction)rlock_release_save,
478 METH_NOARGS, rlock_release_save_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +0200479 {"__enter__", (PyCFunction)(void(*)(void))rlock_acquire,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
481 {"__exit__", (PyCFunction)rlock_release,
482 METH_VARARGS, rlock_release_doc},
483 {NULL, NULL} /* sentinel */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000484};
485
486
487static PyTypeObject RLocktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 PyVarObject_HEAD_INIT(&PyType_Type, 0)
489 "_thread.RLock", /*tp_name*/
Peter Eisentraut0e0bc4e2018-09-10 18:46:08 +0200490 sizeof(rlockobject), /*tp_basicsize*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 0, /*tp_itemsize*/
492 /* methods */
493 (destructor)rlock_dealloc, /*tp_dealloc*/
494 0, /*tp_print*/
495 0, /*tp_getattr*/
496 0, /*tp_setattr*/
497 0, /*tp_reserved*/
498 (reprfunc)rlock_repr, /*tp_repr*/
499 0, /*tp_as_number*/
500 0, /*tp_as_sequence*/
501 0, /*tp_as_mapping*/
502 0, /*tp_hash*/
503 0, /*tp_call*/
504 0, /*tp_str*/
505 0, /*tp_getattro*/
506 0, /*tp_setattro*/
507 0, /*tp_as_buffer*/
508 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
509 0, /*tp_doc*/
510 0, /*tp_traverse*/
511 0, /*tp_clear*/
512 0, /*tp_richcompare*/
513 offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
514 0, /*tp_iter*/
515 0, /*tp_iternext*/
516 rlock_methods, /*tp_methods*/
517 0, /* tp_members */
518 0, /* tp_getset */
519 0, /* tp_base */
520 0, /* tp_dict */
521 0, /* tp_descr_get */
522 0, /* tp_descr_set */
523 0, /* tp_dictoffset */
524 0, /* tp_init */
525 PyType_GenericAlloc, /* tp_alloc */
526 rlock_new /* tp_new */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000527};
528
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000529static lockobject *
530newlockobject(void)
531{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 lockobject *self;
533 self = PyObject_New(lockobject, &Locktype);
534 if (self == NULL)
535 return NULL;
536 self->lock_lock = PyThread_allocate_lock();
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000537 self->locked = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 self->in_weakreflist = NULL;
539 if (self->lock_lock == NULL) {
540 Py_DECREF(self);
541 PyErr_SetString(ThreadError, "can't allocate lock");
542 return NULL;
543 }
544 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000545}
546
Jim Fultond15dc062004-07-14 19:11:50 +0000547/* Thread-local objects */
548
549#include "structmember.h"
550
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000551/* Quick overview:
552
553 We need to be able to reclaim reference cycles as soon as possible
554 (both when a thread is being terminated, or a thread-local object
555 becomes unreachable from user data). Constraints:
556 - it must not be possible for thread-state dicts to be involved in
557 reference cycles (otherwise the cyclic GC will refuse to consider
558 objects referenced from a reachable thread-state dict, even though
559 local_dealloc would clear them)
560 - the death of a thread-state dict must still imply destruction of the
561 corresponding local dicts in all thread-local objects.
562
563 Our implementation uses small "localdummy" objects in order to break
564 the reference chain. These trivial objects are hashable (using the
565 default scheme of identity hashing) and weakrefable.
566 Each thread-state holds a separate localdummy for each local object
567 (as a /strong reference/),
568 and each thread-local object holds a dict mapping /weak references/
569 of localdummies to local dicts.
570
571 Therefore:
572 - only the thread-state dict holds a strong reference to the dummies
573 - only the thread-local object holds a strong reference to the local dicts
574 - only outside objects (application- or library-level) hold strong
575 references to the thread-local objects
576 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
577 dummies attached to that thread are called, and destroy the corresponding
578 local dicts from thread-local objects
579 - as soon as a thread-local object is destroyed, its local dicts are
580 destroyed and its dummies are manually removed from all thread states
581 - the GC can do its work correctly when a thread-local object is dangling,
582 without any interference from the thread-state dicts
583
584 As an additional optimization, each localdummy holds a borrowed reference
585 to the corresponding localdict. This borrowed reference is only used
586 by the thread-local object which has created the localdummy, which should
587 guarantee that the localdict still exists when accessed.
588*/
589
590typedef struct {
591 PyObject_HEAD
592 PyObject *localdict; /* Borrowed reference! */
593 PyObject *weakreflist; /* List of weak references to self */
594} localdummyobject;
595
596static void
597localdummy_dealloc(localdummyobject *self)
598{
599 if (self->weakreflist != NULL)
600 PyObject_ClearWeakRefs((PyObject *) self);
601 Py_TYPE(self)->tp_free((PyObject*)self);
602}
603
604static PyTypeObject localdummytype = {
605 PyVarObject_HEAD_INIT(NULL, 0)
606 /* tp_name */ "_thread._localdummy",
607 /* tp_basicsize */ sizeof(localdummyobject),
608 /* tp_itemsize */ 0,
609 /* tp_dealloc */ (destructor)localdummy_dealloc,
610 /* tp_print */ 0,
611 /* tp_getattr */ 0,
612 /* tp_setattr */ 0,
613 /* tp_reserved */ 0,
614 /* tp_repr */ 0,
615 /* tp_as_number */ 0,
616 /* tp_as_sequence */ 0,
617 /* tp_as_mapping */ 0,
618 /* tp_hash */ 0,
619 /* tp_call */ 0,
620 /* tp_str */ 0,
621 /* tp_getattro */ 0,
622 /* tp_setattro */ 0,
623 /* tp_as_buffer */ 0,
624 /* tp_flags */ Py_TPFLAGS_DEFAULT,
625 /* tp_doc */ "Thread-local dummy",
626 /* tp_traverse */ 0,
627 /* tp_clear */ 0,
628 /* tp_richcompare */ 0,
629 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
630};
631
632
Jim Fultond15dc062004-07-14 19:11:50 +0000633typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 PyObject_HEAD
635 PyObject *key;
636 PyObject *args;
637 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000638 PyObject *weakreflist; /* List of weak references to self */
639 /* A {localdummy weakref -> localdict} dict */
640 PyObject *dummies;
641 /* The callback for weakrefs to localdummies */
642 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000643} localobject;
644
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000645/* Forward declaration */
646static PyObject *_ldict(localobject *self);
647static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
648
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000649/* Create and register the dummy for the current thread.
650 Returns a borrowed reference of the corresponding local dict */
651static PyObject *
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000652_local_create_dummy(localobject *self)
653{
654 PyObject *tdict, *ldict = NULL, *wr = NULL;
655 localdummyobject *dummy = NULL;
656 int r;
657
658 tdict = PyThreadState_GetDict();
659 if (tdict == NULL) {
660 PyErr_SetString(PyExc_SystemError,
661 "Couldn't get thread-state dictionary");
662 goto err;
663 }
664
665 ldict = PyDict_New();
666 if (ldict == NULL)
667 goto err;
668 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
669 if (dummy == NULL)
670 goto err;
671 dummy->localdict = ldict;
672 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
673 if (wr == NULL)
674 goto err;
675
676 /* As a side-effect, this will cache the weakref's hash before the
677 dummy gets deleted */
678 r = PyDict_SetItem(self->dummies, wr, ldict);
679 if (r < 0)
680 goto err;
681 Py_CLEAR(wr);
682 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
683 if (r < 0)
684 goto err;
685 Py_CLEAR(dummy);
686
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000687 Py_DECREF(ldict);
688 return ldict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000689
690err:
691 Py_XDECREF(ldict);
692 Py_XDECREF(wr);
693 Py_XDECREF(dummy);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000694 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000695}
696
Jim Fultond15dc062004-07-14 19:11:50 +0000697static PyObject *
698local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
699{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 localobject *self;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000701 PyObject *wr;
702 static PyMethodDef wr_callback_def = {
703 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
704 };
Jim Fultond15dc062004-07-14 19:11:50 +0000705
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300706 if (type->tp_init == PyBaseObject_Type.tp_init) {
707 int rc = 0;
708 if (args != NULL)
709 rc = PyObject_IsTrue(args);
710 if (rc == 0 && kw != NULL)
711 rc = PyObject_IsTrue(kw);
712 if (rc != 0) {
713 if (rc > 0)
714 PyErr_SetString(PyExc_TypeError,
715 "Initialization arguments are not supported");
716 return NULL;
717 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 }
Jim Fultond15dc062004-07-14 19:11:50 +0000719
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 self = (localobject *)type->tp_alloc(type, 0);
721 if (self == NULL)
722 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000723
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 Py_XINCREF(args);
725 self->args = args;
726 Py_XINCREF(kw);
727 self->kw = kw;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 self->key = PyUnicode_FromFormat("thread.local.%p", self);
729 if (self->key == NULL)
730 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000731
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000732 self->dummies = PyDict_New();
733 if (self->dummies == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000735
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000736 /* We use a weak reference to self in the callback closure
737 in order to avoid spurious reference cycles */
738 wr = PyWeakref_NewRef((PyObject *) self, NULL);
739 if (wr == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 goto err;
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200741 self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000742 Py_DECREF(wr);
743 if (self->wr_callback == NULL)
744 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000745
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000746 if (_local_create_dummy(self) == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000749 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000750
751 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000752 Py_DECREF(self);
753 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000754}
755
756static int
757local_traverse(localobject *self, visitproc visit, void *arg)
758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 Py_VISIT(self->args);
760 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000761 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000763}
764
765static int
766local_clear(localobject *self)
767{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000768 PyThreadState *tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 Py_CLEAR(self->args);
770 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000771 Py_CLEAR(self->dummies);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000772 Py_CLEAR(self->wr_callback);
773 /* Remove all strong references to dummies from the thread states */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000774 if (self->key
775 && (tstate = PyThreadState_Get())
776 && tstate->interp) {
777 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
778 tstate;
779 tstate = PyThreadState_Next(tstate))
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200780 if (tstate->dict && PyDict_GetItem(tstate->dict, self->key)) {
781 if (PyDict_DelItem(tstate->dict, self->key)) {
782 PyErr_Clear();
783 }
784 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000785 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000786 return 0;
787}
Jim Fultond15dc062004-07-14 19:11:50 +0000788
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000789static void
790local_dealloc(localobject *self)
791{
792 /* Weakrefs must be invalidated right now, otherwise they can be used
793 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
794 if (self->weakreflist != NULL)
795 PyObject_ClearWeakRefs((PyObject *) self);
796
797 PyObject_GC_UnTrack(self);
798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000799 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000800 Py_XDECREF(self->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000802}
803
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000804/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000805static PyObject *
806_ldict(localobject *self)
807{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000808 PyObject *tdict, *ldict, *dummy;
Jim Fultond15dc062004-07-14 19:11:50 +0000809
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000810 tdict = PyThreadState_GetDict();
811 if (tdict == NULL) {
812 PyErr_SetString(PyExc_SystemError,
813 "Couldn't get thread-state dictionary");
814 return NULL;
815 }
Jim Fultond15dc062004-07-14 19:11:50 +0000816
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200817 dummy = PyDict_GetItemWithError(tdict, self->key);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000818 if (dummy == NULL) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200819 if (PyErr_Occurred()) {
820 return NULL;
821 }
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000822 ldict = _local_create_dummy(self);
823 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000824 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
827 Py_TYPE(self)->tp_init((PyObject*)self,
828 self->args, self->kw) < 0) {
829 /* we need to get rid of ldict from thread so
830 we create a new one the next time we do an attr
Ezio Melotti42da6632011-03-15 05:18:48 +0200831 access */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000832 PyDict_DelItem(tdict, self->key);
833 return NULL;
834 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000835 }
836 else {
837 assert(Py_TYPE(dummy) == &localdummytype);
838 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000839 }
Jim Fultond15dc062004-07-14 19:11:50 +0000840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000842}
843
Jim Fultond15dc062004-07-14 19:11:50 +0000844static int
845local_setattro(localobject *self, PyObject *name, PyObject *v)
846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000847 PyObject *ldict;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000848 int r;
Jim Fultond15dc062004-07-14 19:11:50 +0000849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000850 ldict = _ldict(self);
851 if (ldict == NULL)
852 return -1;
853
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000854 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
855 if (r == 1) {
856 PyErr_Format(PyExc_AttributeError,
857 "'%.50s' object attribute '%U' is read-only",
858 Py_TYPE(self)->tp_name, name);
859 return -1;
860 }
861 if (r == -1)
862 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000863
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000864 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000865}
866
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000867static PyObject *local_getattro(localobject *, PyObject *);
868
Jim Fultond15dc062004-07-14 19:11:50 +0000869static PyTypeObject localtype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000870 PyVarObject_HEAD_INIT(NULL, 0)
871 /* tp_name */ "_thread._local",
872 /* tp_basicsize */ sizeof(localobject),
873 /* tp_itemsize */ 0,
874 /* tp_dealloc */ (destructor)local_dealloc,
875 /* tp_print */ 0,
876 /* tp_getattr */ 0,
877 /* tp_setattr */ 0,
878 /* tp_reserved */ 0,
879 /* tp_repr */ 0,
880 /* tp_as_number */ 0,
881 /* tp_as_sequence */ 0,
882 /* tp_as_mapping */ 0,
883 /* tp_hash */ 0,
884 /* tp_call */ 0,
885 /* tp_str */ 0,
886 /* tp_getattro */ (getattrofunc)local_getattro,
887 /* tp_setattro */ (setattrofunc)local_setattro,
888 /* tp_as_buffer */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000889 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
890 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 /* tp_doc */ "Thread-local data",
892 /* tp_traverse */ (traverseproc)local_traverse,
893 /* tp_clear */ (inquiry)local_clear,
894 /* tp_richcompare */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000895 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000896 /* tp_iter */ 0,
897 /* tp_iternext */ 0,
898 /* tp_methods */ 0,
899 /* tp_members */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000900 /* tp_getset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 /* tp_base */ 0,
902 /* tp_dict */ 0, /* internal use */
903 /* tp_descr_get */ 0,
904 /* tp_descr_set */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000905 /* tp_dictoffset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 /* tp_init */ 0,
907 /* tp_alloc */ 0,
908 /* tp_new */ local_new,
909 /* tp_free */ 0, /* Low-level free-mem routine */
910 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000911};
912
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000913static PyObject *
914local_getattro(localobject *self, PyObject *name)
915{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 PyObject *ldict, *value;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000917 int r;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000919 ldict = _ldict(self);
920 if (ldict == NULL)
921 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000922
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000923 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
924 if (r == 1) {
925 Py_INCREF(ldict);
926 return ldict;
927 }
928 if (r == -1)
929 return NULL;
930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000931 if (Py_TYPE(self) != &localtype)
932 /* use generic lookup for subtypes */
INADA Naoki378edee2018-01-16 20:52:41 +0900933 return _PyObject_GenericGetAttrWithDict(
934 (PyObject *)self, name, ldict, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000936 /* Optimization: just look in dict ourselves */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200937 value = PyDict_GetItemWithError(ldict, name);
938 if (value != NULL) {
939 Py_INCREF(value);
940 return value;
941 }
942 else if (PyErr_Occurred()) {
943 return NULL;
944 }
945 /* Fall back on generic to get __class__ and __dict__ */
946 return _PyObject_GenericGetAttrWithDict(
947 (PyObject *)self, name, ldict, 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000948}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000949
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000950/* Called when a dummy is destroyed. */
951static PyObject *
952_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
953{
954 PyObject *obj;
955 localobject *self;
956 assert(PyWeakref_CheckRef(localweakref));
957 obj = PyWeakref_GET_OBJECT(localweakref);
958 if (obj == Py_None)
959 Py_RETURN_NONE;
960 Py_INCREF(obj);
961 assert(PyObject_TypeCheck(obj, &localtype));
962 /* If the thread-local object is still alive and not being cleared,
963 remove the corresponding local dict */
964 self = (localobject *) obj;
965 if (self->dummies != NULL) {
966 PyObject *ldict;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200967 ldict = PyDict_GetItemWithError(self->dummies, dummyweakref);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000968 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000969 PyDict_DelItem(self->dummies, dummyweakref);
970 }
971 if (PyErr_Occurred())
972 PyErr_WriteUnraisable(obj);
973 }
974 Py_DECREF(obj);
975 Py_RETURN_NONE;
976}
977
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000978/* Module functions */
979
Guido van Rossuma027efa1997-05-05 20:56:21 +0000980struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 PyInterpreterState *interp;
982 PyObject *func;
983 PyObject *args;
984 PyObject *keyw;
985 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000986};
987
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000988static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000989t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000990{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 struct bootstate *boot = (struct bootstate *) boot_raw;
992 PyThreadState *tstate;
993 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 tstate = boot->tstate;
996 tstate->thread_id = PyThread_get_thread_ident();
Victor Stinner8bb32302019-04-24 16:47:40 +0200997 _PyThreadState_Init(&_PyRuntime, tstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000998 PyEval_AcquireThread(tstate);
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600999 tstate->interp->num_threads++;
INADA Naoki72dccde2017-02-16 09:26:01 +09001000 res = PyObject_Call(boot->func, boot->args, boot->keyw);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 if (res == NULL) {
1002 if (PyErr_ExceptionMatches(PyExc_SystemExit))
1003 PyErr_Clear();
1004 else {
1005 PyObject *file;
Benjamin Petersone9000962012-04-02 11:15:17 -04001006 PyObject *exc, *value, *tb;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 PySys_WriteStderr(
1008 "Unhandled exception in thread started by ");
Benjamin Petersone9000962012-04-02 11:15:17 -04001009 PyErr_Fetch(&exc, &value, &tb);
Victor Stinnerbd303c12013-11-07 23:07:29 +01001010 file = _PySys_GetObjectId(&PyId_stderr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 if (file != NULL && file != Py_None)
1012 PyFile_WriteObject(boot->func, file, 0);
1013 else
1014 PyObject_Print(boot->func, stderr, 0);
1015 PySys_WriteStderr("\n");
Benjamin Petersone9000962012-04-02 11:15:17 -04001016 PyErr_Restore(exc, value, tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001017 PyErr_PrintEx(0);
1018 }
1019 }
1020 else
1021 Py_DECREF(res);
1022 Py_DECREF(boot->func);
1023 Py_DECREF(boot->args);
1024 Py_XDECREF(boot->keyw);
1025 PyMem_DEL(boot_raw);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001026 tstate->interp->num_threads--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 PyThreadState_Clear(tstate);
1028 PyThreadState_DeleteCurrent();
1029 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001030}
1031
Barry Warsawd0c10421996-12-17 00:05:22 +00001032static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001033thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001034{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 PyObject *func, *args, *keyw = NULL;
1036 struct bootstate *boot;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001037 unsigned long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
1040 &func, &args, &keyw))
1041 return NULL;
1042 if (!PyCallable_Check(func)) {
1043 PyErr_SetString(PyExc_TypeError,
1044 "first arg must be callable");
1045 return NULL;
1046 }
1047 if (!PyTuple_Check(args)) {
1048 PyErr_SetString(PyExc_TypeError,
1049 "2nd arg must be a tuple");
1050 return NULL;
1051 }
1052 if (keyw != NULL && !PyDict_Check(keyw)) {
1053 PyErr_SetString(PyExc_TypeError,
1054 "optional 3rd arg must be a dictionary");
1055 return NULL;
1056 }
1057 boot = PyMem_NEW(struct bootstate, 1);
1058 if (boot == NULL)
1059 return PyErr_NoMemory();
Victor Stinnercaba55b2018-08-03 15:33:52 +02001060 boot->interp = _PyInterpreterState_Get();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 boot->func = func;
1062 boot->args = args;
1063 boot->keyw = keyw;
1064 boot->tstate = _PyThreadState_Prealloc(boot->interp);
1065 if (boot->tstate == NULL) {
1066 PyMem_DEL(boot);
1067 return PyErr_NoMemory();
1068 }
1069 Py_INCREF(func);
1070 Py_INCREF(args);
1071 Py_XINCREF(keyw);
1072 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
1073 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001074 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 PyErr_SetString(ThreadError, "can't start new thread");
1076 Py_DECREF(func);
1077 Py_DECREF(args);
1078 Py_XDECREF(keyw);
1079 PyThreadState_Clear(boot->tstate);
1080 PyMem_DEL(boot);
1081 return NULL;
1082 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001083 return PyLong_FromUnsignedLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001084}
1085
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001086PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001087"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001088(start_new() is an obsolete synonym)\n\
1089\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001090Start a new thread and return its identifier. The thread will call the\n\
1091function with positional arguments from the tuple args and keyword arguments\n\
1092taken from the optional dictionary kwargs. The thread exits when the\n\
1093function returns; the return value is ignored. The thread will also exit\n\
1094when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001095printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001096
Barry Warsawd0c10421996-12-17 00:05:22 +00001097static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301098thread_PyThread_exit_thread(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001099{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 PyErr_SetNone(PyExc_SystemExit);
1101 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001102}
1103
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001104PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001105"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001106(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001107\n\
1108This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001109thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001110
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001111static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301112thread_PyThread_interrupt_main(PyObject * self, PyObject *Py_UNUSED(ignored))
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001113{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 PyErr_SetInterrupt();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001115 Py_RETURN_NONE;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001116}
1117
1118PyDoc_STRVAR(interrupt_doc,
1119"interrupt_main()\n\
1120\n\
1121Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001122A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001123);
1124
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001125static lockobject *newlockobject(void);
1126
Barry Warsawd0c10421996-12-17 00:05:22 +00001127static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301128thread_PyThread_allocate_lock(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001129{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001130 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001131}
1132
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001133PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001134"allocate_lock() -> lock object\n\
1135(allocate() is an obsolete synonym)\n\
1136\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001137Create a new lock object. See help(type(threading.Lock())) for\n\
1138information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001139
Barry Warsawd0c10421996-12-17 00:05:22 +00001140static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301141thread_get_ident(PyObject *self, PyObject *Py_UNUSED(ignored))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001142{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001143 unsigned long ident = PyThread_get_thread_ident();
1144 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 PyErr_SetString(ThreadError, "no current thread ident");
1146 return NULL;
1147 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001148 return PyLong_FromUnsignedLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001149}
1150
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001151PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001152"get_ident() -> integer\n\
1153\n\
1154Return a non-zero integer that uniquely identifies the current thread\n\
1155amongst other threads that exist simultaneously.\n\
1156This may be used to identify per-thread resources.\n\
1157Even though on some platforms threads identities may appear to be\n\
1158allocated consecutive numbers starting at 1, this behavior should not\n\
1159be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001160A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001161
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001162static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301163thread__count(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001164{
Victor Stinnercaba55b2018-08-03 15:33:52 +02001165 PyInterpreterState *interp = _PyInterpreterState_Get();
1166 return PyLong_FromLong(interp->num_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001167}
1168
1169PyDoc_STRVAR(_count_doc,
1170"_count() -> integer\n\
1171\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001172\
oldkaa0735f2018-02-02 16:52:55 +08001173Return the number of currently running Python threads, excluding\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001174the main thread. The returned number comprises all threads created\n\
1175through `start_new_thread()` as well as `threading.Thread`, and not\n\
1176yet finished.\n\
1177\n\
1178This function is meant for internal and specialized purposes only.\n\
1179In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001180
Antoine Pitrou7b476992013-09-07 23:38:37 +02001181static void
Victor Stinnera42de742018-11-22 10:25:22 +01001182release_sentinel(void *wr_raw)
Antoine Pitrou7b476992013-09-07 23:38:37 +02001183{
Victor Stinnera42de742018-11-22 10:25:22 +01001184 PyObject *wr = _PyObject_CAST(wr_raw);
Antoine Pitrou7b476992013-09-07 23:38:37 +02001185 /* Tricky: this function is called when the current thread state
1186 is being deleted. Therefore, only simple C code can safely
1187 execute here. */
1188 PyObject *obj = PyWeakref_GET_OBJECT(wr);
1189 lockobject *lock;
1190 if (obj != Py_None) {
1191 assert(Py_TYPE(obj) == &Locktype);
1192 lock = (lockobject *) obj;
1193 if (lock->locked) {
1194 PyThread_release_lock(lock->lock_lock);
1195 lock->locked = 0;
1196 }
1197 }
1198 /* Deallocating a weakref with a NULL callback only calls
1199 PyObject_GC_Del(), which can't call any Python code. */
1200 Py_DECREF(wr);
1201}
1202
1203static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301204thread__set_sentinel(PyObject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou7b476992013-09-07 23:38:37 +02001205{
1206 PyObject *wr;
1207 PyThreadState *tstate = PyThreadState_Get();
1208 lockobject *lock;
1209
1210 if (tstate->on_delete_data != NULL) {
1211 /* We must support the re-creation of the lock from a
1212 fork()ed child. */
1213 assert(tstate->on_delete == &release_sentinel);
1214 wr = (PyObject *) tstate->on_delete_data;
1215 tstate->on_delete = NULL;
1216 tstate->on_delete_data = NULL;
1217 Py_DECREF(wr);
1218 }
1219 lock = newlockobject();
1220 if (lock == NULL)
1221 return NULL;
1222 /* The lock is owned by whoever called _set_sentinel(), but the weakref
1223 hangs to the thread state. */
1224 wr = PyWeakref_NewRef((PyObject *) lock, NULL);
1225 if (wr == NULL) {
1226 Py_DECREF(lock);
1227 return NULL;
1228 }
1229 tstate->on_delete_data = (void *) wr;
1230 tstate->on_delete = &release_sentinel;
1231 return (PyObject *) lock;
1232}
1233
1234PyDoc_STRVAR(_set_sentinel_doc,
1235"_set_sentinel() -> lock\n\
1236\n\
1237Set a sentinel lock that will be released when the current thread\n\
1238state is finalized (after it is untied from the interpreter).\n\
1239\n\
1240This is a private API for the threading module.");
1241
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001242static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001243thread_stack_size(PyObject *self, PyObject *args)
1244{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 size_t old_size;
1246 Py_ssize_t new_size = 0;
1247 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1250 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 if (new_size < 0) {
1253 PyErr_SetString(PyExc_ValueError,
1254 "size must be 0 or a positive value");
1255 return NULL;
1256 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 rc = PyThread_set_stacksize((size_t) new_size);
1261 if (rc == -1) {
1262 PyErr_Format(PyExc_ValueError,
1263 "size not valid: %zd bytes",
1264 new_size);
1265 return NULL;
1266 }
1267 if (rc == -2) {
1268 PyErr_SetString(ThreadError,
1269 "setting stack size not supported");
1270 return NULL;
1271 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001274}
1275
1276PyDoc_STRVAR(stack_size_doc,
1277"stack_size([size]) -> size\n\
1278\n\
1279Return the thread stack size used when creating new threads. The\n\
1280optional size argument specifies the stack size (in bytes) to be used\n\
1281for subsequently created threads, and must be 0 (use platform or\n\
1282configured default) or a positive integer value of at least 32,768 (32k).\n\
1283If changing the thread stack size is unsupported, a ThreadError\n\
1284exception is raised. If the specified size is invalid, a ValueError\n\
1285exception is raised, and the stack size is unmodified. 32k bytes\n\
1286 currently the minimum supported stack size value to guarantee\n\
1287sufficient stack space for the interpreter itself.\n\
1288\n\
1289Note that some platforms may have particular restrictions on values for\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001290the stack size, such as requiring a minimum stack size larger than 32 KiB or\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001291requiring allocation in multiples of the system memory page size\n\
1292- platform documentation should be referred to for more information\n\
Victor Stinner8c663fd2017-11-08 14:44:44 -08001293(4 KiB pages are common; using multiples of 4096 for the stack size is\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001294the suggested approach in the absence of more specific information).");
1295
Barry Warsawd0c10421996-12-17 00:05:22 +00001296static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001298 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001300 METH_VARARGS, start_new_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301301 {"allocate_lock", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301303 {"allocate", thread_PyThread_allocate_lock,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 METH_NOARGS, allocate_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301305 {"exit_thread", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301307 {"exit", thread_PyThread_exit_thread,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 METH_NOARGS, exit_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301309 {"interrupt_main", thread_PyThread_interrupt_main,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 METH_NOARGS, interrupt_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301311 {"get_ident", thread_get_ident,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 METH_NOARGS, get_ident_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301313 {"_count", thread__count,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 METH_NOARGS, _count_doc},
1315 {"stack_size", (PyCFunction)thread_stack_size,
Victor Stinner754851f2011-04-19 23:58:51 +02001316 METH_VARARGS, stack_size_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301317 {"_set_sentinel", thread__set_sentinel,
Antoine Pitrou7b476992013-09-07 23:38:37 +02001318 METH_NOARGS, _set_sentinel_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001320};
1321
1322
1323/* Initialization function */
1324
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001325PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001326"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001327The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001328
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001329PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001330"A lock object is a synchronization primitive. To create a lock,\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001331call threading.Lock(). Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001332\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001333acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1334release() -- unlock of the lock\n\
1335locked() -- test whether the lock is currently locked\n\
1336\n\
1337A lock is not owned by the thread that locked it; another thread may\n\
1338unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001339will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001340
Martin v. Löwis1a214512008-06-11 05:26:20 +00001341static struct PyModuleDef threadmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 PyModuleDef_HEAD_INIT,
1343 "_thread",
1344 thread_doc,
1345 -1,
1346 thread_methods,
1347 NULL,
1348 NULL,
1349 NULL,
1350 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001351};
1352
1353
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001354PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001355PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001356{
Victor Stinnerf5faad22015-03-28 03:52:05 +01001357 PyObject *m, *d, *v;
1358 double time_max;
1359 double timeout_max;
Victor Stinnercaba55b2018-08-03 15:33:52 +02001360 PyInterpreterState *interp = _PyInterpreterState_Get();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 /* Initialize types: */
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001363 if (PyType_Ready(&localdummytype) < 0)
1364 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 if (PyType_Ready(&localtype) < 0)
1366 return NULL;
1367 if (PyType_Ready(&Locktype) < 0)
1368 return NULL;
1369 if (PyType_Ready(&RLocktype) < 0)
1370 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 /* Create the module and add the functions */
1373 m = PyModule_Create(&threadmodule);
1374 if (m == NULL)
1375 return NULL;
Antoine Pitrou7c3e5772010-04-14 15:44:10 +00001376
Victor Stinnerc319eee2017-11-30 23:03:47 +01001377 timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6;
Victor Stinner850a18e2017-10-24 16:53:32 -07001378 time_max = _PyTime_AsSecondsDouble(_PyTime_MAX);
Victor Stinnerf5faad22015-03-28 03:52:05 +01001379 timeout_max = Py_MIN(timeout_max, time_max);
Victor Stinner850a18e2017-10-24 16:53:32 -07001380 /* Round towards minus infinity */
1381 timeout_max = floor(timeout_max);
Victor Stinnerf5faad22015-03-28 03:52:05 +01001382
1383 v = PyFloat_FromDouble(timeout_max);
1384 if (!v)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 return NULL;
Victor Stinnerf5faad22015-03-28 03:52:05 +01001386 if (PyModule_AddObject(m, "TIMEOUT_MAX", v) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 /* Add a symbolic constant */
1390 d = PyModule_GetDict(m);
Antoine Pitroufcf81fd2011-02-28 22:03:34 +00001391 ThreadError = PyExc_RuntimeError;
1392 Py_INCREF(ThreadError);
Victor Stinner754851f2011-04-19 23:58:51 +02001393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 PyDict_SetItemString(d, "error", ThreadError);
1395 Locktype.tp_doc = lock_doc;
1396 Py_INCREF(&Locktype);
1397 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Antoine Pitrou434736a2009-11-10 18:46:01 +00001398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 Py_INCREF(&RLocktype);
1400 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1401 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001403 Py_INCREF(&localtype);
1404 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1405 return NULL;
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001406
Victor Stinnercaba55b2018-08-03 15:33:52 +02001407 interp->num_threads = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +00001409 str_dict = PyUnicode_InternFromString("__dict__");
1410 if (str_dict == NULL)
1411 return NULL;
1412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 /* Initialize the C thread library */
1414 PyThread_init_thread();
1415 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001416}