blob: 0907aa0eb25f9c1c438bdb31e45ed66e30c6004a [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
48 * are returned, depending on whether the lock can be acquired withing the
49 * 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 Stinnerf5faad22015-03-28 03:52:05 +010087 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;
104 const _PyTime_t unset_timeout = _PyTime_FromNanoseconds(-1000000000);
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,
R David Murray95b71102013-02-04 10:15:58 -0500162"acquire([wait]) -> 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;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000183 Py_INCREF(Py_None);
184 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000185}
186
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000187PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000188"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000189(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000190\n\
191Release the lock, allowing another thread that is blocked waiting for\n\
192the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000193but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000194
Barry Warsawd0c10421996-12-17 00:05:22 +0000195static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000196lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000197{
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000198 return PyBool_FromLong((long)self->locked);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000199}
200
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000201PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000202"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000203(locked_lock() is an obsolete synonym)\n\
204\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000205Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000206
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700207static PyObject *
208lock_repr(lockobject *self)
209{
210 return PyUnicode_FromFormat("<%s %s object at %p>",
211 self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
212}
213
Barry Warsawd0c10421996-12-17 00:05:22 +0000214static PyMethodDef lock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
216 METH_VARARGS | METH_KEYWORDS, acquire_doc},
217 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
218 METH_VARARGS | METH_KEYWORDS, acquire_doc},
219 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
220 METH_NOARGS, release_doc},
221 {"release", (PyCFunction)lock_PyThread_release_lock,
222 METH_NOARGS, release_doc},
223 {"locked_lock", (PyCFunction)lock_locked_lock,
224 METH_NOARGS, locked_doc},
225 {"locked", (PyCFunction)lock_locked_lock,
226 METH_NOARGS, locked_doc},
227 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
228 METH_VARARGS | METH_KEYWORDS, acquire_doc},
229 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
230 METH_VARARGS, release_doc},
231 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000232};
233
Barry Warsawd0c10421996-12-17 00:05:22 +0000234static PyTypeObject Locktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 PyVarObject_HEAD_INIT(&PyType_Type, 0)
236 "_thread.lock", /*tp_name*/
237 sizeof(lockobject), /*tp_size*/
238 0, /*tp_itemsize*/
239 /* methods */
240 (destructor)lock_dealloc, /*tp_dealloc*/
241 0, /*tp_print*/
242 0, /*tp_getattr*/
243 0, /*tp_setattr*/
244 0, /*tp_reserved*/
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700245 (reprfunc)lock_repr, /*tp_repr*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 0, /*tp_as_number*/
247 0, /*tp_as_sequence*/
248 0, /*tp_as_mapping*/
249 0, /*tp_hash*/
250 0, /*tp_call*/
251 0, /*tp_str*/
252 0, /*tp_getattro*/
253 0, /*tp_setattro*/
254 0, /*tp_as_buffer*/
255 Py_TPFLAGS_DEFAULT, /*tp_flags*/
256 0, /*tp_doc*/
257 0, /*tp_traverse*/
258 0, /*tp_clear*/
259 0, /*tp_richcompare*/
260 offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
261 0, /*tp_iter*/
262 0, /*tp_iternext*/
263 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000264};
265
Antoine Pitrou434736a2009-11-10 18:46:01 +0000266/* Recursive lock objects */
267
268typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 PyObject_HEAD
270 PyThread_type_lock rlock_lock;
271 long rlock_owner;
272 unsigned long rlock_count;
273 PyObject *in_weakreflist;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000274} rlockobject;
275
276static void
277rlock_dealloc(rlockobject *self)
278{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 if (self->in_weakreflist != NULL)
280 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner357f5152013-11-05 15:10:19 +0100281 /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed
282 in rlock_new() */
283 if (self->rlock_lock != NULL) {
284 /* Unlock the lock so it's safe to free it */
285 if (self->rlock_count > 0)
286 PyThread_release_lock(self->rlock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287
Victor Stinner357f5152013-11-05 15:10:19 +0100288 PyThread_free_lock(self->rlock_lock);
289 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 Py_TYPE(self)->tp_free(self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000291}
292
293static PyObject *
294rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
295{
Victor Stinnerf5faad22015-03-28 03:52:05 +0100296 _PyTime_t timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 long tid;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000298 PyLockStatus r = PY_LOCK_ACQUIRED;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000299
Victor Stinnerf5faad22015-03-28 03:52:05 +0100300 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 tid = PyThread_get_thread_ident();
304 if (self->rlock_count > 0 && tid == self->rlock_owner) {
305 unsigned long count = self->rlock_count + 1;
306 if (count <= self->rlock_count) {
307 PyErr_SetString(PyExc_OverflowError,
308 "Internal lock count overflowed");
309 return NULL;
310 }
311 self->rlock_count = count;
312 Py_RETURN_TRUE;
313 }
Victor Stinnerf5faad22015-03-28 03:52:05 +0100314 r = acquire_timed(self->rlock_lock, timeout);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000315 if (r == PY_LOCK_ACQUIRED) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 assert(self->rlock_count == 0);
317 self->rlock_owner = tid;
318 self->rlock_count = 1;
319 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000320 else if (r == PY_LOCK_INTR) {
321 return NULL;
322 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323
Antoine Pitrou810023d2010-12-15 22:59:16 +0000324 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000325}
326
327PyDoc_STRVAR(rlock_acquire_doc,
328"acquire(blocking=True) -> bool\n\
329\n\
330Lock the lock. `blocking` indicates whether we should wait\n\
331for the lock to be available or not. If `blocking` is False\n\
332and another thread holds the lock, the method will return False\n\
333immediately. If `blocking` is True and another thread holds\n\
334the lock, the method will wait for the lock to be released,\n\
335take it and then return True.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000336(note: the blocking operation is interruptible.)\n\
Antoine Pitrou434736a2009-11-10 18:46:01 +0000337\n\
338In all other cases, the method will return True immediately.\n\
339Precisely, if the current thread already holds the lock, its\n\
340internal counter is simply incremented. If nobody holds the lock,\n\
341the lock is taken and its internal counter initialized to 1.");
342
343static PyObject *
344rlock_release(rlockobject *self)
345{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000346 long tid = PyThread_get_thread_ident();
Antoine Pitrou434736a2009-11-10 18:46:01 +0000347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 if (self->rlock_count == 0 || self->rlock_owner != tid) {
349 PyErr_SetString(PyExc_RuntimeError,
350 "cannot release un-acquired lock");
351 return NULL;
352 }
353 if (--self->rlock_count == 0) {
354 self->rlock_owner = 0;
355 PyThread_release_lock(self->rlock_lock);
356 }
357 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000358}
359
360PyDoc_STRVAR(rlock_release_doc,
361"release()\n\
362\n\
363Release the lock, allowing another thread that is blocked waiting for\n\
364the lock to acquire the lock. The lock must be in the locked state,\n\
365and must be locked by the same thread that unlocks it; otherwise a\n\
366`RuntimeError` is raised.\n\
367\n\
368Do note that if the lock was acquire()d several times in a row by the\n\
369current thread, release() needs to be called as many times for the lock\n\
370to be available for other threads.");
371
372static PyObject *
Victor Stinnere8794522014-01-02 12:47:24 +0100373rlock_acquire_restore(rlockobject *self, PyObject *args)
Antoine Pitrou434736a2009-11-10 18:46:01 +0000374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 long owner;
376 unsigned long count;
377 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000378
Victor Stinnere8794522014-01-02 12:47:24 +0100379 if (!PyArg_ParseTuple(args, "(kl):_acquire_restore", &count, &owner))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
383 Py_BEGIN_ALLOW_THREADS
384 r = PyThread_acquire_lock(self->rlock_lock, 1);
385 Py_END_ALLOW_THREADS
386 }
387 if (!r) {
388 PyErr_SetString(ThreadError, "couldn't acquire lock");
389 return NULL;
390 }
391 assert(self->rlock_count == 0);
392 self->rlock_owner = owner;
393 self->rlock_count = count;
394 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000395}
396
397PyDoc_STRVAR(rlock_acquire_restore_doc,
398"_acquire_restore(state) -> None\n\
399\n\
400For internal use by `threading.Condition`.");
401
402static PyObject *
403rlock_release_save(rlockobject *self)
404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 long owner;
406 unsigned long count;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000407
Victor Stinnerc2824d42011-04-24 23:41:33 +0200408 if (self->rlock_count == 0) {
409 PyErr_SetString(PyExc_RuntimeError,
410 "cannot release un-acquired lock");
411 return NULL;
412 }
413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 owner = self->rlock_owner;
415 count = self->rlock_count;
416 self->rlock_count = 0;
417 self->rlock_owner = 0;
418 PyThread_release_lock(self->rlock_lock);
419 return Py_BuildValue("kl", count, owner);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000420}
421
422PyDoc_STRVAR(rlock_release_save_doc,
423"_release_save() -> tuple\n\
424\n\
425For internal use by `threading.Condition`.");
426
427
428static PyObject *
429rlock_is_owned(rlockobject *self)
430{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 long tid = PyThread_get_thread_ident();
432
433 if (self->rlock_count > 0 && self->rlock_owner == tid) {
434 Py_RETURN_TRUE;
435 }
436 Py_RETURN_FALSE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000437}
438
439PyDoc_STRVAR(rlock_is_owned_doc,
440"_is_owned() -> bool\n\
441\n\
442For internal use by `threading.Condition`.");
443
444static PyObject *
445rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
446{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 rlockobject *self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000448
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 self = (rlockobject *) type->tp_alloc(type, 0);
450 if (self != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 self->in_weakreflist = NULL;
452 self->rlock_owner = 0;
453 self->rlock_count = 0;
Victor Stinner357f5152013-11-05 15:10:19 +0100454
455 self->rlock_lock = PyThread_allocate_lock();
456 if (self->rlock_lock == NULL) {
457 Py_DECREF(self);
458 PyErr_SetString(ThreadError, "can't allocate lock");
459 return NULL;
460 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 return (PyObject *) self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000464}
465
466static PyObject *
467rlock_repr(rlockobject *self)
468{
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700469 return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>",
470 self->rlock_count ? "locked" : "unlocked",
471 Py_TYPE(self)->tp_name, self->rlock_owner,
472 self->rlock_count, self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000473}
474
475
476static PyMethodDef rlock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 {"acquire", (PyCFunction)rlock_acquire,
478 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
479 {"release", (PyCFunction)rlock_release,
480 METH_NOARGS, rlock_release_doc},
481 {"_is_owned", (PyCFunction)rlock_is_owned,
482 METH_NOARGS, rlock_is_owned_doc},
483 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
Victor Stinnere8794522014-01-02 12:47:24 +0100484 METH_VARARGS, rlock_acquire_restore_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 {"_release_save", (PyCFunction)rlock_release_save,
486 METH_NOARGS, rlock_release_save_doc},
487 {"__enter__", (PyCFunction)rlock_acquire,
488 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
489 {"__exit__", (PyCFunction)rlock_release,
490 METH_VARARGS, rlock_release_doc},
491 {NULL, NULL} /* sentinel */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000492};
493
494
495static PyTypeObject RLocktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 PyVarObject_HEAD_INIT(&PyType_Type, 0)
497 "_thread.RLock", /*tp_name*/
498 sizeof(rlockobject), /*tp_size*/
499 0, /*tp_itemsize*/
500 /* methods */
501 (destructor)rlock_dealloc, /*tp_dealloc*/
502 0, /*tp_print*/
503 0, /*tp_getattr*/
504 0, /*tp_setattr*/
505 0, /*tp_reserved*/
506 (reprfunc)rlock_repr, /*tp_repr*/
507 0, /*tp_as_number*/
508 0, /*tp_as_sequence*/
509 0, /*tp_as_mapping*/
510 0, /*tp_hash*/
511 0, /*tp_call*/
512 0, /*tp_str*/
513 0, /*tp_getattro*/
514 0, /*tp_setattro*/
515 0, /*tp_as_buffer*/
516 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
517 0, /*tp_doc*/
518 0, /*tp_traverse*/
519 0, /*tp_clear*/
520 0, /*tp_richcompare*/
521 offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
522 0, /*tp_iter*/
523 0, /*tp_iternext*/
524 rlock_methods, /*tp_methods*/
525 0, /* tp_members */
526 0, /* tp_getset */
527 0, /* tp_base */
528 0, /* tp_dict */
529 0, /* tp_descr_get */
530 0, /* tp_descr_set */
531 0, /* tp_dictoffset */
532 0, /* tp_init */
533 PyType_GenericAlloc, /* tp_alloc */
534 rlock_new /* tp_new */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000535};
536
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000537static lockobject *
538newlockobject(void)
539{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 lockobject *self;
541 self = PyObject_New(lockobject, &Locktype);
542 if (self == NULL)
543 return NULL;
544 self->lock_lock = PyThread_allocate_lock();
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000545 self->locked = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 self->in_weakreflist = NULL;
547 if (self->lock_lock == NULL) {
548 Py_DECREF(self);
549 PyErr_SetString(ThreadError, "can't allocate lock");
550 return NULL;
551 }
552 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000553}
554
Jim Fultond15dc062004-07-14 19:11:50 +0000555/* Thread-local objects */
556
557#include "structmember.h"
558
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000559/* Quick overview:
560
561 We need to be able to reclaim reference cycles as soon as possible
562 (both when a thread is being terminated, or a thread-local object
563 becomes unreachable from user data). Constraints:
564 - it must not be possible for thread-state dicts to be involved in
565 reference cycles (otherwise the cyclic GC will refuse to consider
566 objects referenced from a reachable thread-state dict, even though
567 local_dealloc would clear them)
568 - the death of a thread-state dict must still imply destruction of the
569 corresponding local dicts in all thread-local objects.
570
571 Our implementation uses small "localdummy" objects in order to break
572 the reference chain. These trivial objects are hashable (using the
573 default scheme of identity hashing) and weakrefable.
574 Each thread-state holds a separate localdummy for each local object
575 (as a /strong reference/),
576 and each thread-local object holds a dict mapping /weak references/
577 of localdummies to local dicts.
578
579 Therefore:
580 - only the thread-state dict holds a strong reference to the dummies
581 - only the thread-local object holds a strong reference to the local dicts
582 - only outside objects (application- or library-level) hold strong
583 references to the thread-local objects
584 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
585 dummies attached to that thread are called, and destroy the corresponding
586 local dicts from thread-local objects
587 - as soon as a thread-local object is destroyed, its local dicts are
588 destroyed and its dummies are manually removed from all thread states
589 - the GC can do its work correctly when a thread-local object is dangling,
590 without any interference from the thread-state dicts
591
592 As an additional optimization, each localdummy holds a borrowed reference
593 to the corresponding localdict. This borrowed reference is only used
594 by the thread-local object which has created the localdummy, which should
595 guarantee that the localdict still exists when accessed.
596*/
597
598typedef struct {
599 PyObject_HEAD
600 PyObject *localdict; /* Borrowed reference! */
601 PyObject *weakreflist; /* List of weak references to self */
602} localdummyobject;
603
604static void
605localdummy_dealloc(localdummyobject *self)
606{
607 if (self->weakreflist != NULL)
608 PyObject_ClearWeakRefs((PyObject *) self);
609 Py_TYPE(self)->tp_free((PyObject*)self);
610}
611
612static PyTypeObject localdummytype = {
613 PyVarObject_HEAD_INIT(NULL, 0)
614 /* tp_name */ "_thread._localdummy",
615 /* tp_basicsize */ sizeof(localdummyobject),
616 /* tp_itemsize */ 0,
617 /* tp_dealloc */ (destructor)localdummy_dealloc,
618 /* tp_print */ 0,
619 /* tp_getattr */ 0,
620 /* tp_setattr */ 0,
621 /* tp_reserved */ 0,
622 /* tp_repr */ 0,
623 /* tp_as_number */ 0,
624 /* tp_as_sequence */ 0,
625 /* tp_as_mapping */ 0,
626 /* tp_hash */ 0,
627 /* tp_call */ 0,
628 /* tp_str */ 0,
629 /* tp_getattro */ 0,
630 /* tp_setattro */ 0,
631 /* tp_as_buffer */ 0,
632 /* tp_flags */ Py_TPFLAGS_DEFAULT,
633 /* tp_doc */ "Thread-local dummy",
634 /* tp_traverse */ 0,
635 /* tp_clear */ 0,
636 /* tp_richcompare */ 0,
637 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
638};
639
640
Jim Fultond15dc062004-07-14 19:11:50 +0000641typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 PyObject_HEAD
643 PyObject *key;
644 PyObject *args;
645 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000646 PyObject *weakreflist; /* List of weak references to self */
647 /* A {localdummy weakref -> localdict} dict */
648 PyObject *dummies;
649 /* The callback for weakrefs to localdummies */
650 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000651} localobject;
652
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000653/* Forward declaration */
654static PyObject *_ldict(localobject *self);
655static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
656
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000657/* Create and register the dummy for the current thread.
658 Returns a borrowed reference of the corresponding local dict */
659static PyObject *
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000660_local_create_dummy(localobject *self)
661{
662 PyObject *tdict, *ldict = NULL, *wr = NULL;
663 localdummyobject *dummy = NULL;
664 int r;
665
666 tdict = PyThreadState_GetDict();
667 if (tdict == NULL) {
668 PyErr_SetString(PyExc_SystemError,
669 "Couldn't get thread-state dictionary");
670 goto err;
671 }
672
673 ldict = PyDict_New();
674 if (ldict == NULL)
675 goto err;
676 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
677 if (dummy == NULL)
678 goto err;
679 dummy->localdict = ldict;
680 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
681 if (wr == NULL)
682 goto err;
683
684 /* As a side-effect, this will cache the weakref's hash before the
685 dummy gets deleted */
686 r = PyDict_SetItem(self->dummies, wr, ldict);
687 if (r < 0)
688 goto err;
689 Py_CLEAR(wr);
690 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
691 if (r < 0)
692 goto err;
693 Py_CLEAR(dummy);
694
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000695 Py_DECREF(ldict);
696 return ldict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000697
698err:
699 Py_XDECREF(ldict);
700 Py_XDECREF(wr);
701 Py_XDECREF(dummy);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000702 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000703}
704
Jim Fultond15dc062004-07-14 19:11:50 +0000705static PyObject *
706local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
707{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 localobject *self;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000709 PyObject *wr;
710 static PyMethodDef wr_callback_def = {
711 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
712 };
Jim Fultond15dc062004-07-14 19:11:50 +0000713
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 if (type->tp_init == PyBaseObject_Type.tp_init
715 && ((args && PyObject_IsTrue(args))
716 || (kw && PyObject_IsTrue(kw)))) {
717 PyErr_SetString(PyExc_TypeError,
718 "Initialization arguments are not supported");
719 return NULL;
720 }
Jim Fultond15dc062004-07-14 19:11:50 +0000721
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 self = (localobject *)type->tp_alloc(type, 0);
723 if (self == NULL)
724 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000725
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 Py_XINCREF(args);
727 self->args = args;
728 Py_XINCREF(kw);
729 self->kw = kw;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 self->key = PyUnicode_FromFormat("thread.local.%p", self);
731 if (self->key == NULL)
732 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000733
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000734 self->dummies = PyDict_New();
735 if (self->dummies == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000737
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000738 /* We use a weak reference to self in the callback closure
739 in order to avoid spurious reference cycles */
740 wr = PyWeakref_NewRef((PyObject *) self, NULL);
741 if (wr == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 goto err;
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200743 self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000744 Py_DECREF(wr);
745 if (self->wr_callback == NULL)
746 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000747
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000748 if (_local_create_dummy(self) == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000749 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000751 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000752
753 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 Py_DECREF(self);
755 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000756}
757
758static int
759local_traverse(localobject *self, visitproc visit, void *arg)
760{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 Py_VISIT(self->args);
762 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000763 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000764 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000765}
766
767static int
768local_clear(localobject *self)
769{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000770 PyThreadState *tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000771 Py_CLEAR(self->args);
772 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000773 Py_CLEAR(self->dummies);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000774 Py_CLEAR(self->wr_callback);
775 /* Remove all strong references to dummies from the thread states */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 if (self->key
777 && (tstate = PyThreadState_Get())
778 && tstate->interp) {
779 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
780 tstate;
781 tstate = PyThreadState_Next(tstate))
782 if (tstate->dict &&
783 PyDict_GetItem(tstate->dict, self->key))
784 PyDict_DelItem(tstate->dict, self->key);
785 }
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
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000817 dummy = PyDict_GetItem(tdict, self->key);
818 if (dummy == NULL) {
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000819 ldict = _local_create_dummy(self);
820 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000821 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000822
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000823 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
824 Py_TYPE(self)->tp_init((PyObject*)self,
825 self->args, self->kw) < 0) {
826 /* we need to get rid of ldict from thread so
827 we create a new one the next time we do an attr
Ezio Melotti42da6632011-03-15 05:18:48 +0200828 access */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000829 PyDict_DelItem(tdict, self->key);
830 return NULL;
831 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000832 }
833 else {
834 assert(Py_TYPE(dummy) == &localdummytype);
835 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000836 }
Jim Fultond15dc062004-07-14 19:11:50 +0000837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000838 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000839}
840
Jim Fultond15dc062004-07-14 19:11:50 +0000841static int
842local_setattro(localobject *self, PyObject *name, PyObject *v)
843{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000844 PyObject *ldict;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000845 int r;
Jim Fultond15dc062004-07-14 19:11:50 +0000846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000847 ldict = _ldict(self);
848 if (ldict == NULL)
849 return -1;
850
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000851 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
852 if (r == 1) {
853 PyErr_Format(PyExc_AttributeError,
854 "'%.50s' object attribute '%U' is read-only",
855 Py_TYPE(self)->tp_name, name);
856 return -1;
857 }
858 if (r == -1)
859 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000860
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000861 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000862}
863
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000864static PyObject *local_getattro(localobject *, PyObject *);
865
Jim Fultond15dc062004-07-14 19:11:50 +0000866static PyTypeObject localtype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000867 PyVarObject_HEAD_INIT(NULL, 0)
868 /* tp_name */ "_thread._local",
869 /* tp_basicsize */ sizeof(localobject),
870 /* tp_itemsize */ 0,
871 /* tp_dealloc */ (destructor)local_dealloc,
872 /* tp_print */ 0,
873 /* tp_getattr */ 0,
874 /* tp_setattr */ 0,
875 /* tp_reserved */ 0,
876 /* tp_repr */ 0,
877 /* tp_as_number */ 0,
878 /* tp_as_sequence */ 0,
879 /* tp_as_mapping */ 0,
880 /* tp_hash */ 0,
881 /* tp_call */ 0,
882 /* tp_str */ 0,
883 /* tp_getattro */ (getattrofunc)local_getattro,
884 /* tp_setattro */ (setattrofunc)local_setattro,
885 /* tp_as_buffer */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000886 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
887 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000888 /* tp_doc */ "Thread-local data",
889 /* tp_traverse */ (traverseproc)local_traverse,
890 /* tp_clear */ (inquiry)local_clear,
891 /* tp_richcompare */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000892 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000893 /* tp_iter */ 0,
894 /* tp_iternext */ 0,
895 /* tp_methods */ 0,
896 /* tp_members */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000897 /* tp_getset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 /* tp_base */ 0,
899 /* tp_dict */ 0, /* internal use */
900 /* tp_descr_get */ 0,
901 /* tp_descr_set */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000902 /* tp_dictoffset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 /* tp_init */ 0,
904 /* tp_alloc */ 0,
905 /* tp_new */ local_new,
906 /* tp_free */ 0, /* Low-level free-mem routine */
907 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000908};
909
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000910static PyObject *
911local_getattro(localobject *self, PyObject *name)
912{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 PyObject *ldict, *value;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000914 int r;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 ldict = _ldict(self);
917 if (ldict == NULL)
918 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000919
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000920 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
921 if (r == 1) {
922 Py_INCREF(ldict);
923 return ldict;
924 }
925 if (r == -1)
926 return NULL;
927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000928 if (Py_TYPE(self) != &localtype)
929 /* use generic lookup for subtypes */
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000930 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000932 /* Optimization: just look in dict ourselves */
933 value = PyDict_GetItem(ldict, name);
934 if (value == NULL)
935 /* Fall back on generic to get __class__ and __dict__ */
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000936 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 Py_INCREF(value);
939 return value;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000940}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000941
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000942/* Called when a dummy is destroyed. */
943static PyObject *
944_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
945{
946 PyObject *obj;
947 localobject *self;
948 assert(PyWeakref_CheckRef(localweakref));
949 obj = PyWeakref_GET_OBJECT(localweakref);
950 if (obj == Py_None)
951 Py_RETURN_NONE;
952 Py_INCREF(obj);
953 assert(PyObject_TypeCheck(obj, &localtype));
954 /* If the thread-local object is still alive and not being cleared,
955 remove the corresponding local dict */
956 self = (localobject *) obj;
957 if (self->dummies != NULL) {
958 PyObject *ldict;
959 ldict = PyDict_GetItem(self->dummies, dummyweakref);
960 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000961 PyDict_DelItem(self->dummies, dummyweakref);
962 }
963 if (PyErr_Occurred())
964 PyErr_WriteUnraisable(obj);
965 }
966 Py_DECREF(obj);
967 Py_RETURN_NONE;
968}
969
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000970/* Module functions */
971
Guido van Rossuma027efa1997-05-05 20:56:21 +0000972struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 PyInterpreterState *interp;
974 PyObject *func;
975 PyObject *args;
976 PyObject *keyw;
977 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000978};
979
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000980static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000981t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000982{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 struct bootstate *boot = (struct bootstate *) boot_raw;
984 PyThreadState *tstate;
985 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 tstate = boot->tstate;
988 tstate->thread_id = PyThread_get_thread_ident();
989 _PyThreadState_Init(tstate);
990 PyEval_AcquireThread(tstate);
991 nb_threads++;
992 res = PyEval_CallObjectWithKeywords(
993 boot->func, boot->args, boot->keyw);
994 if (res == NULL) {
995 if (PyErr_ExceptionMatches(PyExc_SystemExit))
996 PyErr_Clear();
997 else {
998 PyObject *file;
Benjamin Petersone9000962012-04-02 11:15:17 -0400999 PyObject *exc, *value, *tb;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001000 PySys_WriteStderr(
1001 "Unhandled exception in thread started by ");
Benjamin Petersone9000962012-04-02 11:15:17 -04001002 PyErr_Fetch(&exc, &value, &tb);
Victor Stinnerbd303c12013-11-07 23:07:29 +01001003 file = _PySys_GetObjectId(&PyId_stderr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 if (file != NULL && file != Py_None)
1005 PyFile_WriteObject(boot->func, file, 0);
1006 else
1007 PyObject_Print(boot->func, stderr, 0);
1008 PySys_WriteStderr("\n");
Benjamin Petersone9000962012-04-02 11:15:17 -04001009 PyErr_Restore(exc, value, tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 PyErr_PrintEx(0);
1011 }
1012 }
1013 else
1014 Py_DECREF(res);
1015 Py_DECREF(boot->func);
1016 Py_DECREF(boot->args);
1017 Py_XDECREF(boot->keyw);
1018 PyMem_DEL(boot_raw);
1019 nb_threads--;
1020 PyThreadState_Clear(tstate);
1021 PyThreadState_DeleteCurrent();
1022 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001023}
1024
Barry Warsawd0c10421996-12-17 00:05:22 +00001025static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001026thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001027{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 PyObject *func, *args, *keyw = NULL;
1029 struct bootstate *boot;
1030 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
1033 &func, &args, &keyw))
1034 return NULL;
1035 if (!PyCallable_Check(func)) {
1036 PyErr_SetString(PyExc_TypeError,
1037 "first arg must be callable");
1038 return NULL;
1039 }
1040 if (!PyTuple_Check(args)) {
1041 PyErr_SetString(PyExc_TypeError,
1042 "2nd arg must be a tuple");
1043 return NULL;
1044 }
1045 if (keyw != NULL && !PyDict_Check(keyw)) {
1046 PyErr_SetString(PyExc_TypeError,
1047 "optional 3rd arg must be a dictionary");
1048 return NULL;
1049 }
1050 boot = PyMem_NEW(struct bootstate, 1);
1051 if (boot == NULL)
1052 return PyErr_NoMemory();
1053 boot->interp = PyThreadState_GET()->interp;
1054 boot->func = func;
1055 boot->args = args;
1056 boot->keyw = keyw;
1057 boot->tstate = _PyThreadState_Prealloc(boot->interp);
1058 if (boot->tstate == NULL) {
1059 PyMem_DEL(boot);
1060 return PyErr_NoMemory();
1061 }
1062 Py_INCREF(func);
1063 Py_INCREF(args);
1064 Py_XINCREF(keyw);
1065 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
1066 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
1067 if (ident == -1) {
1068 PyErr_SetString(ThreadError, "can't start new thread");
1069 Py_DECREF(func);
1070 Py_DECREF(args);
1071 Py_XDECREF(keyw);
1072 PyThreadState_Clear(boot->tstate);
1073 PyMem_DEL(boot);
1074 return NULL;
1075 }
1076 return PyLong_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001077}
1078
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001079PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001080"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001081(start_new() is an obsolete synonym)\n\
1082\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001083Start a new thread and return its identifier. The thread will call the\n\
1084function with positional arguments from the tuple args and keyword arguments\n\
1085taken from the optional dictionary kwargs. The thread exits when the\n\
1086function returns; the return value is ignored. The thread will also exit\n\
1087when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001088printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001089
Barry Warsawd0c10421996-12-17 00:05:22 +00001090static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001091thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001092{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 PyErr_SetNone(PyExc_SystemExit);
1094 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001095}
1096
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001097PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001098"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001099(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001100\n\
1101This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001102thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001103
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001104static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001105thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001106{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 PyErr_SetInterrupt();
1108 Py_INCREF(Py_None);
1109 return Py_None;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001110}
1111
1112PyDoc_STRVAR(interrupt_doc,
1113"interrupt_main()\n\
1114\n\
1115Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001116A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001117);
1118
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001119static lockobject *newlockobject(void);
1120
Barry Warsawd0c10421996-12-17 00:05:22 +00001121static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001122thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001123{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001124 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001125}
1126
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001127PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001128"allocate_lock() -> lock object\n\
1129(allocate() is an obsolete synonym)\n\
1130\n\
Alexander Belopolsky977a6842010-08-16 20:17:07 +00001131Create a new lock object. See help(LockType) for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001132
Barry Warsawd0c10421996-12-17 00:05:22 +00001133static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001134thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 long ident;
1137 ident = PyThread_get_thread_ident();
1138 if (ident == -1) {
1139 PyErr_SetString(ThreadError, "no current thread ident");
1140 return NULL;
1141 }
1142 return PyLong_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001143}
1144
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001145PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001146"get_ident() -> integer\n\
1147\n\
1148Return a non-zero integer that uniquely identifies the current thread\n\
1149amongst other threads that exist simultaneously.\n\
1150This may be used to identify per-thread resources.\n\
1151Even though on some platforms threads identities may appear to be\n\
1152allocated consecutive numbers starting at 1, this behavior should not\n\
1153be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001154A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001155
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001156static PyObject *
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001157thread__count(PyObject *self)
1158{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 return PyLong_FromLong(nb_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001160}
1161
1162PyDoc_STRVAR(_count_doc,
1163"_count() -> integer\n\
1164\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001165\
1166Return the number of currently running Python threads, excluding \n\
1167the main thread. The returned number comprises all threads created\n\
1168through `start_new_thread()` as well as `threading.Thread`, and not\n\
1169yet finished.\n\
1170\n\
1171This function is meant for internal and specialized purposes only.\n\
1172In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001173
Antoine Pitrou7b476992013-09-07 23:38:37 +02001174static void
1175release_sentinel(void *wr)
1176{
1177 /* Tricky: this function is called when the current thread state
1178 is being deleted. Therefore, only simple C code can safely
1179 execute here. */
1180 PyObject *obj = PyWeakref_GET_OBJECT(wr);
1181 lockobject *lock;
1182 if (obj != Py_None) {
1183 assert(Py_TYPE(obj) == &Locktype);
1184 lock = (lockobject *) obj;
1185 if (lock->locked) {
1186 PyThread_release_lock(lock->lock_lock);
1187 lock->locked = 0;
1188 }
1189 }
1190 /* Deallocating a weakref with a NULL callback only calls
1191 PyObject_GC_Del(), which can't call any Python code. */
1192 Py_DECREF(wr);
1193}
1194
1195static PyObject *
1196thread__set_sentinel(PyObject *self)
1197{
1198 PyObject *wr;
1199 PyThreadState *tstate = PyThreadState_Get();
1200 lockobject *lock;
1201
1202 if (tstate->on_delete_data != NULL) {
1203 /* We must support the re-creation of the lock from a
1204 fork()ed child. */
1205 assert(tstate->on_delete == &release_sentinel);
1206 wr = (PyObject *) tstate->on_delete_data;
1207 tstate->on_delete = NULL;
1208 tstate->on_delete_data = NULL;
1209 Py_DECREF(wr);
1210 }
1211 lock = newlockobject();
1212 if (lock == NULL)
1213 return NULL;
1214 /* The lock is owned by whoever called _set_sentinel(), but the weakref
1215 hangs to the thread state. */
1216 wr = PyWeakref_NewRef((PyObject *) lock, NULL);
1217 if (wr == NULL) {
1218 Py_DECREF(lock);
1219 return NULL;
1220 }
1221 tstate->on_delete_data = (void *) wr;
1222 tstate->on_delete = &release_sentinel;
1223 return (PyObject *) lock;
1224}
1225
1226PyDoc_STRVAR(_set_sentinel_doc,
1227"_set_sentinel() -> lock\n\
1228\n\
1229Set a sentinel lock that will be released when the current thread\n\
1230state is finalized (after it is untied from the interpreter).\n\
1231\n\
1232This is a private API for the threading module.");
1233
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001234static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001235thread_stack_size(PyObject *self, PyObject *args)
1236{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 size_t old_size;
1238 Py_ssize_t new_size = 0;
1239 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1242 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 if (new_size < 0) {
1245 PyErr_SetString(PyExc_ValueError,
1246 "size must be 0 or a positive value");
1247 return NULL;
1248 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 rc = PyThread_set_stacksize((size_t) new_size);
1253 if (rc == -1) {
1254 PyErr_Format(PyExc_ValueError,
1255 "size not valid: %zd bytes",
1256 new_size);
1257 return NULL;
1258 }
1259 if (rc == -2) {
1260 PyErr_SetString(ThreadError,
1261 "setting stack size not supported");
1262 return NULL;
1263 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001265 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001266}
1267
1268PyDoc_STRVAR(stack_size_doc,
1269"stack_size([size]) -> size\n\
1270\n\
1271Return the thread stack size used when creating new threads. The\n\
1272optional size argument specifies the stack size (in bytes) to be used\n\
1273for subsequently created threads, and must be 0 (use platform or\n\
1274configured default) or a positive integer value of at least 32,768 (32k).\n\
1275If changing the thread stack size is unsupported, a ThreadError\n\
1276exception is raised. If the specified size is invalid, a ValueError\n\
1277exception is raised, and the stack size is unmodified. 32k bytes\n\
1278 currently the minimum supported stack size value to guarantee\n\
1279sufficient stack space for the interpreter itself.\n\
1280\n\
1281Note that some platforms may have particular restrictions on values for\n\
1282the stack size, such as requiring a minimum stack size larger than 32kB or\n\
1283requiring allocation in multiples of the system memory page size\n\
1284- platform documentation should be referred to for more information\n\
1285(4kB pages are common; using multiples of 4096 for the stack size is\n\
1286the suggested approach in the absence of more specific information).");
1287
Barry Warsawd0c10421996-12-17 00:05:22 +00001288static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001290 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001292 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
1294 METH_NOARGS, allocate_doc},
1295 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
1296 METH_NOARGS, allocate_doc},
1297 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
1298 METH_NOARGS, exit_doc},
1299 {"exit", (PyCFunction)thread_PyThread_exit_thread,
1300 METH_NOARGS, exit_doc},
1301 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
1302 METH_NOARGS, interrupt_doc},
1303 {"get_ident", (PyCFunction)thread_get_ident,
1304 METH_NOARGS, get_ident_doc},
1305 {"_count", (PyCFunction)thread__count,
1306 METH_NOARGS, _count_doc},
1307 {"stack_size", (PyCFunction)thread_stack_size,
Victor Stinner754851f2011-04-19 23:58:51 +02001308 METH_VARARGS, stack_size_doc},
Antoine Pitrou7b476992013-09-07 23:38:37 +02001309 {"_set_sentinel", (PyCFunction)thread__set_sentinel,
1310 METH_NOARGS, _set_sentinel_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001312};
1313
1314
1315/* Initialization function */
1316
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001317PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001318"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001319The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001320
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001321PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001322"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +00001323call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001324\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001325acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1326release() -- unlock of the lock\n\
1327locked() -- test whether the lock is currently locked\n\
1328\n\
1329A lock is not owned by the thread that locked it; another thread may\n\
1330unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001331will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001332
Martin v. Löwis1a214512008-06-11 05:26:20 +00001333static struct PyModuleDef threadmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 PyModuleDef_HEAD_INIT,
1335 "_thread",
1336 thread_doc,
1337 -1,
1338 thread_methods,
1339 NULL,
1340 NULL,
1341 NULL,
1342 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001343};
1344
1345
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001346PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001347PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001348{
Victor Stinnerf5faad22015-03-28 03:52:05 +01001349 PyObject *m, *d, *v;
1350 double time_max;
1351 double timeout_max;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 /* Initialize types: */
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001354 if (PyType_Ready(&localdummytype) < 0)
1355 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 if (PyType_Ready(&localtype) < 0)
1357 return NULL;
1358 if (PyType_Ready(&Locktype) < 0)
1359 return NULL;
1360 if (PyType_Ready(&RLocktype) < 0)
1361 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001363 /* Create the module and add the functions */
1364 m = PyModule_Create(&threadmodule);
1365 if (m == NULL)
1366 return NULL;
Antoine Pitrou7c3e5772010-04-14 15:44:10 +00001367
Victor Stinnerf5faad22015-03-28 03:52:05 +01001368 timeout_max = PY_TIMEOUT_MAX / 1000000;
1369 time_max = floor(_PyTime_AsSecondsDouble(_PyTime_MAX));
1370 timeout_max = Py_MIN(timeout_max, time_max);
1371
1372 v = PyFloat_FromDouble(timeout_max);
1373 if (!v)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 return NULL;
Victor Stinnerf5faad22015-03-28 03:52:05 +01001375 if (PyModule_AddObject(m, "TIMEOUT_MAX", v) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 /* Add a symbolic constant */
1379 d = PyModule_GetDict(m);
Antoine Pitroufcf81fd2011-02-28 22:03:34 +00001380 ThreadError = PyExc_RuntimeError;
1381 Py_INCREF(ThreadError);
Victor Stinner754851f2011-04-19 23:58:51 +02001382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 PyDict_SetItemString(d, "error", ThreadError);
1384 Locktype.tp_doc = lock_doc;
1385 Py_INCREF(&Locktype);
1386 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Antoine Pitrou434736a2009-11-10 18:46:01 +00001387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 Py_INCREF(&RLocktype);
1389 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1390 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 Py_INCREF(&localtype);
1393 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1394 return NULL;
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 nb_threads = 0;
1397
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +00001398 str_dict = PyUnicode_InternFromString("__dict__");
1399 if (str_dict == NULL)
1400 return NULL;
1401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 /* Initialize the C thread library */
1403 PyThread_init_thread();
1404 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001405}