blob: cb349b63a3e652b2e3ada9475124a67c14fae47a [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
20/* Lock objects */
21
22typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000023 PyObject_HEAD
24 PyThread_type_lock lock_lock;
25 PyObject *in_weakreflist;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000026} lockobject;
27
Guido van Rossum1984f1e1992-08-04 12:41:02 +000028static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000029lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000030{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000031 if (self->in_weakreflist != NULL)
32 PyObject_ClearWeakRefs((PyObject *) self);
33 if (self->lock_lock != NULL) {
34 /* Unlock the lock so it's safe to free it */
35 PyThread_acquire_lock(self->lock_lock, 0);
36 PyThread_release_lock(self->lock_lock);
37
38 PyThread_free_lock(self->lock_lock);
39 }
40 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000041}
42
Barry Warsawd0c10421996-12-17 00:05:22 +000043static PyObject *
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000044lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000045{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000046 char *kwlist[] = {"blocking", "timeout", NULL};
47 int blocking = 1;
48 double timeout = -1;
49 PY_TIMEOUT_T microseconds;
50 int r;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000051
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist,
53 &blocking, &timeout))
54 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000056 if (!blocking && timeout != -1) {
57 PyErr_SetString(PyExc_ValueError, "can't specify a timeout "
58 "for a non-blocking call");
59 return NULL;
60 }
61 if (timeout < 0 && timeout != -1) {
62 PyErr_SetString(PyExc_ValueError, "timeout value must be "
63 "strictly positive");
64 return NULL;
65 }
66 if (!blocking)
67 microseconds = 0;
68 else if (timeout == -1)
69 microseconds = -1;
70 else {
71 timeout *= 1e6;
72 if (timeout >= (double) PY_TIMEOUT_MAX) {
73 PyErr_SetString(PyExc_OverflowError,
74 "timeout value is too large");
75 return NULL;
76 }
77 microseconds = (PY_TIMEOUT_T) timeout;
78 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +000079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080 Py_BEGIN_ALLOW_THREADS
81 r = PyThread_acquire_lock_timed(self->lock_lock, microseconds);
82 Py_END_ALLOW_THREADS
83
84 return PyBool_FromLong(r);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000085}
86
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000087PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000088"acquire([wait]) -> None or bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000089(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000090\n\
91Lock the lock. Without argument, this blocks if the lock is already\n\
92locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000093the lock, and return None once the lock is acquired.\n\
94With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000095and the return value reflects whether the lock is acquired.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000096The blocking operation is not interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000097
Barry Warsawd0c10421996-12-17 00:05:22 +000098static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000099lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000100{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000101 /* Sanity check: the lock must be locked */
102 if (PyThread_acquire_lock(self->lock_lock, 0)) {
103 PyThread_release_lock(self->lock_lock);
104 PyErr_SetString(ThreadError, "release unlocked lock");
105 return NULL;
106 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000108 PyThread_release_lock(self->lock_lock);
109 Py_INCREF(Py_None);
110 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000111}
112
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000113PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000114"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000115(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000116\n\
117Release the lock, allowing another thread that is blocked waiting for\n\
118the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000119but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000120
Barry Warsawd0c10421996-12-17 00:05:22 +0000121static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000122lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000123{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 if (PyThread_acquire_lock(self->lock_lock, 0)) {
125 PyThread_release_lock(self->lock_lock);
126 return PyBool_FromLong(0L);
127 }
128 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000129}
130
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000131PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000132"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000133(locked_lock() is an obsolete synonym)\n\
134\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000135Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000136
Barry Warsawd0c10421996-12-17 00:05:22 +0000137static PyMethodDef lock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000138 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
139 METH_VARARGS | METH_KEYWORDS, acquire_doc},
140 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
141 METH_VARARGS | METH_KEYWORDS, acquire_doc},
142 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
143 METH_NOARGS, release_doc},
144 {"release", (PyCFunction)lock_PyThread_release_lock,
145 METH_NOARGS, release_doc},
146 {"locked_lock", (PyCFunction)lock_locked_lock,
147 METH_NOARGS, locked_doc},
148 {"locked", (PyCFunction)lock_locked_lock,
149 METH_NOARGS, locked_doc},
150 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
151 METH_VARARGS | METH_KEYWORDS, acquire_doc},
152 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
153 METH_VARARGS, release_doc},
154 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000155};
156
Barry Warsawd0c10421996-12-17 00:05:22 +0000157static PyTypeObject Locktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 PyVarObject_HEAD_INIT(&PyType_Type, 0)
159 "_thread.lock", /*tp_name*/
160 sizeof(lockobject), /*tp_size*/
161 0, /*tp_itemsize*/
162 /* methods */
163 (destructor)lock_dealloc, /*tp_dealloc*/
164 0, /*tp_print*/
165 0, /*tp_getattr*/
166 0, /*tp_setattr*/
167 0, /*tp_reserved*/
168 0, /*tp_repr*/
169 0, /*tp_as_number*/
170 0, /*tp_as_sequence*/
171 0, /*tp_as_mapping*/
172 0, /*tp_hash*/
173 0, /*tp_call*/
174 0, /*tp_str*/
175 0, /*tp_getattro*/
176 0, /*tp_setattro*/
177 0, /*tp_as_buffer*/
178 Py_TPFLAGS_DEFAULT, /*tp_flags*/
179 0, /*tp_doc*/
180 0, /*tp_traverse*/
181 0, /*tp_clear*/
182 0, /*tp_richcompare*/
183 offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
184 0, /*tp_iter*/
185 0, /*tp_iternext*/
186 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000187};
188
Antoine Pitrou434736a2009-11-10 18:46:01 +0000189/* Recursive lock objects */
190
191typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 PyObject_HEAD
193 PyThread_type_lock rlock_lock;
194 long rlock_owner;
195 unsigned long rlock_count;
196 PyObject *in_weakreflist;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000197} rlockobject;
198
199static void
200rlock_dealloc(rlockobject *self)
201{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000202 assert(self->rlock_lock);
203 if (self->in_weakreflist != NULL)
204 PyObject_ClearWeakRefs((PyObject *) self);
205 /* Unlock the lock so it's safe to free it */
206 if (self->rlock_count > 0)
207 PyThread_release_lock(self->rlock_lock);
208
209 PyThread_free_lock(self->rlock_lock);
210 Py_TYPE(self)->tp_free(self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000211}
212
213static PyObject *
214rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
215{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000216 char *kwlist[] = {"blocking", "timeout", NULL};
217 int blocking = 1;
218 double timeout = -1;
219 PY_TIMEOUT_T microseconds;
220 long tid;
221 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000223 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist,
224 &blocking, &timeout))
225 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 if (!blocking && timeout != -1) {
228 PyErr_SetString(PyExc_ValueError, "can't specify a timeout "
229 "for a non-blocking call");
230 return NULL;
231 }
232 if (timeout < 0 && timeout != -1) {
233 PyErr_SetString(PyExc_ValueError, "timeout value must be "
234 "strictly positive");
235 return NULL;
236 }
237 if (!blocking)
238 microseconds = 0;
239 else if (timeout == -1)
240 microseconds = -1;
241 else {
242 timeout *= 1e6;
243 if (timeout >= (double) PY_TIMEOUT_MAX) {
244 PyErr_SetString(PyExc_OverflowError,
245 "timeout value is too large");
246 return NULL;
247 }
248 microseconds = (PY_TIMEOUT_T) timeout;
249 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 tid = PyThread_get_thread_ident();
252 if (self->rlock_count > 0 && tid == self->rlock_owner) {
253 unsigned long count = self->rlock_count + 1;
254 if (count <= self->rlock_count) {
255 PyErr_SetString(PyExc_OverflowError,
256 "Internal lock count overflowed");
257 return NULL;
258 }
259 self->rlock_count = count;
260 Py_RETURN_TRUE;
261 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 if (self->rlock_count > 0 ||
264 !PyThread_acquire_lock(self->rlock_lock, 0)) {
265 if (microseconds == 0) {
266 Py_RETURN_FALSE;
267 }
268 Py_BEGIN_ALLOW_THREADS
269 r = PyThread_acquire_lock_timed(self->rlock_lock, microseconds);
270 Py_END_ALLOW_THREADS
271 }
272 if (r) {
273 assert(self->rlock_count == 0);
274 self->rlock_owner = tid;
275 self->rlock_count = 1;
276 }
277
278 return PyBool_FromLong(r);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000279}
280
281PyDoc_STRVAR(rlock_acquire_doc,
282"acquire(blocking=True) -> bool\n\
283\n\
284Lock the lock. `blocking` indicates whether we should wait\n\
285for the lock to be available or not. If `blocking` is False\n\
286and another thread holds the lock, the method will return False\n\
287immediately. If `blocking` is True and another thread holds\n\
288the lock, the method will wait for the lock to be released,\n\
289take it and then return True.\n\
290(note: the blocking operation is not interruptible.)\n\
291\n\
292In all other cases, the method will return True immediately.\n\
293Precisely, if the current thread already holds the lock, its\n\
294internal counter is simply incremented. If nobody holds the lock,\n\
295the lock is taken and its internal counter initialized to 1.");
296
297static PyObject *
298rlock_release(rlockobject *self)
299{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 long tid = PyThread_get_thread_ident();
Antoine Pitrou434736a2009-11-10 18:46:01 +0000301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 if (self->rlock_count == 0 || self->rlock_owner != tid) {
303 PyErr_SetString(PyExc_RuntimeError,
304 "cannot release un-acquired lock");
305 return NULL;
306 }
307 if (--self->rlock_count == 0) {
308 self->rlock_owner = 0;
309 PyThread_release_lock(self->rlock_lock);
310 }
311 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000312}
313
314PyDoc_STRVAR(rlock_release_doc,
315"release()\n\
316\n\
317Release the lock, allowing another thread that is blocked waiting for\n\
318the lock to acquire the lock. The lock must be in the locked state,\n\
319and must be locked by the same thread that unlocks it; otherwise a\n\
320`RuntimeError` is raised.\n\
321\n\
322Do note that if the lock was acquire()d several times in a row by the\n\
323current thread, release() needs to be called as many times for the lock\n\
324to be available for other threads.");
325
326static PyObject *
327rlock_acquire_restore(rlockobject *self, PyObject *arg)
328{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 long owner;
330 unsigned long count;
331 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000333 if (!PyArg_ParseTuple(arg, "kl:_acquire_restore", &count, &owner))
334 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
337 Py_BEGIN_ALLOW_THREADS
338 r = PyThread_acquire_lock(self->rlock_lock, 1);
339 Py_END_ALLOW_THREADS
340 }
341 if (!r) {
342 PyErr_SetString(ThreadError, "couldn't acquire lock");
343 return NULL;
344 }
345 assert(self->rlock_count == 0);
346 self->rlock_owner = owner;
347 self->rlock_count = count;
348 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000349}
350
351PyDoc_STRVAR(rlock_acquire_restore_doc,
352"_acquire_restore(state) -> None\n\
353\n\
354For internal use by `threading.Condition`.");
355
356static PyObject *
357rlock_release_save(rlockobject *self)
358{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 long owner;
360 unsigned long count;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 owner = self->rlock_owner;
363 count = self->rlock_count;
364 self->rlock_count = 0;
365 self->rlock_owner = 0;
366 PyThread_release_lock(self->rlock_lock);
367 return Py_BuildValue("kl", count, owner);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000368}
369
370PyDoc_STRVAR(rlock_release_save_doc,
371"_release_save() -> tuple\n\
372\n\
373For internal use by `threading.Condition`.");
374
375
376static PyObject *
377rlock_is_owned(rlockobject *self)
378{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 long tid = PyThread_get_thread_ident();
380
381 if (self->rlock_count > 0 && self->rlock_owner == tid) {
382 Py_RETURN_TRUE;
383 }
384 Py_RETURN_FALSE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000385}
386
387PyDoc_STRVAR(rlock_is_owned_doc,
388"_is_owned() -> bool\n\
389\n\
390For internal use by `threading.Condition`.");
391
392static PyObject *
393rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
394{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 rlockobject *self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 self = (rlockobject *) type->tp_alloc(type, 0);
398 if (self != NULL) {
399 self->rlock_lock = PyThread_allocate_lock();
400 if (self->rlock_lock == NULL) {
401 type->tp_free(self);
402 PyErr_SetString(ThreadError, "can't allocate lock");
403 return NULL;
404 }
405 self->in_weakreflist = NULL;
406 self->rlock_owner = 0;
407 self->rlock_count = 0;
408 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 return (PyObject *) self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000411}
412
413static PyObject *
414rlock_repr(rlockobject *self)
415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 return PyUnicode_FromFormat("<%s owner=%ld count=%lu>",
417 Py_TYPE(self)->tp_name, self->rlock_owner, self->rlock_count);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000418}
419
420
421static PyMethodDef rlock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 {"acquire", (PyCFunction)rlock_acquire,
423 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
424 {"release", (PyCFunction)rlock_release,
425 METH_NOARGS, rlock_release_doc},
426 {"_is_owned", (PyCFunction)rlock_is_owned,
427 METH_NOARGS, rlock_is_owned_doc},
428 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
429 METH_O, rlock_acquire_restore_doc},
430 {"_release_save", (PyCFunction)rlock_release_save,
431 METH_NOARGS, rlock_release_save_doc},
432 {"__enter__", (PyCFunction)rlock_acquire,
433 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
434 {"__exit__", (PyCFunction)rlock_release,
435 METH_VARARGS, rlock_release_doc},
436 {NULL, NULL} /* sentinel */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000437};
438
439
440static PyTypeObject RLocktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 PyVarObject_HEAD_INIT(&PyType_Type, 0)
442 "_thread.RLock", /*tp_name*/
443 sizeof(rlockobject), /*tp_size*/
444 0, /*tp_itemsize*/
445 /* methods */
446 (destructor)rlock_dealloc, /*tp_dealloc*/
447 0, /*tp_print*/
448 0, /*tp_getattr*/
449 0, /*tp_setattr*/
450 0, /*tp_reserved*/
451 (reprfunc)rlock_repr, /*tp_repr*/
452 0, /*tp_as_number*/
453 0, /*tp_as_sequence*/
454 0, /*tp_as_mapping*/
455 0, /*tp_hash*/
456 0, /*tp_call*/
457 0, /*tp_str*/
458 0, /*tp_getattro*/
459 0, /*tp_setattro*/
460 0, /*tp_as_buffer*/
461 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
462 0, /*tp_doc*/
463 0, /*tp_traverse*/
464 0, /*tp_clear*/
465 0, /*tp_richcompare*/
466 offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
467 0, /*tp_iter*/
468 0, /*tp_iternext*/
469 rlock_methods, /*tp_methods*/
470 0, /* tp_members */
471 0, /* tp_getset */
472 0, /* tp_base */
473 0, /* tp_dict */
474 0, /* tp_descr_get */
475 0, /* tp_descr_set */
476 0, /* tp_dictoffset */
477 0, /* tp_init */
478 PyType_GenericAlloc, /* tp_alloc */
479 rlock_new /* tp_new */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000480};
481
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000482static lockobject *
483newlockobject(void)
484{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 lockobject *self;
486 self = PyObject_New(lockobject, &Locktype);
487 if (self == NULL)
488 return NULL;
489 self->lock_lock = PyThread_allocate_lock();
490 self->in_weakreflist = NULL;
491 if (self->lock_lock == NULL) {
492 Py_DECREF(self);
493 PyErr_SetString(ThreadError, "can't allocate lock");
494 return NULL;
495 }
496 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000497}
498
Jim Fultond15dc062004-07-14 19:11:50 +0000499/* Thread-local objects */
500
501#include "structmember.h"
502
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000503/* Quick overview:
504
505 We need to be able to reclaim reference cycles as soon as possible
506 (both when a thread is being terminated, or a thread-local object
507 becomes unreachable from user data). Constraints:
508 - it must not be possible for thread-state dicts to be involved in
509 reference cycles (otherwise the cyclic GC will refuse to consider
510 objects referenced from a reachable thread-state dict, even though
511 local_dealloc would clear them)
512 - the death of a thread-state dict must still imply destruction of the
513 corresponding local dicts in all thread-local objects.
514
515 Our implementation uses small "localdummy" objects in order to break
516 the reference chain. These trivial objects are hashable (using the
517 default scheme of identity hashing) and weakrefable.
518 Each thread-state holds a separate localdummy for each local object
519 (as a /strong reference/),
520 and each thread-local object holds a dict mapping /weak references/
521 of localdummies to local dicts.
522
523 Therefore:
524 - only the thread-state dict holds a strong reference to the dummies
525 - only the thread-local object holds a strong reference to the local dicts
526 - only outside objects (application- or library-level) hold strong
527 references to the thread-local objects
528 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
529 dummies attached to that thread are called, and destroy the corresponding
530 local dicts from thread-local objects
531 - as soon as a thread-local object is destroyed, its local dicts are
532 destroyed and its dummies are manually removed from all thread states
533 - the GC can do its work correctly when a thread-local object is dangling,
534 without any interference from the thread-state dicts
535
536 As an additional optimization, each localdummy holds a borrowed reference
537 to the corresponding localdict. This borrowed reference is only used
538 by the thread-local object which has created the localdummy, which should
539 guarantee that the localdict still exists when accessed.
540*/
541
542typedef struct {
543 PyObject_HEAD
544 PyObject *localdict; /* Borrowed reference! */
545 PyObject *weakreflist; /* List of weak references to self */
546} localdummyobject;
547
548static void
549localdummy_dealloc(localdummyobject *self)
550{
551 if (self->weakreflist != NULL)
552 PyObject_ClearWeakRefs((PyObject *) self);
553 Py_TYPE(self)->tp_free((PyObject*)self);
554}
555
556static PyTypeObject localdummytype = {
557 PyVarObject_HEAD_INIT(NULL, 0)
558 /* tp_name */ "_thread._localdummy",
559 /* tp_basicsize */ sizeof(localdummyobject),
560 /* tp_itemsize */ 0,
561 /* tp_dealloc */ (destructor)localdummy_dealloc,
562 /* tp_print */ 0,
563 /* tp_getattr */ 0,
564 /* tp_setattr */ 0,
565 /* tp_reserved */ 0,
566 /* tp_repr */ 0,
567 /* tp_as_number */ 0,
568 /* tp_as_sequence */ 0,
569 /* tp_as_mapping */ 0,
570 /* tp_hash */ 0,
571 /* tp_call */ 0,
572 /* tp_str */ 0,
573 /* tp_getattro */ 0,
574 /* tp_setattro */ 0,
575 /* tp_as_buffer */ 0,
576 /* tp_flags */ Py_TPFLAGS_DEFAULT,
577 /* tp_doc */ "Thread-local dummy",
578 /* tp_traverse */ 0,
579 /* tp_clear */ 0,
580 /* tp_richcompare */ 0,
581 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
582};
583
584
Jim Fultond15dc062004-07-14 19:11:50 +0000585typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 PyObject_HEAD
587 PyObject *key;
588 PyObject *args;
589 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000590 PyObject *weakreflist; /* List of weak references to self */
591 /* A {localdummy weakref -> localdict} dict */
592 PyObject *dummies;
593 /* The callback for weakrefs to localdummies */
594 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000595} localobject;
596
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000597/* Forward declaration */
598static PyObject *_ldict(localobject *self);
599static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
600
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000601/* Create and register the dummy for the current thread.
602 Returns a borrowed reference of the corresponding local dict */
603static PyObject *
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000604_local_create_dummy(localobject *self)
605{
606 PyObject *tdict, *ldict = NULL, *wr = NULL;
607 localdummyobject *dummy = NULL;
608 int r;
609
610 tdict = PyThreadState_GetDict();
611 if (tdict == NULL) {
612 PyErr_SetString(PyExc_SystemError,
613 "Couldn't get thread-state dictionary");
614 goto err;
615 }
616
617 ldict = PyDict_New();
618 if (ldict == NULL)
619 goto err;
620 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
621 if (dummy == NULL)
622 goto err;
623 dummy->localdict = ldict;
624 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
625 if (wr == NULL)
626 goto err;
627
628 /* As a side-effect, this will cache the weakref's hash before the
629 dummy gets deleted */
630 r = PyDict_SetItem(self->dummies, wr, ldict);
631 if (r < 0)
632 goto err;
633 Py_CLEAR(wr);
634 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
635 if (r < 0)
636 goto err;
637 Py_CLEAR(dummy);
638
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000639 Py_DECREF(ldict);
640 return ldict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000641
642err:
643 Py_XDECREF(ldict);
644 Py_XDECREF(wr);
645 Py_XDECREF(dummy);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000646 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000647}
648
Jim Fultond15dc062004-07-14 19:11:50 +0000649static PyObject *
650local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
651{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 localobject *self;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000653 PyObject *wr;
654 static PyMethodDef wr_callback_def = {
655 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
656 };
Jim Fultond15dc062004-07-14 19:11:50 +0000657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 if (type->tp_init == PyBaseObject_Type.tp_init
659 && ((args && PyObject_IsTrue(args))
660 || (kw && PyObject_IsTrue(kw)))) {
661 PyErr_SetString(PyExc_TypeError,
662 "Initialization arguments are not supported");
663 return NULL;
664 }
Jim Fultond15dc062004-07-14 19:11:50 +0000665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000666 self = (localobject *)type->tp_alloc(type, 0);
667 if (self == NULL)
668 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670 Py_XINCREF(args);
671 self->args = args;
672 Py_XINCREF(kw);
673 self->kw = kw;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 self->key = PyUnicode_FromFormat("thread.local.%p", self);
675 if (self->key == NULL)
676 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000677
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000678 self->dummies = PyDict_New();
679 if (self->dummies == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000681
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000682 /* We use a weak reference to self in the callback closure
683 in order to avoid spurious reference cycles */
684 wr = PyWeakref_NewRef((PyObject *) self, NULL);
685 if (wr == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000686 goto err;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000687 self->wr_callback = PyCFunction_New(&wr_callback_def, wr);
688 Py_DECREF(wr);
689 if (self->wr_callback == NULL)
690 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000691
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000692 if (_local_create_dummy(self) == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000693 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000694
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000696
697 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000698 Py_DECREF(self);
699 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000700}
701
702static int
703local_traverse(localobject *self, visitproc visit, void *arg)
704{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705 Py_VISIT(self->args);
706 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000707 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000709}
710
711static int
712local_clear(localobject *self)
713{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000714 PyThreadState *tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 Py_CLEAR(self->args);
716 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000717 Py_CLEAR(self->dummies);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000718 Py_CLEAR(self->wr_callback);
719 /* Remove all strong references to dummies from the thread states */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 if (self->key
721 && (tstate = PyThreadState_Get())
722 && tstate->interp) {
723 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
724 tstate;
725 tstate = PyThreadState_Next(tstate))
726 if (tstate->dict &&
727 PyDict_GetItem(tstate->dict, self->key))
728 PyDict_DelItem(tstate->dict, self->key);
729 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000730 return 0;
731}
Jim Fultond15dc062004-07-14 19:11:50 +0000732
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000733static void
734local_dealloc(localobject *self)
735{
736 /* Weakrefs must be invalidated right now, otherwise they can be used
737 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
738 if (self->weakreflist != NULL)
739 PyObject_ClearWeakRefs((PyObject *) self);
740
741 PyObject_GC_UnTrack(self);
742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000744 Py_XDECREF(self->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000746}
747
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000748/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000749static PyObject *
750_ldict(localobject *self)
751{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000752 PyObject *tdict, *ldict, *dummy;
Jim Fultond15dc062004-07-14 19:11:50 +0000753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 tdict = PyThreadState_GetDict();
755 if (tdict == NULL) {
756 PyErr_SetString(PyExc_SystemError,
757 "Couldn't get thread-state dictionary");
758 return NULL;
759 }
Jim Fultond15dc062004-07-14 19:11:50 +0000760
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000761 dummy = PyDict_GetItem(tdict, self->key);
762 if (dummy == NULL) {
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000763 ldict = _local_create_dummy(self);
764 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000766
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000767 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
768 Py_TYPE(self)->tp_init((PyObject*)self,
769 self->args, self->kw) < 0) {
770 /* we need to get rid of ldict from thread so
771 we create a new one the next time we do an attr
772 acces */
773 PyDict_DelItem(tdict, self->key);
774 return NULL;
775 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000776 }
777 else {
778 assert(Py_TYPE(dummy) == &localdummytype);
779 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000780 }
Jim Fultond15dc062004-07-14 19:11:50 +0000781
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000782 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000783}
784
Jim Fultond15dc062004-07-14 19:11:50 +0000785static int
786local_setattro(localobject *self, PyObject *name, PyObject *v)
787{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000788 PyObject *ldict;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000789 int r;
Jim Fultond15dc062004-07-14 19:11:50 +0000790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000791 ldict = _ldict(self);
792 if (ldict == NULL)
793 return -1;
794
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000795 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
796 if (r == 1) {
797 PyErr_Format(PyExc_AttributeError,
798 "'%.50s' object attribute '%U' is read-only",
799 Py_TYPE(self)->tp_name, name);
800 return -1;
801 }
802 if (r == -1)
803 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000804
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000805 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000806}
807
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000808static PyObject *local_getattro(localobject *, PyObject *);
809
Jim Fultond15dc062004-07-14 19:11:50 +0000810static PyTypeObject localtype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000811 PyVarObject_HEAD_INIT(NULL, 0)
812 /* tp_name */ "_thread._local",
813 /* tp_basicsize */ sizeof(localobject),
814 /* tp_itemsize */ 0,
815 /* tp_dealloc */ (destructor)local_dealloc,
816 /* tp_print */ 0,
817 /* tp_getattr */ 0,
818 /* tp_setattr */ 0,
819 /* tp_reserved */ 0,
820 /* tp_repr */ 0,
821 /* tp_as_number */ 0,
822 /* tp_as_sequence */ 0,
823 /* tp_as_mapping */ 0,
824 /* tp_hash */ 0,
825 /* tp_call */ 0,
826 /* tp_str */ 0,
827 /* tp_getattro */ (getattrofunc)local_getattro,
828 /* tp_setattro */ (setattrofunc)local_setattro,
829 /* tp_as_buffer */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000830 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
831 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000832 /* tp_doc */ "Thread-local data",
833 /* tp_traverse */ (traverseproc)local_traverse,
834 /* tp_clear */ (inquiry)local_clear,
835 /* tp_richcompare */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000836 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000837 /* tp_iter */ 0,
838 /* tp_iternext */ 0,
839 /* tp_methods */ 0,
840 /* tp_members */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000841 /* tp_getset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 /* tp_base */ 0,
843 /* tp_dict */ 0, /* internal use */
844 /* tp_descr_get */ 0,
845 /* tp_descr_set */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000846 /* tp_dictoffset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000847 /* tp_init */ 0,
848 /* tp_alloc */ 0,
849 /* tp_new */ local_new,
850 /* tp_free */ 0, /* Low-level free-mem routine */
851 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000852};
853
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000854static PyObject *
855local_getattro(localobject *self, PyObject *name)
856{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 PyObject *ldict, *value;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000858 int r;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 ldict = _ldict(self);
861 if (ldict == NULL)
862 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000863
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000864 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
865 if (r == 1) {
866 Py_INCREF(ldict);
867 return ldict;
868 }
869 if (r == -1)
870 return NULL;
871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000872 if (Py_TYPE(self) != &localtype)
873 /* use generic lookup for subtypes */
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000874 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 /* Optimization: just look in dict ourselves */
877 value = PyDict_GetItem(ldict, name);
878 if (value == NULL)
879 /* Fall back on generic to get __class__ and __dict__ */
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000880 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000882 Py_INCREF(value);
883 return value;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000884}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000885
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000886/* Called when a dummy is destroyed. */
887static PyObject *
888_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
889{
890 PyObject *obj;
891 localobject *self;
892 assert(PyWeakref_CheckRef(localweakref));
893 obj = PyWeakref_GET_OBJECT(localweakref);
894 if (obj == Py_None)
895 Py_RETURN_NONE;
896 Py_INCREF(obj);
897 assert(PyObject_TypeCheck(obj, &localtype));
898 /* If the thread-local object is still alive and not being cleared,
899 remove the corresponding local dict */
900 self = (localobject *) obj;
901 if (self->dummies != NULL) {
902 PyObject *ldict;
903 ldict = PyDict_GetItem(self->dummies, dummyweakref);
904 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000905 PyDict_DelItem(self->dummies, dummyweakref);
906 }
907 if (PyErr_Occurred())
908 PyErr_WriteUnraisable(obj);
909 }
910 Py_DECREF(obj);
911 Py_RETURN_NONE;
912}
913
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000914/* Module functions */
915
Guido van Rossuma027efa1997-05-05 20:56:21 +0000916struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000917 PyInterpreterState *interp;
918 PyObject *func;
919 PyObject *args;
920 PyObject *keyw;
921 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000922};
923
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000924static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000925t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000926{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 struct bootstate *boot = (struct bootstate *) boot_raw;
928 PyThreadState *tstate;
929 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000931 tstate = boot->tstate;
932 tstate->thread_id = PyThread_get_thread_ident();
933 _PyThreadState_Init(tstate);
934 PyEval_AcquireThread(tstate);
935 nb_threads++;
936 res = PyEval_CallObjectWithKeywords(
937 boot->func, boot->args, boot->keyw);
938 if (res == NULL) {
939 if (PyErr_ExceptionMatches(PyExc_SystemExit))
940 PyErr_Clear();
941 else {
942 PyObject *file;
943 PySys_WriteStderr(
944 "Unhandled exception in thread started by ");
945 file = PySys_GetObject("stderr");
946 if (file != NULL && file != Py_None)
947 PyFile_WriteObject(boot->func, file, 0);
948 else
949 PyObject_Print(boot->func, stderr, 0);
950 PySys_WriteStderr("\n");
951 PyErr_PrintEx(0);
952 }
953 }
954 else
955 Py_DECREF(res);
956 Py_DECREF(boot->func);
957 Py_DECREF(boot->args);
958 Py_XDECREF(boot->keyw);
959 PyMem_DEL(boot_raw);
960 nb_threads--;
961 PyThreadState_Clear(tstate);
962 PyThreadState_DeleteCurrent();
963 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000964}
965
Barry Warsawd0c10421996-12-17 00:05:22 +0000966static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000967thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000968{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 PyObject *func, *args, *keyw = NULL;
970 struct bootstate *boot;
971 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
974 &func, &args, &keyw))
975 return NULL;
976 if (!PyCallable_Check(func)) {
977 PyErr_SetString(PyExc_TypeError,
978 "first arg must be callable");
979 return NULL;
980 }
981 if (!PyTuple_Check(args)) {
982 PyErr_SetString(PyExc_TypeError,
983 "2nd arg must be a tuple");
984 return NULL;
985 }
986 if (keyw != NULL && !PyDict_Check(keyw)) {
987 PyErr_SetString(PyExc_TypeError,
988 "optional 3rd arg must be a dictionary");
989 return NULL;
990 }
991 boot = PyMem_NEW(struct bootstate, 1);
992 if (boot == NULL)
993 return PyErr_NoMemory();
994 boot->interp = PyThreadState_GET()->interp;
995 boot->func = func;
996 boot->args = args;
997 boot->keyw = keyw;
998 boot->tstate = _PyThreadState_Prealloc(boot->interp);
999 if (boot->tstate == NULL) {
1000 PyMem_DEL(boot);
1001 return PyErr_NoMemory();
1002 }
1003 Py_INCREF(func);
1004 Py_INCREF(args);
1005 Py_XINCREF(keyw);
1006 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
1007 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
1008 if (ident == -1) {
1009 PyErr_SetString(ThreadError, "can't start new thread");
1010 Py_DECREF(func);
1011 Py_DECREF(args);
1012 Py_XDECREF(keyw);
1013 PyThreadState_Clear(boot->tstate);
1014 PyMem_DEL(boot);
1015 return NULL;
1016 }
1017 return PyLong_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001018}
1019
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001020PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001021"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001022(start_new() is an obsolete synonym)\n\
1023\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001024Start a new thread and return its identifier. The thread will call the\n\
1025function with positional arguments from the tuple args and keyword arguments\n\
1026taken from the optional dictionary kwargs. The thread exits when the\n\
1027function returns; the return value is ignored. The thread will also exit\n\
1028when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001029printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001030
Barry Warsawd0c10421996-12-17 00:05:22 +00001031static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001032thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 PyErr_SetNone(PyExc_SystemExit);
1035 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001036}
1037
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001038PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001039"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +00001040(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001041\n\
1042This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001043thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001044
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001045static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001046thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001047{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 PyErr_SetInterrupt();
1049 Py_INCREF(Py_None);
1050 return Py_None;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001051}
1052
1053PyDoc_STRVAR(interrupt_doc,
1054"interrupt_main()\n\
1055\n\
1056Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001057A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001058);
1059
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001060static lockobject *newlockobject(void);
1061
Barry Warsawd0c10421996-12-17 00:05:22 +00001062static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001063thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001066}
1067
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001068PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001069"allocate_lock() -> lock object\n\
1070(allocate() is an obsolete synonym)\n\
1071\n\
Alexander Belopolsky977a6842010-08-16 20:17:07 +00001072Create a new lock object. See help(LockType) for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001073
Barry Warsawd0c10421996-12-17 00:05:22 +00001074static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001075thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 long ident;
1078 ident = PyThread_get_thread_ident();
1079 if (ident == -1) {
1080 PyErr_SetString(ThreadError, "no current thread ident");
1081 return NULL;
1082 }
1083 return PyLong_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001084}
1085
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001086PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001087"get_ident() -> integer\n\
1088\n\
1089Return a non-zero integer that uniquely identifies the current thread\n\
1090amongst other threads that exist simultaneously.\n\
1091This may be used to identify per-thread resources.\n\
1092Even though on some platforms threads identities may appear to be\n\
1093allocated consecutive numbers starting at 1, this behavior should not\n\
1094be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001095A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001096
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001097static PyObject *
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001098thread__count(PyObject *self)
1099{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 return PyLong_FromLong(nb_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001101}
1102
1103PyDoc_STRVAR(_count_doc,
1104"_count() -> integer\n\
1105\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001106\
1107Return the number of currently running Python threads, excluding \n\
1108the main thread. The returned number comprises all threads created\n\
1109through `start_new_thread()` as well as `threading.Thread`, and not\n\
1110yet finished.\n\
1111\n\
1112This function is meant for internal and specialized purposes only.\n\
1113In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001114
1115static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001116thread_stack_size(PyObject *self, PyObject *args)
1117{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 size_t old_size;
1119 Py_ssize_t new_size = 0;
1120 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1123 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 if (new_size < 0) {
1126 PyErr_SetString(PyExc_ValueError,
1127 "size must be 0 or a positive value");
1128 return NULL;
1129 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001133 rc = PyThread_set_stacksize((size_t) new_size);
1134 if (rc == -1) {
1135 PyErr_Format(PyExc_ValueError,
1136 "size not valid: %zd bytes",
1137 new_size);
1138 return NULL;
1139 }
1140 if (rc == -2) {
1141 PyErr_SetString(ThreadError,
1142 "setting stack size not supported");
1143 return NULL;
1144 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001147}
1148
1149PyDoc_STRVAR(stack_size_doc,
1150"stack_size([size]) -> size\n\
1151\n\
1152Return the thread stack size used when creating new threads. The\n\
1153optional size argument specifies the stack size (in bytes) to be used\n\
1154for subsequently created threads, and must be 0 (use platform or\n\
1155configured default) or a positive integer value of at least 32,768 (32k).\n\
1156If changing the thread stack size is unsupported, a ThreadError\n\
1157exception is raised. If the specified size is invalid, a ValueError\n\
1158exception is raised, and the stack size is unmodified. 32k bytes\n\
1159 currently the minimum supported stack size value to guarantee\n\
1160sufficient stack space for the interpreter itself.\n\
1161\n\
1162Note that some platforms may have particular restrictions on values for\n\
1163the stack size, such as requiring a minimum stack size larger than 32kB or\n\
1164requiring allocation in multiples of the system memory page size\n\
1165- platform documentation should be referred to for more information\n\
1166(4kB pages are common; using multiples of 4096 for the stack size is\n\
1167the suggested approach in the absence of more specific information).");
1168
Barry Warsawd0c10421996-12-17 00:05:22 +00001169static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
1171 METH_VARARGS,
1172 start_new_doc},
1173 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
1174 METH_VARARGS,
1175 start_new_doc},
1176 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
1177 METH_NOARGS, allocate_doc},
1178 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
1179 METH_NOARGS, allocate_doc},
1180 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
1181 METH_NOARGS, exit_doc},
1182 {"exit", (PyCFunction)thread_PyThread_exit_thread,
1183 METH_NOARGS, exit_doc},
1184 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
1185 METH_NOARGS, interrupt_doc},
1186 {"get_ident", (PyCFunction)thread_get_ident,
1187 METH_NOARGS, get_ident_doc},
1188 {"_count", (PyCFunction)thread__count,
1189 METH_NOARGS, _count_doc},
1190 {"stack_size", (PyCFunction)thread_stack_size,
1191 METH_VARARGS,
1192 stack_size_doc},
1193 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001194};
1195
1196
1197/* Initialization function */
1198
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001199PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001200"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001201The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001202
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001203PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001204"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +00001205call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001206\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001207acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1208release() -- unlock of the lock\n\
1209locked() -- test whether the lock is currently locked\n\
1210\n\
1211A lock is not owned by the thread that locked it; another thread may\n\
1212unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001213will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001214
Martin v. Löwis1a214512008-06-11 05:26:20 +00001215static struct PyModuleDef threadmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 PyModuleDef_HEAD_INIT,
1217 "_thread",
1218 thread_doc,
1219 -1,
1220 thread_methods,
1221 NULL,
1222 NULL,
1223 NULL,
1224 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001225};
1226
1227
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001228PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001229PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001230{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 PyObject *m, *d, *timeout_max;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001232
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 /* Initialize types: */
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001234 if (PyType_Ready(&localdummytype) < 0)
1235 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 if (PyType_Ready(&localtype) < 0)
1237 return NULL;
1238 if (PyType_Ready(&Locktype) < 0)
1239 return NULL;
1240 if (PyType_Ready(&RLocktype) < 0)
1241 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 /* Create the module and add the functions */
1244 m = PyModule_Create(&threadmodule);
1245 if (m == NULL)
1246 return NULL;
Antoine Pitrou7c3e5772010-04-14 15:44:10 +00001247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 timeout_max = PyFloat_FromDouble(PY_TIMEOUT_MAX / 1000000);
1249 if (!timeout_max)
1250 return NULL;
1251 if (PyModule_AddObject(m, "TIMEOUT_MAX", timeout_max) < 0)
1252 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 /* Add a symbolic constant */
1255 d = PyModule_GetDict(m);
1256 ThreadError = PyErr_NewException("_thread.error", NULL, NULL);
1257 PyDict_SetItemString(d, "error", ThreadError);
1258 Locktype.tp_doc = lock_doc;
1259 Py_INCREF(&Locktype);
1260 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Antoine Pitrou434736a2009-11-10 18:46:01 +00001261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 Py_INCREF(&RLocktype);
1263 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1264 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 Py_INCREF(&localtype);
1267 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1268 return NULL;
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 nb_threads = 0;
1271
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +00001272 str_dict = PyUnicode_InternFromString("__dict__");
1273 if (str_dict == NULL)
1274 return NULL;
1275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 /* Initialize the C thread library */
1277 PyThread_init_thread();
1278 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001279}