blob: 30379677dd09d398f0fa0ea46841b2a93c2e0ee3 [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;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000018
19/* Lock objects */
20
21typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000022 PyObject_HEAD
23 PyThread_type_lock lock_lock;
24 PyObject *in_weakreflist;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000025} lockobject;
26
Guido van Rossum1984f1e1992-08-04 12:41:02 +000027static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000028lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000029{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000030 if (self->in_weakreflist != NULL)
31 PyObject_ClearWeakRefs((PyObject *) self);
32 if (self->lock_lock != NULL) {
33 /* Unlock the lock so it's safe to free it */
34 PyThread_acquire_lock(self->lock_lock, 0);
35 PyThread_release_lock(self->lock_lock);
36
37 PyThread_free_lock(self->lock_lock);
38 }
39 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000040}
41
Barry Warsawd0c10421996-12-17 00:05:22 +000042static PyObject *
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000043lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000044{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000045 char *kwlist[] = {"blocking", "timeout", NULL};
46 int blocking = 1;
47 double timeout = -1;
48 PY_TIMEOUT_T microseconds;
49 int r;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000050
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000051 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist,
52 &blocking, &timeout))
53 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000054
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000055 if (!blocking && timeout != -1) {
56 PyErr_SetString(PyExc_ValueError, "can't specify a timeout "
57 "for a non-blocking call");
58 return NULL;
59 }
60 if (timeout < 0 && timeout != -1) {
61 PyErr_SetString(PyExc_ValueError, "timeout value must be "
62 "strictly positive");
63 return NULL;
64 }
65 if (!blocking)
66 microseconds = 0;
67 else if (timeout == -1)
68 microseconds = -1;
69 else {
70 timeout *= 1e6;
71 if (timeout >= (double) PY_TIMEOUT_MAX) {
72 PyErr_SetString(PyExc_OverflowError,
73 "timeout value is too large");
74 return NULL;
75 }
76 microseconds = (PY_TIMEOUT_T) timeout;
77 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +000078
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000079 Py_BEGIN_ALLOW_THREADS
80 r = PyThread_acquire_lock_timed(self->lock_lock, microseconds);
81 Py_END_ALLOW_THREADS
82
83 return PyBool_FromLong(r);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000084}
85
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000086PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000087"acquire([wait]) -> None or bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000088(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000089\n\
90Lock the lock. Without argument, this blocks if the lock is already\n\
91locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000092the lock, and return None once the lock is acquired.\n\
93With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000094and the return value reflects whether the lock is acquired.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000095The blocking operation is not interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000096
Barry Warsawd0c10421996-12-17 00:05:22 +000097static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000098lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000099{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100 /* Sanity check: the lock must be locked */
101 if (PyThread_acquire_lock(self->lock_lock, 0)) {
102 PyThread_release_lock(self->lock_lock);
103 PyErr_SetString(ThreadError, "release unlocked lock");
104 return NULL;
105 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000106
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107 PyThread_release_lock(self->lock_lock);
108 Py_INCREF(Py_None);
109 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000110}
111
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000112PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000113"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000114(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000115\n\
116Release the lock, allowing another thread that is blocked waiting for\n\
117the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000118but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000119
Barry Warsawd0c10421996-12-17 00:05:22 +0000120static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000121lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000122{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 if (PyThread_acquire_lock(self->lock_lock, 0)) {
124 PyThread_release_lock(self->lock_lock);
125 return PyBool_FromLong(0L);
126 }
127 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000128}
129
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000130PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000131"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000132(locked_lock() is an obsolete synonym)\n\
133\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000134Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000135
Barry Warsawd0c10421996-12-17 00:05:22 +0000136static PyMethodDef lock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
138 METH_VARARGS | METH_KEYWORDS, acquire_doc},
139 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
140 METH_VARARGS | METH_KEYWORDS, acquire_doc},
141 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
142 METH_NOARGS, release_doc},
143 {"release", (PyCFunction)lock_PyThread_release_lock,
144 METH_NOARGS, release_doc},
145 {"locked_lock", (PyCFunction)lock_locked_lock,
146 METH_NOARGS, locked_doc},
147 {"locked", (PyCFunction)lock_locked_lock,
148 METH_NOARGS, locked_doc},
149 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
150 METH_VARARGS | METH_KEYWORDS, acquire_doc},
151 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
152 METH_VARARGS, release_doc},
153 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000154};
155
Barry Warsawd0c10421996-12-17 00:05:22 +0000156static PyTypeObject Locktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 PyVarObject_HEAD_INIT(&PyType_Type, 0)
158 "_thread.lock", /*tp_name*/
159 sizeof(lockobject), /*tp_size*/
160 0, /*tp_itemsize*/
161 /* methods */
162 (destructor)lock_dealloc, /*tp_dealloc*/
163 0, /*tp_print*/
164 0, /*tp_getattr*/
165 0, /*tp_setattr*/
166 0, /*tp_reserved*/
167 0, /*tp_repr*/
168 0, /*tp_as_number*/
169 0, /*tp_as_sequence*/
170 0, /*tp_as_mapping*/
171 0, /*tp_hash*/
172 0, /*tp_call*/
173 0, /*tp_str*/
174 0, /*tp_getattro*/
175 0, /*tp_setattro*/
176 0, /*tp_as_buffer*/
177 Py_TPFLAGS_DEFAULT, /*tp_flags*/
178 0, /*tp_doc*/
179 0, /*tp_traverse*/
180 0, /*tp_clear*/
181 0, /*tp_richcompare*/
182 offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
183 0, /*tp_iter*/
184 0, /*tp_iternext*/
185 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000186};
187
Antoine Pitrou434736a2009-11-10 18:46:01 +0000188/* Recursive lock objects */
189
190typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 PyObject_HEAD
192 PyThread_type_lock rlock_lock;
193 long rlock_owner;
194 unsigned long rlock_count;
195 PyObject *in_weakreflist;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000196} rlockobject;
197
198static void
199rlock_dealloc(rlockobject *self)
200{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000201 assert(self->rlock_lock);
202 if (self->in_weakreflist != NULL)
203 PyObject_ClearWeakRefs((PyObject *) self);
204 /* Unlock the lock so it's safe to free it */
205 if (self->rlock_count > 0)
206 PyThread_release_lock(self->rlock_lock);
207
208 PyThread_free_lock(self->rlock_lock);
209 Py_TYPE(self)->tp_free(self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000210}
211
212static PyObject *
213rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
214{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 char *kwlist[] = {"blocking", "timeout", NULL};
216 int blocking = 1;
217 double timeout = -1;
218 PY_TIMEOUT_T microseconds;
219 long tid;
220 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist,
223 &blocking, &timeout))
224 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 if (!blocking && timeout != -1) {
227 PyErr_SetString(PyExc_ValueError, "can't specify a timeout "
228 "for a non-blocking call");
229 return NULL;
230 }
231 if (timeout < 0 && timeout != -1) {
232 PyErr_SetString(PyExc_ValueError, "timeout value must be "
233 "strictly positive");
234 return NULL;
235 }
236 if (!blocking)
237 microseconds = 0;
238 else if (timeout == -1)
239 microseconds = -1;
240 else {
241 timeout *= 1e6;
242 if (timeout >= (double) PY_TIMEOUT_MAX) {
243 PyErr_SetString(PyExc_OverflowError,
244 "timeout value is too large");
245 return NULL;
246 }
247 microseconds = (PY_TIMEOUT_T) timeout;
248 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 tid = PyThread_get_thread_ident();
251 if (self->rlock_count > 0 && tid == self->rlock_owner) {
252 unsigned long count = self->rlock_count + 1;
253 if (count <= self->rlock_count) {
254 PyErr_SetString(PyExc_OverflowError,
255 "Internal lock count overflowed");
256 return NULL;
257 }
258 self->rlock_count = count;
259 Py_RETURN_TRUE;
260 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 if (self->rlock_count > 0 ||
263 !PyThread_acquire_lock(self->rlock_lock, 0)) {
264 if (microseconds == 0) {
265 Py_RETURN_FALSE;
266 }
267 Py_BEGIN_ALLOW_THREADS
268 r = PyThread_acquire_lock_timed(self->rlock_lock, microseconds);
269 Py_END_ALLOW_THREADS
270 }
271 if (r) {
272 assert(self->rlock_count == 0);
273 self->rlock_owner = tid;
274 self->rlock_count = 1;
275 }
276
277 return PyBool_FromLong(r);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000278}
279
280PyDoc_STRVAR(rlock_acquire_doc,
281"acquire(blocking=True) -> bool\n\
282\n\
283Lock the lock. `blocking` indicates whether we should wait\n\
284for the lock to be available or not. If `blocking` is False\n\
285and another thread holds the lock, the method will return False\n\
286immediately. If `blocking` is True and another thread holds\n\
287the lock, the method will wait for the lock to be released,\n\
288take it and then return True.\n\
289(note: the blocking operation is not interruptible.)\n\
290\n\
291In all other cases, the method will return True immediately.\n\
292Precisely, if the current thread already holds the lock, its\n\
293internal counter is simply incremented. If nobody holds the lock,\n\
294the lock is taken and its internal counter initialized to 1.");
295
296static PyObject *
297rlock_release(rlockobject *self)
298{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000299 long tid = PyThread_get_thread_ident();
Antoine Pitrou434736a2009-11-10 18:46:01 +0000300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 if (self->rlock_count == 0 || self->rlock_owner != tid) {
302 PyErr_SetString(PyExc_RuntimeError,
303 "cannot release un-acquired lock");
304 return NULL;
305 }
306 if (--self->rlock_count == 0) {
307 self->rlock_owner = 0;
308 PyThread_release_lock(self->rlock_lock);
309 }
310 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000311}
312
313PyDoc_STRVAR(rlock_release_doc,
314"release()\n\
315\n\
316Release the lock, allowing another thread that is blocked waiting for\n\
317the lock to acquire the lock. The lock must be in the locked state,\n\
318and must be locked by the same thread that unlocks it; otherwise a\n\
319`RuntimeError` is raised.\n\
320\n\
321Do note that if the lock was acquire()d several times in a row by the\n\
322current thread, release() needs to be called as many times for the lock\n\
323to be available for other threads.");
324
325static PyObject *
326rlock_acquire_restore(rlockobject *self, PyObject *arg)
327{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 long owner;
329 unsigned long count;
330 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 if (!PyArg_ParseTuple(arg, "kl:_acquire_restore", &count, &owner))
333 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
336 Py_BEGIN_ALLOW_THREADS
337 r = PyThread_acquire_lock(self->rlock_lock, 1);
338 Py_END_ALLOW_THREADS
339 }
340 if (!r) {
341 PyErr_SetString(ThreadError, "couldn't acquire lock");
342 return NULL;
343 }
344 assert(self->rlock_count == 0);
345 self->rlock_owner = owner;
346 self->rlock_count = count;
347 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000348}
349
350PyDoc_STRVAR(rlock_acquire_restore_doc,
351"_acquire_restore(state) -> None\n\
352\n\
353For internal use by `threading.Condition`.");
354
355static PyObject *
356rlock_release_save(rlockobject *self)
357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 long owner;
359 unsigned long count;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 owner = self->rlock_owner;
362 count = self->rlock_count;
363 self->rlock_count = 0;
364 self->rlock_owner = 0;
365 PyThread_release_lock(self->rlock_lock);
366 return Py_BuildValue("kl", count, owner);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000367}
368
369PyDoc_STRVAR(rlock_release_save_doc,
370"_release_save() -> tuple\n\
371\n\
372For internal use by `threading.Condition`.");
373
374
375static PyObject *
376rlock_is_owned(rlockobject *self)
377{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 long tid = PyThread_get_thread_ident();
379
380 if (self->rlock_count > 0 && self->rlock_owner == tid) {
381 Py_RETURN_TRUE;
382 }
383 Py_RETURN_FALSE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000384}
385
386PyDoc_STRVAR(rlock_is_owned_doc,
387"_is_owned() -> bool\n\
388\n\
389For internal use by `threading.Condition`.");
390
391static PyObject *
392rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
393{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 rlockobject *self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 self = (rlockobject *) type->tp_alloc(type, 0);
397 if (self != NULL) {
398 self->rlock_lock = PyThread_allocate_lock();
399 if (self->rlock_lock == NULL) {
400 type->tp_free(self);
401 PyErr_SetString(ThreadError, "can't allocate lock");
402 return NULL;
403 }
404 self->in_weakreflist = NULL;
405 self->rlock_owner = 0;
406 self->rlock_count = 0;
407 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 return (PyObject *) self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000410}
411
412static PyObject *
413rlock_repr(rlockobject *self)
414{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 return PyUnicode_FromFormat("<%s owner=%ld count=%lu>",
416 Py_TYPE(self)->tp_name, self->rlock_owner, self->rlock_count);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000417}
418
419
420static PyMethodDef rlock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 {"acquire", (PyCFunction)rlock_acquire,
422 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
423 {"release", (PyCFunction)rlock_release,
424 METH_NOARGS, rlock_release_doc},
425 {"_is_owned", (PyCFunction)rlock_is_owned,
426 METH_NOARGS, rlock_is_owned_doc},
427 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
428 METH_O, rlock_acquire_restore_doc},
429 {"_release_save", (PyCFunction)rlock_release_save,
430 METH_NOARGS, rlock_release_save_doc},
431 {"__enter__", (PyCFunction)rlock_acquire,
432 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
433 {"__exit__", (PyCFunction)rlock_release,
434 METH_VARARGS, rlock_release_doc},
435 {NULL, NULL} /* sentinel */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000436};
437
438
439static PyTypeObject RLocktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000440 PyVarObject_HEAD_INIT(&PyType_Type, 0)
441 "_thread.RLock", /*tp_name*/
442 sizeof(rlockobject), /*tp_size*/
443 0, /*tp_itemsize*/
444 /* methods */
445 (destructor)rlock_dealloc, /*tp_dealloc*/
446 0, /*tp_print*/
447 0, /*tp_getattr*/
448 0, /*tp_setattr*/
449 0, /*tp_reserved*/
450 (reprfunc)rlock_repr, /*tp_repr*/
451 0, /*tp_as_number*/
452 0, /*tp_as_sequence*/
453 0, /*tp_as_mapping*/
454 0, /*tp_hash*/
455 0, /*tp_call*/
456 0, /*tp_str*/
457 0, /*tp_getattro*/
458 0, /*tp_setattro*/
459 0, /*tp_as_buffer*/
460 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
461 0, /*tp_doc*/
462 0, /*tp_traverse*/
463 0, /*tp_clear*/
464 0, /*tp_richcompare*/
465 offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
466 0, /*tp_iter*/
467 0, /*tp_iternext*/
468 rlock_methods, /*tp_methods*/
469 0, /* tp_members */
470 0, /* tp_getset */
471 0, /* tp_base */
472 0, /* tp_dict */
473 0, /* tp_descr_get */
474 0, /* tp_descr_set */
475 0, /* tp_dictoffset */
476 0, /* tp_init */
477 PyType_GenericAlloc, /* tp_alloc */
478 rlock_new /* tp_new */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000479};
480
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000481static lockobject *
482newlockobject(void)
483{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 lockobject *self;
485 self = PyObject_New(lockobject, &Locktype);
486 if (self == NULL)
487 return NULL;
488 self->lock_lock = PyThread_allocate_lock();
489 self->in_weakreflist = NULL;
490 if (self->lock_lock == NULL) {
491 Py_DECREF(self);
492 PyErr_SetString(ThreadError, "can't allocate lock");
493 return NULL;
494 }
495 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000496}
497
Jim Fultond15dc062004-07-14 19:11:50 +0000498/* Thread-local objects */
499
500#include "structmember.h"
501
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000502/* Quick overview:
503
504 We need to be able to reclaim reference cycles as soon as possible
505 (both when a thread is being terminated, or a thread-local object
506 becomes unreachable from user data). Constraints:
507 - it must not be possible for thread-state dicts to be involved in
508 reference cycles (otherwise the cyclic GC will refuse to consider
509 objects referenced from a reachable thread-state dict, even though
510 local_dealloc would clear them)
511 - the death of a thread-state dict must still imply destruction of the
512 corresponding local dicts in all thread-local objects.
513
514 Our implementation uses small "localdummy" objects in order to break
515 the reference chain. These trivial objects are hashable (using the
516 default scheme of identity hashing) and weakrefable.
517 Each thread-state holds a separate localdummy for each local object
518 (as a /strong reference/),
519 and each thread-local object holds a dict mapping /weak references/
520 of localdummies to local dicts.
521
522 Therefore:
523 - only the thread-state dict holds a strong reference to the dummies
524 - only the thread-local object holds a strong reference to the local dicts
525 - only outside objects (application- or library-level) hold strong
526 references to the thread-local objects
527 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
528 dummies attached to that thread are called, and destroy the corresponding
529 local dicts from thread-local objects
530 - as soon as a thread-local object is destroyed, its local dicts are
531 destroyed and its dummies are manually removed from all thread states
532 - the GC can do its work correctly when a thread-local object is dangling,
533 without any interference from the thread-state dicts
534
535 As an additional optimization, each localdummy holds a borrowed reference
536 to the corresponding localdict. This borrowed reference is only used
537 by the thread-local object which has created the localdummy, which should
538 guarantee that the localdict still exists when accessed.
539*/
540
541typedef struct {
542 PyObject_HEAD
543 PyObject *localdict; /* Borrowed reference! */
544 PyObject *weakreflist; /* List of weak references to self */
545} localdummyobject;
546
547static void
548localdummy_dealloc(localdummyobject *self)
549{
550 if (self->weakreflist != NULL)
551 PyObject_ClearWeakRefs((PyObject *) self);
552 Py_TYPE(self)->tp_free((PyObject*)self);
553}
554
555static PyTypeObject localdummytype = {
556 PyVarObject_HEAD_INIT(NULL, 0)
557 /* tp_name */ "_thread._localdummy",
558 /* tp_basicsize */ sizeof(localdummyobject),
559 /* tp_itemsize */ 0,
560 /* tp_dealloc */ (destructor)localdummy_dealloc,
561 /* tp_print */ 0,
562 /* tp_getattr */ 0,
563 /* tp_setattr */ 0,
564 /* tp_reserved */ 0,
565 /* tp_repr */ 0,
566 /* tp_as_number */ 0,
567 /* tp_as_sequence */ 0,
568 /* tp_as_mapping */ 0,
569 /* tp_hash */ 0,
570 /* tp_call */ 0,
571 /* tp_str */ 0,
572 /* tp_getattro */ 0,
573 /* tp_setattro */ 0,
574 /* tp_as_buffer */ 0,
575 /* tp_flags */ Py_TPFLAGS_DEFAULT,
576 /* tp_doc */ "Thread-local dummy",
577 /* tp_traverse */ 0,
578 /* tp_clear */ 0,
579 /* tp_richcompare */ 0,
580 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
581};
582
583
Jim Fultond15dc062004-07-14 19:11:50 +0000584typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 PyObject_HEAD
586 PyObject *key;
587 PyObject *args;
588 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000589 /* The current thread's local dict (necessary for tp_dictoffset) */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 PyObject *dict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000591 PyObject *weakreflist; /* List of weak references to self */
592 /* A {localdummy weakref -> localdict} dict */
593 PyObject *dummies;
594 /* The callback for weakrefs to localdummies */
595 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000596} localobject;
597
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000598/* Forward declaration */
599static PyObject *_ldict(localobject *self);
600static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
601
602/* Create and register the dummy for the current thread, as well as the
603 corresponding local dict */
604static int
605_local_create_dummy(localobject *self)
606{
607 PyObject *tdict, *ldict = NULL, *wr = NULL;
608 localdummyobject *dummy = NULL;
609 int r;
610
611 tdict = PyThreadState_GetDict();
612 if (tdict == NULL) {
613 PyErr_SetString(PyExc_SystemError,
614 "Couldn't get thread-state dictionary");
615 goto err;
616 }
617
618 ldict = PyDict_New();
619 if (ldict == NULL)
620 goto err;
621 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
622 if (dummy == NULL)
623 goto err;
624 dummy->localdict = ldict;
625 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
626 if (wr == NULL)
627 goto err;
628
629 /* As a side-effect, this will cache the weakref's hash before the
630 dummy gets deleted */
631 r = PyDict_SetItem(self->dummies, wr, ldict);
632 if (r < 0)
633 goto err;
634 Py_CLEAR(wr);
635 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
636 if (r < 0)
637 goto err;
638 Py_CLEAR(dummy);
639
640 Py_CLEAR(self->dict);
641 self->dict = ldict;
642 return 0;
643
644err:
645 Py_XDECREF(ldict);
646 Py_XDECREF(wr);
647 Py_XDECREF(dummy);
648 return -1;
649}
650
Jim Fultond15dc062004-07-14 19:11:50 +0000651static PyObject *
652local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 localobject *self;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000655 PyObject *wr;
656 static PyMethodDef wr_callback_def = {
657 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
658 };
Jim Fultond15dc062004-07-14 19:11:50 +0000659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 if (type->tp_init == PyBaseObject_Type.tp_init
661 && ((args && PyObject_IsTrue(args))
662 || (kw && PyObject_IsTrue(kw)))) {
663 PyErr_SetString(PyExc_TypeError,
664 "Initialization arguments are not supported");
665 return NULL;
666 }
Jim Fultond15dc062004-07-14 19:11:50 +0000667
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000668 self = (localobject *)type->tp_alloc(type, 0);
669 if (self == NULL)
670 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000671
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 Py_XINCREF(args);
673 self->args = args;
674 Py_XINCREF(kw);
675 self->kw = kw;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 self->key = PyUnicode_FromFormat("thread.local.%p", self);
677 if (self->key == NULL)
678 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000679
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000680 self->dummies = PyDict_New();
681 if (self->dummies == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000683
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000684 /* We use a weak reference to self in the callback closure
685 in order to avoid spurious reference cycles */
686 wr = PyWeakref_NewRef((PyObject *) self, NULL);
687 if (wr == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 goto err;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000689 self->wr_callback = PyCFunction_New(&wr_callback_def, wr);
690 Py_DECREF(wr);
691 if (self->wr_callback == NULL)
692 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000693
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000694 if (_local_create_dummy(self) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000698
699 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 Py_DECREF(self);
701 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000702}
703
704static int
705local_traverse(localobject *self, visitproc visit, void *arg)
706{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 Py_VISIT(self->args);
708 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000709 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000710 Py_VISIT(self->dict);
711 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000712}
713
714static int
715local_clear(localobject *self)
716{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000717 PyThreadState *tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 Py_CLEAR(self->args);
719 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000720 Py_CLEAR(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 Py_CLEAR(self->dict);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000722 Py_CLEAR(self->wr_callback);
723 /* Remove all strong references to dummies from the thread states */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 if (self->key
725 && (tstate = PyThreadState_Get())
726 && tstate->interp) {
727 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
728 tstate;
729 tstate = PyThreadState_Next(tstate))
730 if (tstate->dict &&
731 PyDict_GetItem(tstate->dict, self->key))
732 PyDict_DelItem(tstate->dict, self->key);
733 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000734 return 0;
735}
Jim Fultond15dc062004-07-14 19:11:50 +0000736
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000737static void
738local_dealloc(localobject *self)
739{
740 /* Weakrefs must be invalidated right now, otherwise they can be used
741 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
742 if (self->weakreflist != NULL)
743 PyObject_ClearWeakRefs((PyObject *) self);
744
745 PyObject_GC_UnTrack(self);
746
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000748 Py_XDECREF(self->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000749 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000750}
751
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000752/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000753static PyObject *
754_ldict(localobject *self)
755{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000756 PyObject *tdict, *ldict, *dummy;
Jim Fultond15dc062004-07-14 19:11:50 +0000757
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 tdict = PyThreadState_GetDict();
759 if (tdict == NULL) {
760 PyErr_SetString(PyExc_SystemError,
761 "Couldn't get thread-state dictionary");
762 return NULL;
763 }
Jim Fultond15dc062004-07-14 19:11:50 +0000764
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000765 dummy = PyDict_GetItem(tdict, self->key);
766 if (dummy == NULL) {
767 if (_local_create_dummy(self) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000768 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000769 ldict = self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000771 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
772 Py_TYPE(self)->tp_init((PyObject*)self,
773 self->args, self->kw) < 0) {
774 /* we need to get rid of ldict from thread so
775 we create a new one the next time we do an attr
776 acces */
777 PyDict_DelItem(tdict, self->key);
778 return NULL;
779 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000780 }
781 else {
782 assert(Py_TYPE(dummy) == &localdummytype);
783 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000784 }
Jim Fultond15dc062004-07-14 19:11:50 +0000785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000786 /* The call to tp_init above may have caused another thread to run.
787 Install our ldict again. */
788 if (self->dict != ldict) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000789 Py_INCREF(ldict);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000790 Py_CLEAR(self->dict);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000791 self->dict = ldict;
792 }
793
794 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000795}
796
Jim Fultond15dc062004-07-14 19:11:50 +0000797static int
798local_setattro(localobject *self, PyObject *name, PyObject *v)
799{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 PyObject *ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 ldict = _ldict(self);
803 if (ldict == NULL)
804 return -1;
805
806 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000807}
808
809static PyObject *
810local_getdict(localobject *self, void *closure)
811{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000812 PyObject *ldict;
813 ldict = _ldict(self);
814 Py_XINCREF(ldict);
815 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000816}
817
818static PyGetSetDef local_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000819 {"__dict__", (getter)local_getdict, (setter)NULL,
820 "Local-data dictionary", NULL},
821 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000822};
823
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000824static PyObject *local_getattro(localobject *, PyObject *);
825
Jim Fultond15dc062004-07-14 19:11:50 +0000826static PyTypeObject localtype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000827 PyVarObject_HEAD_INIT(NULL, 0)
828 /* tp_name */ "_thread._local",
829 /* tp_basicsize */ sizeof(localobject),
830 /* tp_itemsize */ 0,
831 /* tp_dealloc */ (destructor)local_dealloc,
832 /* tp_print */ 0,
833 /* tp_getattr */ 0,
834 /* tp_setattr */ 0,
835 /* tp_reserved */ 0,
836 /* tp_repr */ 0,
837 /* tp_as_number */ 0,
838 /* tp_as_sequence */ 0,
839 /* tp_as_mapping */ 0,
840 /* tp_hash */ 0,
841 /* tp_call */ 0,
842 /* tp_str */ 0,
843 /* tp_getattro */ (getattrofunc)local_getattro,
844 /* tp_setattro */ (setattrofunc)local_setattro,
845 /* tp_as_buffer */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000846 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
847 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 /* tp_doc */ "Thread-local data",
849 /* tp_traverse */ (traverseproc)local_traverse,
850 /* tp_clear */ (inquiry)local_clear,
851 /* tp_richcompare */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000852 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 /* tp_iter */ 0,
854 /* tp_iternext */ 0,
855 /* tp_methods */ 0,
856 /* tp_members */ 0,
857 /* tp_getset */ local_getset,
858 /* tp_base */ 0,
859 /* tp_dict */ 0, /* internal use */
860 /* tp_descr_get */ 0,
861 /* tp_descr_set */ 0,
862 /* tp_dictoffset */ offsetof(localobject, dict),
863 /* tp_init */ 0,
864 /* tp_alloc */ 0,
865 /* tp_new */ local_new,
866 /* tp_free */ 0, /* Low-level free-mem routine */
867 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000868};
869
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000870static PyObject *
871local_getattro(localobject *self, PyObject *name)
872{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000873 PyObject *ldict, *value;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000875 ldict = _ldict(self);
876 if (ldict == NULL)
877 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000879 if (Py_TYPE(self) != &localtype)
880 /* use generic lookup for subtypes */
881 return PyObject_GenericGetAttr((PyObject *)self, name);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000883 /* Optimization: just look in dict ourselves */
884 value = PyDict_GetItem(ldict, name);
885 if (value == NULL)
886 /* Fall back on generic to get __class__ and __dict__ */
887 return PyObject_GenericGetAttr((PyObject *)self, name);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 Py_INCREF(value);
890 return value;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000891}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000892
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000893/* Called when a dummy is destroyed. */
894static PyObject *
895_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
896{
897 PyObject *obj;
898 localobject *self;
899 assert(PyWeakref_CheckRef(localweakref));
900 obj = PyWeakref_GET_OBJECT(localweakref);
901 if (obj == Py_None)
902 Py_RETURN_NONE;
903 Py_INCREF(obj);
904 assert(PyObject_TypeCheck(obj, &localtype));
905 /* If the thread-local object is still alive and not being cleared,
906 remove the corresponding local dict */
907 self = (localobject *) obj;
908 if (self->dummies != NULL) {
909 PyObject *ldict;
910 ldict = PyDict_GetItem(self->dummies, dummyweakref);
911 if (ldict != NULL) {
912 if (ldict == self->dict)
913 Py_CLEAR(self->dict);
914 PyDict_DelItem(self->dummies, dummyweakref);
915 }
916 if (PyErr_Occurred())
917 PyErr_WriteUnraisable(obj);
918 }
919 Py_DECREF(obj);
920 Py_RETURN_NONE;
921}
922
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000923/* Module functions */
924
Guido van Rossuma027efa1997-05-05 20:56:21 +0000925struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 PyInterpreterState *interp;
927 PyObject *func;
928 PyObject *args;
929 PyObject *keyw;
930 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000931};
932
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000933static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000934t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000935{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000936 struct bootstate *boot = (struct bootstate *) boot_raw;
937 PyThreadState *tstate;
938 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 tstate = boot->tstate;
941 tstate->thread_id = PyThread_get_thread_ident();
942 _PyThreadState_Init(tstate);
943 PyEval_AcquireThread(tstate);
944 nb_threads++;
945 res = PyEval_CallObjectWithKeywords(
946 boot->func, boot->args, boot->keyw);
947 if (res == NULL) {
948 if (PyErr_ExceptionMatches(PyExc_SystemExit))
949 PyErr_Clear();
950 else {
951 PyObject *file;
952 PySys_WriteStderr(
953 "Unhandled exception in thread started by ");
954 file = PySys_GetObject("stderr");
955 if (file != NULL && file != Py_None)
956 PyFile_WriteObject(boot->func, file, 0);
957 else
958 PyObject_Print(boot->func, stderr, 0);
959 PySys_WriteStderr("\n");
960 PyErr_PrintEx(0);
961 }
962 }
963 else
964 Py_DECREF(res);
965 Py_DECREF(boot->func);
966 Py_DECREF(boot->args);
967 Py_XDECREF(boot->keyw);
968 PyMem_DEL(boot_raw);
969 nb_threads--;
970 PyThreadState_Clear(tstate);
971 PyThreadState_DeleteCurrent();
972 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000973}
974
Barry Warsawd0c10421996-12-17 00:05:22 +0000975static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000976thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000977{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 PyObject *func, *args, *keyw = NULL;
979 struct bootstate *boot;
980 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
983 &func, &args, &keyw))
984 return NULL;
985 if (!PyCallable_Check(func)) {
986 PyErr_SetString(PyExc_TypeError,
987 "first arg must be callable");
988 return NULL;
989 }
990 if (!PyTuple_Check(args)) {
991 PyErr_SetString(PyExc_TypeError,
992 "2nd arg must be a tuple");
993 return NULL;
994 }
995 if (keyw != NULL && !PyDict_Check(keyw)) {
996 PyErr_SetString(PyExc_TypeError,
997 "optional 3rd arg must be a dictionary");
998 return NULL;
999 }
1000 boot = PyMem_NEW(struct bootstate, 1);
1001 if (boot == NULL)
1002 return PyErr_NoMemory();
1003 boot->interp = PyThreadState_GET()->interp;
1004 boot->func = func;
1005 boot->args = args;
1006 boot->keyw = keyw;
1007 boot->tstate = _PyThreadState_Prealloc(boot->interp);
1008 if (boot->tstate == NULL) {
1009 PyMem_DEL(boot);
1010 return PyErr_NoMemory();
1011 }
1012 Py_INCREF(func);
1013 Py_INCREF(args);
1014 Py_XINCREF(keyw);
1015 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
1016 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
1017 if (ident == -1) {
1018 PyErr_SetString(ThreadError, "can't start new thread");
1019 Py_DECREF(func);
1020 Py_DECREF(args);
1021 Py_XDECREF(keyw);
1022 PyThreadState_Clear(boot->tstate);
1023 PyMem_DEL(boot);
1024 return NULL;
1025 }
1026 return PyLong_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001027}
1028
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001029PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001030"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001031(start_new() is an obsolete synonym)\n\
1032\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001033Start a new thread and return its identifier. The thread will call the\n\
1034function with positional arguments from the tuple args and keyword arguments\n\
1035taken from the optional dictionary kwargs. The thread exits when the\n\
1036function returns; the return value is ignored. The thread will also exit\n\
1037when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001038printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001039
Barry Warsawd0c10421996-12-17 00:05:22 +00001040static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001041thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001042{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001043 PyErr_SetNone(PyExc_SystemExit);
1044 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001045}
1046
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001047PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001048"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +00001049(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001050\n\
1051This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001052thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001053
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001054static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001055thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001056{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 PyErr_SetInterrupt();
1058 Py_INCREF(Py_None);
1059 return Py_None;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001060}
1061
1062PyDoc_STRVAR(interrupt_doc,
1063"interrupt_main()\n\
1064\n\
1065Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001066A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001067);
1068
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001069static lockobject *newlockobject(void);
1070
Barry Warsawd0c10421996-12-17 00:05:22 +00001071static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001072thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001075}
1076
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001077PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001078"allocate_lock() -> lock object\n\
1079(allocate() is an obsolete synonym)\n\
1080\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001081Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001082
Barry Warsawd0c10421996-12-17 00:05:22 +00001083static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001084thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001085{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001086 long ident;
1087 ident = PyThread_get_thread_ident();
1088 if (ident == -1) {
1089 PyErr_SetString(ThreadError, "no current thread ident");
1090 return NULL;
1091 }
1092 return PyLong_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001093}
1094
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001095PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001096"get_ident() -> integer\n\
1097\n\
1098Return a non-zero integer that uniquely identifies the current thread\n\
1099amongst other threads that exist simultaneously.\n\
1100This may be used to identify per-thread resources.\n\
1101Even though on some platforms threads identities may appear to be\n\
1102allocated consecutive numbers starting at 1, this behavior should not\n\
1103be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001104A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001105
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001106static PyObject *
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001107thread__count(PyObject *self)
1108{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001109 return PyLong_FromLong(nb_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001110}
1111
1112PyDoc_STRVAR(_count_doc,
1113"_count() -> integer\n\
1114\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001115\
1116Return the number of currently running Python threads, excluding \n\
1117the main thread. The returned number comprises all threads created\n\
1118through `start_new_thread()` as well as `threading.Thread`, and not\n\
1119yet finished.\n\
1120\n\
1121This function is meant for internal and specialized purposes only.\n\
1122In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001123
1124static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001125thread_stack_size(PyObject *self, PyObject *args)
1126{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001127 size_t old_size;
1128 Py_ssize_t new_size = 0;
1129 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1132 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001134 if (new_size < 0) {
1135 PyErr_SetString(PyExc_ValueError,
1136 "size must be 0 or a positive value");
1137 return NULL;
1138 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 rc = PyThread_set_stacksize((size_t) new_size);
1143 if (rc == -1) {
1144 PyErr_Format(PyExc_ValueError,
1145 "size not valid: %zd bytes",
1146 new_size);
1147 return NULL;
1148 }
1149 if (rc == -2) {
1150 PyErr_SetString(ThreadError,
1151 "setting stack size not supported");
1152 return NULL;
1153 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001156}
1157
1158PyDoc_STRVAR(stack_size_doc,
1159"stack_size([size]) -> size\n\
1160\n\
1161Return the thread stack size used when creating new threads. The\n\
1162optional size argument specifies the stack size (in bytes) to be used\n\
1163for subsequently created threads, and must be 0 (use platform or\n\
1164configured default) or a positive integer value of at least 32,768 (32k).\n\
1165If changing the thread stack size is unsupported, a ThreadError\n\
1166exception is raised. If the specified size is invalid, a ValueError\n\
1167exception is raised, and the stack size is unmodified. 32k bytes\n\
1168 currently the minimum supported stack size value to guarantee\n\
1169sufficient stack space for the interpreter itself.\n\
1170\n\
1171Note that some platforms may have particular restrictions on values for\n\
1172the stack size, such as requiring a minimum stack size larger than 32kB or\n\
1173requiring allocation in multiples of the system memory page size\n\
1174- platform documentation should be referred to for more information\n\
1175(4kB pages are common; using multiples of 4096 for the stack size is\n\
1176the suggested approach in the absence of more specific information).");
1177
Barry Warsawd0c10421996-12-17 00:05:22 +00001178static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
1180 METH_VARARGS,
1181 start_new_doc},
1182 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
1183 METH_VARARGS,
1184 start_new_doc},
1185 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
1186 METH_NOARGS, allocate_doc},
1187 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
1188 METH_NOARGS, allocate_doc},
1189 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
1190 METH_NOARGS, exit_doc},
1191 {"exit", (PyCFunction)thread_PyThread_exit_thread,
1192 METH_NOARGS, exit_doc},
1193 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
1194 METH_NOARGS, interrupt_doc},
1195 {"get_ident", (PyCFunction)thread_get_ident,
1196 METH_NOARGS, get_ident_doc},
1197 {"_count", (PyCFunction)thread__count,
1198 METH_NOARGS, _count_doc},
1199 {"stack_size", (PyCFunction)thread_stack_size,
1200 METH_VARARGS,
1201 stack_size_doc},
1202 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001203};
1204
1205
1206/* Initialization function */
1207
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001208PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001209"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001210The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001211
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001212PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001213"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +00001214call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001215\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001216acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1217release() -- unlock of the lock\n\
1218locked() -- test whether the lock is currently locked\n\
1219\n\
1220A lock is not owned by the thread that locked it; another thread may\n\
1221unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001222will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001223
Martin v. Löwis1a214512008-06-11 05:26:20 +00001224static struct PyModuleDef threadmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001225 PyModuleDef_HEAD_INIT,
1226 "_thread",
1227 thread_doc,
1228 -1,
1229 thread_methods,
1230 NULL,
1231 NULL,
1232 NULL,
1233 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001234};
1235
1236
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001237PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001238PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001239{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 PyObject *m, *d, *timeout_max;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 /* Initialize types: */
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001243 if (PyType_Ready(&localdummytype) < 0)
1244 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 if (PyType_Ready(&localtype) < 0)
1246 return NULL;
1247 if (PyType_Ready(&Locktype) < 0)
1248 return NULL;
1249 if (PyType_Ready(&RLocktype) < 0)
1250 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 /* Create the module and add the functions */
1253 m = PyModule_Create(&threadmodule);
1254 if (m == NULL)
1255 return NULL;
Antoine Pitrou7c3e5772010-04-14 15:44:10 +00001256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 timeout_max = PyFloat_FromDouble(PY_TIMEOUT_MAX / 1000000);
1258 if (!timeout_max)
1259 return NULL;
1260 if (PyModule_AddObject(m, "TIMEOUT_MAX", timeout_max) < 0)
1261 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 /* Add a symbolic constant */
1264 d = PyModule_GetDict(m);
1265 ThreadError = PyErr_NewException("_thread.error", NULL, NULL);
1266 PyDict_SetItemString(d, "error", ThreadError);
1267 Locktype.tp_doc = lock_doc;
1268 Py_INCREF(&Locktype);
1269 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Antoine Pitrou434736a2009-11-10 18:46:01 +00001270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 Py_INCREF(&RLocktype);
1272 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1273 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 Py_INCREF(&localtype);
1276 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1277 return NULL;
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 nb_threads = 0;
1280
1281 /* Initialize the C thread library */
1282 PyThread_init_thread();
1283 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001284}