blob: da750c01cd9598d8afb26c9378bf5a7a11dec816 [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"
Benjamin Petersonbec4d572009-10-10 01:16:07 +00006#include "structmember.h" /* offsetof */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00007
Guido van Rossumb6775db1994-08-01 11:34:53 +00008#ifndef WITH_THREAD
Guido van Rossuma027efa1997-05-05 20:56:21 +00009#error "Error! The rest of Python is not compiled with thread support."
Neal Norwitz884baa12002-09-05 21:31:04 +000010#error "Rerun configure, adding a --with-threads option."
Guido van Rossuma027efa1997-05-05 20:56:21 +000011#error "Then run `make clean' followed by `make'."
Guido van Rossumb6775db1994-08-01 11:34:53 +000012#endif
13
Guido van Rossum49b56061998-10-01 20:42:43 +000014#include "pythread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000015
Barry Warsawd0c10421996-12-17 00:05:22 +000016static PyObject *ThreadError;
Antoine Pitrou65c9c642009-10-30 17:25:12 +000017static long nb_threads = 0;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +000018static PyObject *str_dict;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000019
Victor Stinnerbd303c12013-11-07 23:07:29 +010020_Py_IDENTIFIER(stderr);
21
Guido van Rossum1984f1e1992-08-04 12:41:02 +000022/* Lock objects */
23
24typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000025 PyObject_HEAD
26 PyThread_type_lock lock_lock;
27 PyObject *in_weakreflist;
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000028 char locked; /* for sanity checking */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000029} lockobject;
30
Guido van Rossum1984f1e1992-08-04 12:41:02 +000031static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000032lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000034 if (self->in_weakreflist != NULL)
35 PyObject_ClearWeakRefs((PyObject *) self);
36 if (self->lock_lock != NULL) {
37 /* Unlock the lock so it's safe to free it */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000038 if (self->locked)
39 PyThread_release_lock(self->lock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000040 PyThread_free_lock(self->lock_lock);
41 }
42 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000043}
44
Antoine Pitrou810023d2010-12-15 22:59:16 +000045/* Helper to acquire an interruptible lock with a timeout. If the lock acquire
46 * is interrupted, signal handlers are run, and if they raise an exception,
47 * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE
Raymond Hettinger15f44ab2016-08-30 10:47:49 -070048 * are returned, depending on whether the lock can be acquired within the
Antoine Pitrou810023d2010-12-15 22:59:16 +000049 * timeout.
50 */
51static PyLockStatus
Victor Stinnerf5faad22015-03-28 03:52:05 +010052acquire_timed(PyThread_type_lock lock, _PyTime_t timeout)
Antoine Pitrou810023d2010-12-15 22:59:16 +000053{
54 PyLockStatus r;
Victor Stinnerf5faad22015-03-28 03:52:05 +010055 _PyTime_t endtime = 0;
56 _PyTime_t microseconds;
Antoine Pitrou810023d2010-12-15 22:59:16 +000057
Victor Stinnerf5faad22015-03-28 03:52:05 +010058 if (timeout > 0)
59 endtime = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrou810023d2010-12-15 22:59:16 +000060
61 do {
Victor Stinner869e1772015-03-30 03:49:14 +020062 microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING);
Victor Stinnerf5faad22015-03-28 03:52:05 +010063
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000064 /* first a simple non-blocking try without releasing the GIL */
65 r = PyThread_acquire_lock_timed(lock, 0, 0);
66 if (r == PY_LOCK_FAILURE && microseconds != 0) {
67 Py_BEGIN_ALLOW_THREADS
68 r = PyThread_acquire_lock_timed(lock, microseconds, 1);
69 Py_END_ALLOW_THREADS
Victor Stinner357f5152013-11-05 15:10:19 +010070 }
Antoine Pitrou810023d2010-12-15 22:59:16 +000071
72 if (r == PY_LOCK_INTR) {
73 /* Run signal handlers if we were interrupted. Propagate
74 * exceptions from signal handlers, such as KeyboardInterrupt, by
75 * passing up PY_LOCK_INTR. */
76 if (Py_MakePendingCalls() < 0) {
77 return PY_LOCK_INTR;
78 }
79
80 /* If we're using a timeout, recompute the timeout after processing
81 * signals, since those can take time. */
Victor Stinnerf5faad22015-03-28 03:52:05 +010082 if (timeout > 0) {
83 timeout = endtime - _PyTime_GetMonotonicClock();
Antoine Pitrou810023d2010-12-15 22:59:16 +000084
85 /* Check for negative values, since those mean block forever.
86 */
Victor Stinner6aa446c2015-03-30 21:33:51 +020087 if (timeout < 0) {
Antoine Pitrou810023d2010-12-15 22:59:16 +000088 r = PY_LOCK_FAILURE;
89 }
90 }
91 }
92 } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */
93
94 return r;
95}
96
Victor Stinnerf5faad22015-03-28 03:52:05 +010097static int
98lock_acquire_parse_args(PyObject *args, PyObject *kwds,
99 _PyTime_t *timeout)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000100{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000101 char *kwlist[] = {"blocking", "timeout", NULL};
102 int blocking = 1;
Victor Stinnerf5faad22015-03-28 03:52:05 +0100103 PyObject *timeout_obj = NULL;
Victor Stinner13019fd2015-04-03 13:10:54 +0200104 const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000105
Victor Stinnerf5faad22015-03-28 03:52:05 +0100106 *timeout = unset_timeout ;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000107
Victor Stinnerf5faad22015-03-28 03:52:05 +0100108 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:acquire", kwlist,
109 &blocking, &timeout_obj))
110 return -1;
111
112 if (timeout_obj
Victor Stinner869e1772015-03-30 03:49:14 +0200113 && _PyTime_FromSecondsObject(timeout,
114 timeout_obj, _PyTime_ROUND_CEILING) < 0)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100115 return -1;
116
117 if (!blocking && *timeout != unset_timeout ) {
118 PyErr_SetString(PyExc_ValueError,
119 "can't specify a timeout for a non-blocking call");
120 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100122 if (*timeout < 0 && *timeout != unset_timeout) {
123 PyErr_SetString(PyExc_ValueError,
124 "timeout value must be positive");
125 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000126 }
127 if (!blocking)
Victor Stinnerf5faad22015-03-28 03:52:05 +0100128 *timeout = 0;
129 else if (*timeout != unset_timeout) {
130 _PyTime_t microseconds;
131
Victor Stinner869e1772015-03-30 03:49:14 +0200132 microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_CEILING);
Victor Stinnerf5faad22015-03-28 03:52:05 +0100133 if (microseconds >= PY_TIMEOUT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000134 PyErr_SetString(PyExc_OverflowError,
135 "timeout value is too large");
Victor Stinnerf5faad22015-03-28 03:52:05 +0100136 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000138 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100139 return 0;
140}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000141
Victor Stinnerf5faad22015-03-28 03:52:05 +0100142static PyObject *
143lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
144{
145 _PyTime_t timeout;
146 PyLockStatus r;
147
148 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
149 return NULL;
150
151 r = acquire_timed(self->lock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000152 if (r == PY_LOCK_INTR) {
153 return NULL;
154 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000156 if (r == PY_LOCK_ACQUIRED)
157 self->locked = 1;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000158 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000159}
160
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000161PyDoc_STRVAR(acquire_doc,
Berker Peksag720e6552016-05-02 12:25:35 +0300162"acquire(blocking=True, timeout=-1) -> bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000163(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000164\n\
165Lock the lock. Without argument, this blocks if the lock is already\n\
166locked (even by the same thread), waiting for another thread to release\n\
R David Murray95b71102013-02-04 10:15:58 -0500167the lock, and return True once the lock is acquired.\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000168With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000169and the return value reflects whether the lock is acquired.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000170The blocking operation is interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000171
Barry Warsawd0c10421996-12-17 00:05:22 +0000172static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000173lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 /* Sanity check: the lock must be locked */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000176 if (!self->locked) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 PyErr_SetString(ThreadError, "release unlocked lock");
178 return NULL;
179 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000181 PyThread_release_lock(self->lock_lock);
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000182 self->locked = 0;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200183 Py_RETURN_NONE;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000184}
185
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000186PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000187"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000188(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000189\n\
190Release the lock, allowing another thread that is blocked waiting for\n\
191the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000192but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000193
Barry Warsawd0c10421996-12-17 00:05:22 +0000194static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000195lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000196{
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000197 return PyBool_FromLong((long)self->locked);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000198}
199
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000200PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000201"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000202(locked_lock() is an obsolete synonym)\n\
203\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000204Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000205
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700206static PyObject *
207lock_repr(lockobject *self)
208{
209 return PyUnicode_FromFormat("<%s %s object at %p>",
210 self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
211}
212
Barry Warsawd0c10421996-12-17 00:05:22 +0000213static PyMethodDef lock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
215 METH_VARARGS | METH_KEYWORDS, acquire_doc},
216 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
217 METH_VARARGS | METH_KEYWORDS, acquire_doc},
218 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
219 METH_NOARGS, release_doc},
220 {"release", (PyCFunction)lock_PyThread_release_lock,
221 METH_NOARGS, release_doc},
222 {"locked_lock", (PyCFunction)lock_locked_lock,
223 METH_NOARGS, locked_doc},
224 {"locked", (PyCFunction)lock_locked_lock,
225 METH_NOARGS, locked_doc},
226 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
227 METH_VARARGS | METH_KEYWORDS, acquire_doc},
228 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
229 METH_VARARGS, release_doc},
230 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000231};
232
Barry Warsawd0c10421996-12-17 00:05:22 +0000233static PyTypeObject Locktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 PyVarObject_HEAD_INIT(&PyType_Type, 0)
235 "_thread.lock", /*tp_name*/
236 sizeof(lockobject), /*tp_size*/
237 0, /*tp_itemsize*/
238 /* methods */
239 (destructor)lock_dealloc, /*tp_dealloc*/
240 0, /*tp_print*/
241 0, /*tp_getattr*/
242 0, /*tp_setattr*/
243 0, /*tp_reserved*/
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700244 (reprfunc)lock_repr, /*tp_repr*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 0, /*tp_as_number*/
246 0, /*tp_as_sequence*/
247 0, /*tp_as_mapping*/
248 0, /*tp_hash*/
249 0, /*tp_call*/
250 0, /*tp_str*/
251 0, /*tp_getattro*/
252 0, /*tp_setattro*/
253 0, /*tp_as_buffer*/
254 Py_TPFLAGS_DEFAULT, /*tp_flags*/
255 0, /*tp_doc*/
256 0, /*tp_traverse*/
257 0, /*tp_clear*/
258 0, /*tp_richcompare*/
259 offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
260 0, /*tp_iter*/
261 0, /*tp_iternext*/
262 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000263};
264
Antoine Pitrou434736a2009-11-10 18:46:01 +0000265/* Recursive lock objects */
266
267typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 PyObject_HEAD
269 PyThread_type_lock rlock_lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200270 unsigned long rlock_owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 unsigned long rlock_count;
272 PyObject *in_weakreflist;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000273} rlockobject;
274
275static void
276rlock_dealloc(rlockobject *self)
277{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278 if (self->in_weakreflist != NULL)
279 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner357f5152013-11-05 15:10:19 +0100280 /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed
281 in rlock_new() */
282 if (self->rlock_lock != NULL) {
283 /* Unlock the lock so it's safe to free it */
284 if (self->rlock_count > 0)
285 PyThread_release_lock(self->rlock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286
Victor Stinner357f5152013-11-05 15:10:19 +0100287 PyThread_free_lock(self->rlock_lock);
288 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 Py_TYPE(self)->tp_free(self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000290}
291
292static PyObject *
293rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
294{
Victor Stinnerf5faad22015-03-28 03:52:05 +0100295 _PyTime_t timeout;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200296 unsigned long tid;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000297 PyLockStatus r = PY_LOCK_ACQUIRED;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000298
Victor Stinnerf5faad22015-03-28 03:52:05 +0100299 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 tid = PyThread_get_thread_ident();
303 if (self->rlock_count > 0 && tid == self->rlock_owner) {
304 unsigned long count = self->rlock_count + 1;
305 if (count <= self->rlock_count) {
306 PyErr_SetString(PyExc_OverflowError,
307 "Internal lock count overflowed");
308 return NULL;
309 }
310 self->rlock_count = count;
311 Py_RETURN_TRUE;
312 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100313 r = acquire_timed(self->rlock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000314 if (r == PY_LOCK_ACQUIRED) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 assert(self->rlock_count == 0);
316 self->rlock_owner = tid;
317 self->rlock_count = 1;
318 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000319 else if (r == PY_LOCK_INTR) {
320 return NULL;
321 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322
Antoine Pitrou810023d2010-12-15 22:59:16 +0000323 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000324}
325
326PyDoc_STRVAR(rlock_acquire_doc,
327"acquire(blocking=True) -> bool\n\
328\n\
329Lock the lock. `blocking` indicates whether we should wait\n\
330for the lock to be available or not. If `blocking` is False\n\
331and another thread holds the lock, the method will return False\n\
332immediately. If `blocking` is True and another thread holds\n\
333the lock, the method will wait for the lock to be released,\n\
334take it and then return True.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000335(note: the blocking operation is interruptible.)\n\
Antoine Pitrou434736a2009-11-10 18:46:01 +0000336\n\
337In all other cases, the method will return True immediately.\n\
338Precisely, if the current thread already holds the lock, its\n\
339internal counter is simply incremented. If nobody holds the lock,\n\
340the lock is taken and its internal counter initialized to 1.");
341
342static PyObject *
343rlock_release(rlockobject *self)
344{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200345 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrou434736a2009-11-10 18:46:01 +0000346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 if (self->rlock_count == 0 || self->rlock_owner != tid) {
348 PyErr_SetString(PyExc_RuntimeError,
349 "cannot release un-acquired lock");
350 return NULL;
351 }
352 if (--self->rlock_count == 0) {
353 self->rlock_owner = 0;
354 PyThread_release_lock(self->rlock_lock);
355 }
356 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000357}
358
359PyDoc_STRVAR(rlock_release_doc,
360"release()\n\
361\n\
362Release the lock, allowing another thread that is blocked waiting for\n\
363the lock to acquire the lock. The lock must be in the locked state,\n\
364and must be locked by the same thread that unlocks it; otherwise a\n\
365`RuntimeError` is raised.\n\
366\n\
367Do note that if the lock was acquire()d several times in a row by the\n\
368current thread, release() needs to be called as many times for the lock\n\
369to be available for other threads.");
370
371static PyObject *
Victor Stinnere8794522014-01-02 12:47:24 +0100372rlock_acquire_restore(rlockobject *self, PyObject *args)
Antoine Pitrou434736a2009-11-10 18:46:01 +0000373{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200374 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 unsigned long count;
376 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000377
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200378 if (!PyArg_ParseTuple(args, "(kk):_acquire_restore", &count, &owner))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
382 Py_BEGIN_ALLOW_THREADS
383 r = PyThread_acquire_lock(self->rlock_lock, 1);
384 Py_END_ALLOW_THREADS
385 }
386 if (!r) {
387 PyErr_SetString(ThreadError, "couldn't acquire lock");
388 return NULL;
389 }
390 assert(self->rlock_count == 0);
391 self->rlock_owner = owner;
392 self->rlock_count = count;
393 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000394}
395
396PyDoc_STRVAR(rlock_acquire_restore_doc,
397"_acquire_restore(state) -> None\n\
398\n\
399For internal use by `threading.Condition`.");
400
401static PyObject *
402rlock_release_save(rlockobject *self)
403{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200404 unsigned long owner;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 unsigned long count;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000406
Victor Stinnerc2824d42011-04-24 23:41:33 +0200407 if (self->rlock_count == 0) {
408 PyErr_SetString(PyExc_RuntimeError,
409 "cannot release un-acquired lock");
410 return NULL;
411 }
412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 owner = self->rlock_owner;
414 count = self->rlock_count;
415 self->rlock_count = 0;
416 self->rlock_owner = 0;
417 PyThread_release_lock(self->rlock_lock);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200418 return Py_BuildValue("kk", count, owner);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000419}
420
421PyDoc_STRVAR(rlock_release_save_doc,
422"_release_save() -> tuple\n\
423\n\
424For internal use by `threading.Condition`.");
425
426
427static PyObject *
428rlock_is_owned(rlockobject *self)
429{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200430 unsigned long tid = PyThread_get_thread_ident();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431
432 if (self->rlock_count > 0 && self->rlock_owner == tid) {
433 Py_RETURN_TRUE;
434 }
435 Py_RETURN_FALSE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000436}
437
438PyDoc_STRVAR(rlock_is_owned_doc,
439"_is_owned() -> bool\n\
440\n\
441For internal use by `threading.Condition`.");
442
443static PyObject *
444rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446 rlockobject *self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 self = (rlockobject *) type->tp_alloc(type, 0);
449 if (self != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 self->in_weakreflist = NULL;
451 self->rlock_owner = 0;
452 self->rlock_count = 0;
Victor Stinner357f5152013-11-05 15:10:19 +0100453
454 self->rlock_lock = PyThread_allocate_lock();
455 if (self->rlock_lock == NULL) {
456 Py_DECREF(self);
457 PyErr_SetString(ThreadError, "can't allocate lock");
458 return NULL;
459 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 return (PyObject *) self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000463}
464
465static PyObject *
466rlock_repr(rlockobject *self)
467{
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700468 return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>",
469 self->rlock_count ? "locked" : "unlocked",
470 Py_TYPE(self)->tp_name, self->rlock_owner,
471 self->rlock_count, self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000472}
473
474
475static PyMethodDef rlock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 {"acquire", (PyCFunction)rlock_acquire,
477 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
478 {"release", (PyCFunction)rlock_release,
479 METH_NOARGS, rlock_release_doc},
480 {"_is_owned", (PyCFunction)rlock_is_owned,
481 METH_NOARGS, rlock_is_owned_doc},
482 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
Victor Stinnere8794522014-01-02 12:47:24 +0100483 METH_VARARGS, rlock_acquire_restore_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 {"_release_save", (PyCFunction)rlock_release_save,
485 METH_NOARGS, rlock_release_save_doc},
486 {"__enter__", (PyCFunction)rlock_acquire,
487 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
488 {"__exit__", (PyCFunction)rlock_release,
489 METH_VARARGS, rlock_release_doc},
490 {NULL, NULL} /* sentinel */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000491};
492
493
494static PyTypeObject RLocktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 PyVarObject_HEAD_INIT(&PyType_Type, 0)
496 "_thread.RLock", /*tp_name*/
497 sizeof(rlockobject), /*tp_size*/
498 0, /*tp_itemsize*/
499 /* methods */
500 (destructor)rlock_dealloc, /*tp_dealloc*/
501 0, /*tp_print*/
502 0, /*tp_getattr*/
503 0, /*tp_setattr*/
504 0, /*tp_reserved*/
505 (reprfunc)rlock_repr, /*tp_repr*/
506 0, /*tp_as_number*/
507 0, /*tp_as_sequence*/
508 0, /*tp_as_mapping*/
509 0, /*tp_hash*/
510 0, /*tp_call*/
511 0, /*tp_str*/
512 0, /*tp_getattro*/
513 0, /*tp_setattro*/
514 0, /*tp_as_buffer*/
515 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
516 0, /*tp_doc*/
517 0, /*tp_traverse*/
518 0, /*tp_clear*/
519 0, /*tp_richcompare*/
520 offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
521 0, /*tp_iter*/
522 0, /*tp_iternext*/
523 rlock_methods, /*tp_methods*/
524 0, /* tp_members */
525 0, /* tp_getset */
526 0, /* tp_base */
527 0, /* tp_dict */
528 0, /* tp_descr_get */
529 0, /* tp_descr_set */
530 0, /* tp_dictoffset */
531 0, /* tp_init */
532 PyType_GenericAlloc, /* tp_alloc */
533 rlock_new /* tp_new */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000534};
535
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000536static lockobject *
537newlockobject(void)
538{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 lockobject *self;
540 self = PyObject_New(lockobject, &Locktype);
541 if (self == NULL)
542 return NULL;
543 self->lock_lock = PyThread_allocate_lock();
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000544 self->locked = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 self->in_weakreflist = NULL;
546 if (self->lock_lock == NULL) {
547 Py_DECREF(self);
548 PyErr_SetString(ThreadError, "can't allocate lock");
549 return NULL;
550 }
551 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000552}
553
Jim Fultond15dc062004-07-14 19:11:50 +0000554/* Thread-local objects */
555
556#include "structmember.h"
557
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000558/* Quick overview:
559
560 We need to be able to reclaim reference cycles as soon as possible
561 (both when a thread is being terminated, or a thread-local object
562 becomes unreachable from user data). Constraints:
563 - it must not be possible for thread-state dicts to be involved in
564 reference cycles (otherwise the cyclic GC will refuse to consider
565 objects referenced from a reachable thread-state dict, even though
566 local_dealloc would clear them)
567 - the death of a thread-state dict must still imply destruction of the
568 corresponding local dicts in all thread-local objects.
569
570 Our implementation uses small "localdummy" objects in order to break
571 the reference chain. These trivial objects are hashable (using the
572 default scheme of identity hashing) and weakrefable.
573 Each thread-state holds a separate localdummy for each local object
574 (as a /strong reference/),
575 and each thread-local object holds a dict mapping /weak references/
576 of localdummies to local dicts.
577
578 Therefore:
579 - only the thread-state dict holds a strong reference to the dummies
580 - only the thread-local object holds a strong reference to the local dicts
581 - only outside objects (application- or library-level) hold strong
582 references to the thread-local objects
583 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
584 dummies attached to that thread are called, and destroy the corresponding
585 local dicts from thread-local objects
586 - as soon as a thread-local object is destroyed, its local dicts are
587 destroyed and its dummies are manually removed from all thread states
588 - the GC can do its work correctly when a thread-local object is dangling,
589 without any interference from the thread-state dicts
590
591 As an additional optimization, each localdummy holds a borrowed reference
592 to the corresponding localdict. This borrowed reference is only used
593 by the thread-local object which has created the localdummy, which should
594 guarantee that the localdict still exists when accessed.
595*/
596
597typedef struct {
598 PyObject_HEAD
599 PyObject *localdict; /* Borrowed reference! */
600 PyObject *weakreflist; /* List of weak references to self */
601} localdummyobject;
602
603static void
604localdummy_dealloc(localdummyobject *self)
605{
606 if (self->weakreflist != NULL)
607 PyObject_ClearWeakRefs((PyObject *) self);
608 Py_TYPE(self)->tp_free((PyObject*)self);
609}
610
611static PyTypeObject localdummytype = {
612 PyVarObject_HEAD_INIT(NULL, 0)
613 /* tp_name */ "_thread._localdummy",
614 /* tp_basicsize */ sizeof(localdummyobject),
615 /* tp_itemsize */ 0,
616 /* tp_dealloc */ (destructor)localdummy_dealloc,
617 /* tp_print */ 0,
618 /* tp_getattr */ 0,
619 /* tp_setattr */ 0,
620 /* tp_reserved */ 0,
621 /* tp_repr */ 0,
622 /* tp_as_number */ 0,
623 /* tp_as_sequence */ 0,
624 /* tp_as_mapping */ 0,
625 /* tp_hash */ 0,
626 /* tp_call */ 0,
627 /* tp_str */ 0,
628 /* tp_getattro */ 0,
629 /* tp_setattro */ 0,
630 /* tp_as_buffer */ 0,
631 /* tp_flags */ Py_TPFLAGS_DEFAULT,
632 /* tp_doc */ "Thread-local dummy",
633 /* tp_traverse */ 0,
634 /* tp_clear */ 0,
635 /* tp_richcompare */ 0,
636 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
637};
638
639
Jim Fultond15dc062004-07-14 19:11:50 +0000640typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 PyObject_HEAD
642 PyObject *key;
643 PyObject *args;
644 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000645 PyObject *weakreflist; /* List of weak references to self */
646 /* A {localdummy weakref -> localdict} dict */
647 PyObject *dummies;
648 /* The callback for weakrefs to localdummies */
649 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000650} localobject;
651
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000652/* Forward declaration */
653static PyObject *_ldict(localobject *self);
654static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
655
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000656/* Create and register the dummy for the current thread.
657 Returns a borrowed reference of the corresponding local dict */
658static PyObject *
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000659_local_create_dummy(localobject *self)
660{
661 PyObject *tdict, *ldict = NULL, *wr = NULL;
662 localdummyobject *dummy = NULL;
663 int r;
664
665 tdict = PyThreadState_GetDict();
666 if (tdict == NULL) {
667 PyErr_SetString(PyExc_SystemError,
668 "Couldn't get thread-state dictionary");
669 goto err;
670 }
671
672 ldict = PyDict_New();
673 if (ldict == NULL)
674 goto err;
675 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
676 if (dummy == NULL)
677 goto err;
678 dummy->localdict = ldict;
679 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
680 if (wr == NULL)
681 goto err;
682
683 /* As a side-effect, this will cache the weakref's hash before the
684 dummy gets deleted */
685 r = PyDict_SetItem(self->dummies, wr, ldict);
686 if (r < 0)
687 goto err;
688 Py_CLEAR(wr);
689 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
690 if (r < 0)
691 goto err;
692 Py_CLEAR(dummy);
693
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000694 Py_DECREF(ldict);
695 return ldict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000696
697err:
698 Py_XDECREF(ldict);
699 Py_XDECREF(wr);
700 Py_XDECREF(dummy);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000701 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000702}
703
Jim Fultond15dc062004-07-14 19:11:50 +0000704static PyObject *
705local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
706{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 localobject *self;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000708 PyObject *wr;
709 static PyMethodDef wr_callback_def = {
710 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
711 };
Jim Fultond15dc062004-07-14 19:11:50 +0000712
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300713 if (type->tp_init == PyBaseObject_Type.tp_init) {
714 int rc = 0;
715 if (args != NULL)
716 rc = PyObject_IsTrue(args);
717 if (rc == 0 && kw != NULL)
718 rc = PyObject_IsTrue(kw);
719 if (rc != 0) {
720 if (rc > 0)
721 PyErr_SetString(PyExc_TypeError,
722 "Initialization arguments are not supported");
723 return NULL;
724 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 }
Jim Fultond15dc062004-07-14 19:11:50 +0000726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727 self = (localobject *)type->tp_alloc(type, 0);
728 if (self == NULL)
729 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000730
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 Py_XINCREF(args);
732 self->args = args;
733 Py_XINCREF(kw);
734 self->kw = kw;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 self->key = PyUnicode_FromFormat("thread.local.%p", self);
736 if (self->key == NULL)
737 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000738
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000739 self->dummies = PyDict_New();
740 if (self->dummies == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000742
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000743 /* We use a weak reference to self in the callback closure
744 in order to avoid spurious reference cycles */
745 wr = PyWeakref_NewRef((PyObject *) self, NULL);
746 if (wr == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 goto err;
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200748 self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000749 Py_DECREF(wr);
750 if (self->wr_callback == NULL)
751 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000752
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000753 if (_local_create_dummy(self) == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000756 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000757
758 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 Py_DECREF(self);
760 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000761}
762
763static int
764local_traverse(localobject *self, visitproc visit, void *arg)
765{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000766 Py_VISIT(self->args);
767 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000768 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000770}
771
772static int
773local_clear(localobject *self)
774{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000775 PyThreadState *tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 Py_CLEAR(self->args);
777 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000778 Py_CLEAR(self->dummies);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000779 Py_CLEAR(self->wr_callback);
780 /* Remove all strong references to dummies from the thread states */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000781 if (self->key
782 && (tstate = PyThreadState_Get())
783 && tstate->interp) {
784 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
785 tstate;
786 tstate = PyThreadState_Next(tstate))
787 if (tstate->dict &&
788 PyDict_GetItem(tstate->dict, self->key))
789 PyDict_DelItem(tstate->dict, self->key);
790 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000791 return 0;
792}
Jim Fultond15dc062004-07-14 19:11:50 +0000793
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000794static void
795local_dealloc(localobject *self)
796{
797 /* Weakrefs must be invalidated right now, otherwise they can be used
798 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
799 if (self->weakreflist != NULL)
800 PyObject_ClearWeakRefs((PyObject *) self);
801
802 PyObject_GC_UnTrack(self);
803
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000804 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000805 Py_XDECREF(self->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000806 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000807}
808
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000809/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000810static PyObject *
811_ldict(localobject *self)
812{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000813 PyObject *tdict, *ldict, *dummy;
Jim Fultond15dc062004-07-14 19:11:50 +0000814
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000815 tdict = PyThreadState_GetDict();
816 if (tdict == NULL) {
817 PyErr_SetString(PyExc_SystemError,
818 "Couldn't get thread-state dictionary");
819 return NULL;
820 }
Jim Fultond15dc062004-07-14 19:11:50 +0000821
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000822 dummy = PyDict_GetItem(tdict, self->key);
823 if (dummy == NULL) {
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000824 ldict = _local_create_dummy(self);
825 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000828 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
829 Py_TYPE(self)->tp_init((PyObject*)self,
830 self->args, self->kw) < 0) {
831 /* we need to get rid of ldict from thread so
832 we create a new one the next time we do an attr
Ezio Melotti42da6632011-03-15 05:18:48 +0200833 access */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000834 PyDict_DelItem(tdict, self->key);
835 return NULL;
836 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000837 }
838 else {
839 assert(Py_TYPE(dummy) == &localdummytype);
840 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 }
Jim Fultond15dc062004-07-14 19:11:50 +0000842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000843 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000844}
845
Jim Fultond15dc062004-07-14 19:11:50 +0000846static int
847local_setattro(localobject *self, PyObject *name, PyObject *v)
848{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000849 PyObject *ldict;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000850 int r;
Jim Fultond15dc062004-07-14 19:11:50 +0000851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000852 ldict = _ldict(self);
853 if (ldict == NULL)
854 return -1;
855
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000856 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
857 if (r == 1) {
858 PyErr_Format(PyExc_AttributeError,
859 "'%.50s' object attribute '%U' is read-only",
860 Py_TYPE(self)->tp_name, name);
861 return -1;
862 }
863 if (r == -1)
864 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000865
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000866 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000867}
868
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000869static PyObject *local_getattro(localobject *, PyObject *);
870
Jim Fultond15dc062004-07-14 19:11:50 +0000871static PyTypeObject localtype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000872 PyVarObject_HEAD_INIT(NULL, 0)
873 /* tp_name */ "_thread._local",
874 /* tp_basicsize */ sizeof(localobject),
875 /* tp_itemsize */ 0,
876 /* tp_dealloc */ (destructor)local_dealloc,
877 /* tp_print */ 0,
878 /* tp_getattr */ 0,
879 /* tp_setattr */ 0,
880 /* tp_reserved */ 0,
881 /* tp_repr */ 0,
882 /* tp_as_number */ 0,
883 /* tp_as_sequence */ 0,
884 /* tp_as_mapping */ 0,
885 /* tp_hash */ 0,
886 /* tp_call */ 0,
887 /* tp_str */ 0,
888 /* tp_getattro */ (getattrofunc)local_getattro,
889 /* tp_setattro */ (setattrofunc)local_setattro,
890 /* tp_as_buffer */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000891 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
892 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000893 /* tp_doc */ "Thread-local data",
894 /* tp_traverse */ (traverseproc)local_traverse,
895 /* tp_clear */ (inquiry)local_clear,
896 /* tp_richcompare */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000897 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 /* tp_iter */ 0,
899 /* tp_iternext */ 0,
900 /* tp_methods */ 0,
901 /* tp_members */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000902 /* tp_getset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 /* tp_base */ 0,
904 /* tp_dict */ 0, /* internal use */
905 /* tp_descr_get */ 0,
906 /* tp_descr_set */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000907 /* tp_dictoffset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000908 /* tp_init */ 0,
909 /* tp_alloc */ 0,
910 /* tp_new */ local_new,
911 /* tp_free */ 0, /* Low-level free-mem routine */
912 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000913};
914
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000915static PyObject *
916local_getattro(localobject *self, PyObject *name)
917{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000918 PyObject *ldict, *value;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000919 int r;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000920
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 ldict = _ldict(self);
922 if (ldict == NULL)
923 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000924
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000925 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
926 if (r == 1) {
927 Py_INCREF(ldict);
928 return ldict;
929 }
930 if (r == -1)
931 return NULL;
932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 if (Py_TYPE(self) != &localtype)
934 /* use generic lookup for subtypes */
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000935 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000937 /* Optimization: just look in dict ourselves */
938 value = PyDict_GetItem(ldict, name);
939 if (value == NULL)
940 /* Fall back on generic to get __class__ and __dict__ */
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000941 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 Py_INCREF(value);
944 return value;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000945}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000946
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000947/* Called when a dummy is destroyed. */
948static PyObject *
949_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
950{
951 PyObject *obj;
952 localobject *self;
953 assert(PyWeakref_CheckRef(localweakref));
954 obj = PyWeakref_GET_OBJECT(localweakref);
955 if (obj == Py_None)
956 Py_RETURN_NONE;
957 Py_INCREF(obj);
958 assert(PyObject_TypeCheck(obj, &localtype));
959 /* If the thread-local object is still alive and not being cleared,
960 remove the corresponding local dict */
961 self = (localobject *) obj;
962 if (self->dummies != NULL) {
963 PyObject *ldict;
964 ldict = PyDict_GetItem(self->dummies, dummyweakref);
965 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000966 PyDict_DelItem(self->dummies, dummyweakref);
967 }
968 if (PyErr_Occurred())
969 PyErr_WriteUnraisable(obj);
970 }
971 Py_DECREF(obj);
972 Py_RETURN_NONE;
973}
974
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000975/* Module functions */
976
Guido van Rossuma027efa1997-05-05 20:56:21 +0000977struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 PyInterpreterState *interp;
979 PyObject *func;
980 PyObject *args;
981 PyObject *keyw;
982 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000983};
984
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000985static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000986t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000987{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 struct bootstate *boot = (struct bootstate *) boot_raw;
989 PyThreadState *tstate;
990 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000992 tstate = boot->tstate;
993 tstate->thread_id = PyThread_get_thread_ident();
994 _PyThreadState_Init(tstate);
995 PyEval_AcquireThread(tstate);
996 nb_threads++;
INADA Naoki72dccde2017-02-16 09:26:01 +0900997 res = PyObject_Call(boot->func, boot->args, boot->keyw);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000998 if (res == NULL) {
999 if (PyErr_ExceptionMatches(PyExc_SystemExit))
1000 PyErr_Clear();
1001 else {
1002 PyObject *file;
Benjamin Petersone9000962012-04-02 11:15:17 -04001003 PyObject *exc, *value, *tb;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 PySys_WriteStderr(
1005 "Unhandled exception in thread started by ");
Benjamin Petersone9000962012-04-02 11:15:17 -04001006 PyErr_Fetch(&exc, &value, &tb);
Victor Stinnerbd303c12013-11-07 23:07:29 +01001007 file = _PySys_GetObjectId(&PyId_stderr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 if (file != NULL && file != Py_None)
1009 PyFile_WriteObject(boot->func, file, 0);
1010 else
1011 PyObject_Print(boot->func, stderr, 0);
1012 PySys_WriteStderr("\n");
Benjamin Petersone9000962012-04-02 11:15:17 -04001013 PyErr_Restore(exc, value, tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 PyErr_PrintEx(0);
1015 }
1016 }
1017 else
1018 Py_DECREF(res);
1019 Py_DECREF(boot->func);
1020 Py_DECREF(boot->args);
1021 Py_XDECREF(boot->keyw);
1022 PyMem_DEL(boot_raw);
1023 nb_threads--;
1024 PyThreadState_Clear(tstate);
1025 PyThreadState_DeleteCurrent();
1026 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001027}
1028
Barry Warsawd0c10421996-12-17 00:05:22 +00001029static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001030thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001031{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 PyObject *func, *args, *keyw = NULL;
1033 struct bootstate *boot;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001034 unsigned long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
1037 &func, &args, &keyw))
1038 return NULL;
1039 if (!PyCallable_Check(func)) {
1040 PyErr_SetString(PyExc_TypeError,
1041 "first arg must be callable");
1042 return NULL;
1043 }
1044 if (!PyTuple_Check(args)) {
1045 PyErr_SetString(PyExc_TypeError,
1046 "2nd arg must be a tuple");
1047 return NULL;
1048 }
1049 if (keyw != NULL && !PyDict_Check(keyw)) {
1050 PyErr_SetString(PyExc_TypeError,
1051 "optional 3rd arg must be a dictionary");
1052 return NULL;
1053 }
1054 boot = PyMem_NEW(struct bootstate, 1);
1055 if (boot == NULL)
1056 return PyErr_NoMemory();
1057 boot->interp = PyThreadState_GET()->interp;
1058 boot->func = func;
1059 boot->args = args;
1060 boot->keyw = keyw;
1061 boot->tstate = _PyThreadState_Prealloc(boot->interp);
1062 if (boot->tstate == NULL) {
1063 PyMem_DEL(boot);
1064 return PyErr_NoMemory();
1065 }
1066 Py_INCREF(func);
1067 Py_INCREF(args);
1068 Py_XINCREF(keyw);
1069 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
1070 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001071 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 PyErr_SetString(ThreadError, "can't start new thread");
1073 Py_DECREF(func);
1074 Py_DECREF(args);
1075 Py_XDECREF(keyw);
1076 PyThreadState_Clear(boot->tstate);
1077 PyMem_DEL(boot);
1078 return NULL;
1079 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001080 return PyLong_FromUnsignedLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001081}
1082
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001083PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001084"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001085(start_new() is an obsolete synonym)\n\
1086\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001087Start a new thread and return its identifier. The thread will call the\n\
1088function with positional arguments from the tuple args and keyword arguments\n\
1089taken from the optional dictionary kwargs. The thread exits when the\n\
1090function returns; the return value is ignored. The thread will also exit\n\
1091when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001092printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001093
Barry Warsawd0c10421996-12-17 00:05:22 +00001094static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001095thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001096{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001097 PyErr_SetNone(PyExc_SystemExit);
1098 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001099}
1100
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001101PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001102"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001103(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001104\n\
1105This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001106thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001107
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001108static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001109thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001110{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001111 PyErr_SetInterrupt();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001112 Py_RETURN_NONE;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001113}
1114
1115PyDoc_STRVAR(interrupt_doc,
1116"interrupt_main()\n\
1117\n\
1118Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001119A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001120);
1121
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001122static lockobject *newlockobject(void);
1123
Barry Warsawd0c10421996-12-17 00:05:22 +00001124static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001125thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001126{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001127 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001128}
1129
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001130PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001131"allocate_lock() -> lock object\n\
1132(allocate() is an obsolete synonym)\n\
1133\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001134Create a new lock object. See help(type(threading.Lock())) for\n\
1135information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001136
Barry Warsawd0c10421996-12-17 00:05:22 +00001137static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001138thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001139{
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001140 unsigned long ident = PyThread_get_thread_ident();
1141 if (ident == PYTHREAD_INVALID_THREAD_ID) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 PyErr_SetString(ThreadError, "no current thread ident");
1143 return NULL;
1144 }
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +02001145 return PyLong_FromUnsignedLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001146}
1147
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001148PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001149"get_ident() -> integer\n\
1150\n\
1151Return a non-zero integer that uniquely identifies the current thread\n\
1152amongst other threads that exist simultaneously.\n\
1153This may be used to identify per-thread resources.\n\
1154Even though on some platforms threads identities may appear to be\n\
1155allocated consecutive numbers starting at 1, this behavior should not\n\
1156be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001157A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001158
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001159static PyObject *
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001160thread__count(PyObject *self)
1161{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 return PyLong_FromLong(nb_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001163}
1164
1165PyDoc_STRVAR(_count_doc,
1166"_count() -> integer\n\
1167\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001168\
1169Return the number of currently running Python threads, excluding \n\
1170the main thread. The returned number comprises all threads created\n\
1171through `start_new_thread()` as well as `threading.Thread`, and not\n\
1172yet finished.\n\
1173\n\
1174This function is meant for internal and specialized purposes only.\n\
1175In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001176
Antoine Pitrou7b476992013-09-07 23:38:37 +02001177static void
1178release_sentinel(void *wr)
1179{
1180 /* Tricky: this function is called when the current thread state
1181 is being deleted. Therefore, only simple C code can safely
1182 execute here. */
1183 PyObject *obj = PyWeakref_GET_OBJECT(wr);
1184 lockobject *lock;
1185 if (obj != Py_None) {
1186 assert(Py_TYPE(obj) == &Locktype);
1187 lock = (lockobject *) obj;
1188 if (lock->locked) {
1189 PyThread_release_lock(lock->lock_lock);
1190 lock->locked = 0;
1191 }
1192 }
1193 /* Deallocating a weakref with a NULL callback only calls
1194 PyObject_GC_Del(), which can't call any Python code. */
1195 Py_DECREF(wr);
1196}
1197
1198static PyObject *
1199thread__set_sentinel(PyObject *self)
1200{
1201 PyObject *wr;
1202 PyThreadState *tstate = PyThreadState_Get();
1203 lockobject *lock;
1204
1205 if (tstate->on_delete_data != NULL) {
1206 /* We must support the re-creation of the lock from a
1207 fork()ed child. */
1208 assert(tstate->on_delete == &release_sentinel);
1209 wr = (PyObject *) tstate->on_delete_data;
1210 tstate->on_delete = NULL;
1211 tstate->on_delete_data = NULL;
1212 Py_DECREF(wr);
1213 }
1214 lock = newlockobject();
1215 if (lock == NULL)
1216 return NULL;
1217 /* The lock is owned by whoever called _set_sentinel(), but the weakref
1218 hangs to the thread state. */
1219 wr = PyWeakref_NewRef((PyObject *) lock, NULL);
1220 if (wr == NULL) {
1221 Py_DECREF(lock);
1222 return NULL;
1223 }
1224 tstate->on_delete_data = (void *) wr;
1225 tstate->on_delete = &release_sentinel;
1226 return (PyObject *) lock;
1227}
1228
1229PyDoc_STRVAR(_set_sentinel_doc,
1230"_set_sentinel() -> lock\n\
1231\n\
1232Set a sentinel lock that will be released when the current thread\n\
1233state is finalized (after it is untied from the interpreter).\n\
1234\n\
1235This is a private API for the threading module.");
1236
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001237static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001238thread_stack_size(PyObject *self, PyObject *args)
1239{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 size_t old_size;
1241 Py_ssize_t new_size = 0;
1242 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1245 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 if (new_size < 0) {
1248 PyErr_SetString(PyExc_ValueError,
1249 "size must be 0 or a positive value");
1250 return NULL;
1251 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 rc = PyThread_set_stacksize((size_t) new_size);
1256 if (rc == -1) {
1257 PyErr_Format(PyExc_ValueError,
1258 "size not valid: %zd bytes",
1259 new_size);
1260 return NULL;
1261 }
1262 if (rc == -2) {
1263 PyErr_SetString(ThreadError,
1264 "setting stack size not supported");
1265 return NULL;
1266 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001269}
1270
1271PyDoc_STRVAR(stack_size_doc,
1272"stack_size([size]) -> size\n\
1273\n\
1274Return the thread stack size used when creating new threads. The\n\
1275optional size argument specifies the stack size (in bytes) to be used\n\
1276for subsequently created threads, and must be 0 (use platform or\n\
1277configured default) or a positive integer value of at least 32,768 (32k).\n\
1278If changing the thread stack size is unsupported, a ThreadError\n\
1279exception is raised. If the specified size is invalid, a ValueError\n\
1280exception is raised, and the stack size is unmodified. 32k bytes\n\
1281 currently the minimum supported stack size value to guarantee\n\
1282sufficient stack space for the interpreter itself.\n\
1283\n\
1284Note that some platforms may have particular restrictions on values for\n\
1285the stack size, such as requiring a minimum stack size larger than 32kB or\n\
1286requiring allocation in multiples of the system memory page size\n\
1287- platform documentation should be referred to for more information\n\
1288(4kB pages are common; using multiples of 4096 for the stack size is\n\
1289the suggested approach in the absence of more specific information).");
1290
Barry Warsawd0c10421996-12-17 00:05:22 +00001291static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001293 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001295 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
1297 METH_NOARGS, allocate_doc},
1298 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
1299 METH_NOARGS, allocate_doc},
1300 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
1301 METH_NOARGS, exit_doc},
1302 {"exit", (PyCFunction)thread_PyThread_exit_thread,
1303 METH_NOARGS, exit_doc},
1304 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
1305 METH_NOARGS, interrupt_doc},
1306 {"get_ident", (PyCFunction)thread_get_ident,
1307 METH_NOARGS, get_ident_doc},
1308 {"_count", (PyCFunction)thread__count,
1309 METH_NOARGS, _count_doc},
1310 {"stack_size", (PyCFunction)thread_stack_size,
Victor Stinner754851f2011-04-19 23:58:51 +02001311 METH_VARARGS, stack_size_doc},
Antoine Pitrou7b476992013-09-07 23:38:37 +02001312 {"_set_sentinel", (PyCFunction)thread__set_sentinel,
1313 METH_NOARGS, _set_sentinel_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001315};
1316
1317
1318/* Initialization function */
1319
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001320PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001321"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001322The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001323
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001324PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001325"A lock object is a synchronization primitive. To create a lock,\n\
Berker Peksag720e6552016-05-02 12:25:35 +03001326call threading.Lock(). Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001327\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001328acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1329release() -- unlock of the lock\n\
1330locked() -- test whether the lock is currently locked\n\
1331\n\
1332A lock is not owned by the thread that locked it; another thread may\n\
1333unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001334will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001335
Martin v. Löwis1a214512008-06-11 05:26:20 +00001336static struct PyModuleDef threadmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 PyModuleDef_HEAD_INIT,
1338 "_thread",
1339 thread_doc,
1340 -1,
1341 thread_methods,
1342 NULL,
1343 NULL,
1344 NULL,
1345 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001346};
1347
1348
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001349PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001350PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001351{
Victor Stinnerf5faad22015-03-28 03:52:05 +01001352 PyObject *m, *d, *v;
1353 double time_max;
1354 double timeout_max;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 /* Initialize types: */
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001357 if (PyType_Ready(&localdummytype) < 0)
1358 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 if (PyType_Ready(&localtype) < 0)
1360 return NULL;
1361 if (PyType_Ready(&Locktype) < 0)
1362 return NULL;
1363 if (PyType_Ready(&RLocktype) < 0)
1364 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 /* Create the module and add the functions */
1367 m = PyModule_Create(&threadmodule);
1368 if (m == NULL)
1369 return NULL;
Antoine Pitrou7c3e5772010-04-14 15:44:10 +00001370
Victor Stinnerf5faad22015-03-28 03:52:05 +01001371 timeout_max = PY_TIMEOUT_MAX / 1000000;
1372 time_max = floor(_PyTime_AsSecondsDouble(_PyTime_MAX));
1373 timeout_max = Py_MIN(timeout_max, time_max);
1374
1375 v = PyFloat_FromDouble(timeout_max);
1376 if (!v)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 return NULL;
Victor Stinnerf5faad22015-03-28 03:52:05 +01001378 if (PyModule_AddObject(m, "TIMEOUT_MAX", v) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 /* Add a symbolic constant */
1382 d = PyModule_GetDict(m);
Antoine Pitroufcf81fd2011-02-28 22:03:34 +00001383 ThreadError = PyExc_RuntimeError;
1384 Py_INCREF(ThreadError);
Victor Stinner754851f2011-04-19 23:58:51 +02001385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 PyDict_SetItemString(d, "error", ThreadError);
1387 Locktype.tp_doc = lock_doc;
1388 Py_INCREF(&Locktype);
1389 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Antoine Pitrou434736a2009-11-10 18:46:01 +00001390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 Py_INCREF(&RLocktype);
1392 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1393 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 Py_INCREF(&localtype);
1396 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1397 return NULL;
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 nb_threads = 0;
1400
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +00001401 str_dict = PyUnicode_InternFromString("__dict__");
1402 if (str_dict == NULL)
1403 return NULL;
1404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001405 /* Initialize the C thread library */
1406 PyThread_init_thread();
1407 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001408}