blob: ea038defb1c728a2e0c324fcc885b6b4f58a4459 [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
Antoine Pitrou810023d2010-12-15 22:59:16 +000043/* Helper to acquire an interruptible lock with a timeout. If the lock acquire
44 * is interrupted, signal handlers are run, and if they raise an exception,
45 * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE
46 * are returned, depending on whether the lock can be acquired withing the
47 * timeout.
48 */
49static PyLockStatus
50acquire_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds)
51{
52 PyLockStatus r;
53 _PyTime_timeval curtime;
54 _PyTime_timeval endtime;
55
56 if (microseconds > 0) {
57 _PyTime_gettimeofday(&endtime);
58 endtime.tv_sec += microseconds / (1000 * 1000);
59 endtime.tv_usec += microseconds % (1000 * 1000);
60 }
61
62
63 do {
64 Py_BEGIN_ALLOW_THREADS
65 r = PyThread_acquire_lock_timed(lock, microseconds, 1);
66 Py_END_ALLOW_THREADS
67
68 if (r == PY_LOCK_INTR) {
69 /* Run signal handlers if we were interrupted. Propagate
70 * exceptions from signal handlers, such as KeyboardInterrupt, by
71 * passing up PY_LOCK_INTR. */
72 if (Py_MakePendingCalls() < 0) {
73 return PY_LOCK_INTR;
74 }
75
76 /* If we're using a timeout, recompute the timeout after processing
77 * signals, since those can take time. */
78 if (microseconds >= 0) {
79 _PyTime_gettimeofday(&curtime);
80 microseconds = ((endtime.tv_sec - curtime.tv_sec) * 1000000 +
81 (endtime.tv_usec - curtime.tv_usec));
82
83 /* Check for negative values, since those mean block forever.
84 */
85 if (microseconds <= 0) {
86 r = PY_LOCK_FAILURE;
87 }
88 }
89 }
90 } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */
91
92 return r;
93}
94
Barry Warsawd0c10421996-12-17 00:05:22 +000095static PyObject *
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000096lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000097{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 char *kwlist[] = {"blocking", "timeout", NULL};
99 int blocking = 1;
100 double timeout = -1;
101 PY_TIMEOUT_T microseconds;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000102 PyLockStatus r;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist,
105 &blocking, &timeout))
106 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000108 if (!blocking && timeout != -1) {
109 PyErr_SetString(PyExc_ValueError, "can't specify a timeout "
110 "for a non-blocking call");
111 return NULL;
112 }
113 if (timeout < 0 && timeout != -1) {
114 PyErr_SetString(PyExc_ValueError, "timeout value must be "
115 "strictly positive");
116 return NULL;
117 }
118 if (!blocking)
119 microseconds = 0;
120 else if (timeout == -1)
121 microseconds = -1;
122 else {
123 timeout *= 1e6;
124 if (timeout >= (double) PY_TIMEOUT_MAX) {
125 PyErr_SetString(PyExc_OverflowError,
126 "timeout value is too large");
127 return NULL;
128 }
129 microseconds = (PY_TIMEOUT_T) timeout;
130 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000131
Antoine Pitrou810023d2010-12-15 22:59:16 +0000132 r = acquire_timed(self->lock_lock, microseconds);
133 if (r == PY_LOCK_INTR) {
134 return NULL;
135 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000136
Antoine Pitrou810023d2010-12-15 22:59:16 +0000137 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000138}
139
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000140PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000141"acquire([wait]) -> None or bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000142(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000143\n\
144Lock the lock. Without argument, this blocks if the lock is already\n\
145locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000146the lock, and return None once the lock is acquired.\n\
147With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000148and the return value reflects whether the lock is acquired.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000149The blocking operation is interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000150
Barry Warsawd0c10421996-12-17 00:05:22 +0000151static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000152lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000153{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 /* Sanity check: the lock must be locked */
155 if (PyThread_acquire_lock(self->lock_lock, 0)) {
156 PyThread_release_lock(self->lock_lock);
157 PyErr_SetString(ThreadError, "release unlocked lock");
158 return NULL;
159 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000161 PyThread_release_lock(self->lock_lock);
162 Py_INCREF(Py_None);
163 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000164}
165
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000166PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000167"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000168(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000169\n\
170Release the lock, allowing another thread that is blocked waiting for\n\
171the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000172but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000173
Barry Warsawd0c10421996-12-17 00:05:22 +0000174static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000175lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 if (PyThread_acquire_lock(self->lock_lock, 0)) {
178 PyThread_release_lock(self->lock_lock);
179 return PyBool_FromLong(0L);
180 }
181 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000182}
183
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000184PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000185"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000186(locked_lock() is an obsolete synonym)\n\
187\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000188Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000189
Barry Warsawd0c10421996-12-17 00:05:22 +0000190static PyMethodDef lock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
192 METH_VARARGS | METH_KEYWORDS, acquire_doc},
193 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
194 METH_VARARGS | METH_KEYWORDS, acquire_doc},
195 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
196 METH_NOARGS, release_doc},
197 {"release", (PyCFunction)lock_PyThread_release_lock,
198 METH_NOARGS, release_doc},
199 {"locked_lock", (PyCFunction)lock_locked_lock,
200 METH_NOARGS, locked_doc},
201 {"locked", (PyCFunction)lock_locked_lock,
202 METH_NOARGS, locked_doc},
203 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
204 METH_VARARGS | METH_KEYWORDS, acquire_doc},
205 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
206 METH_VARARGS, release_doc},
207 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000208};
209
Barry Warsawd0c10421996-12-17 00:05:22 +0000210static PyTypeObject Locktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000211 PyVarObject_HEAD_INIT(&PyType_Type, 0)
212 "_thread.lock", /*tp_name*/
213 sizeof(lockobject), /*tp_size*/
214 0, /*tp_itemsize*/
215 /* methods */
216 (destructor)lock_dealloc, /*tp_dealloc*/
217 0, /*tp_print*/
218 0, /*tp_getattr*/
219 0, /*tp_setattr*/
220 0, /*tp_reserved*/
221 0, /*tp_repr*/
222 0, /*tp_as_number*/
223 0, /*tp_as_sequence*/
224 0, /*tp_as_mapping*/
225 0, /*tp_hash*/
226 0, /*tp_call*/
227 0, /*tp_str*/
228 0, /*tp_getattro*/
229 0, /*tp_setattro*/
230 0, /*tp_as_buffer*/
231 Py_TPFLAGS_DEFAULT, /*tp_flags*/
232 0, /*tp_doc*/
233 0, /*tp_traverse*/
234 0, /*tp_clear*/
235 0, /*tp_richcompare*/
236 offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
237 0, /*tp_iter*/
238 0, /*tp_iternext*/
239 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000240};
241
Antoine Pitrou434736a2009-11-10 18:46:01 +0000242/* Recursive lock objects */
243
244typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 PyObject_HEAD
246 PyThread_type_lock rlock_lock;
247 long rlock_owner;
248 unsigned long rlock_count;
249 PyObject *in_weakreflist;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000250} rlockobject;
251
252static void
253rlock_dealloc(rlockobject *self)
254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255 assert(self->rlock_lock);
256 if (self->in_weakreflist != NULL)
257 PyObject_ClearWeakRefs((PyObject *) self);
258 /* Unlock the lock so it's safe to free it */
259 if (self->rlock_count > 0)
260 PyThread_release_lock(self->rlock_lock);
261
262 PyThread_free_lock(self->rlock_lock);
263 Py_TYPE(self)->tp_free(self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000264}
265
266static PyObject *
267rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
268{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 char *kwlist[] = {"blocking", "timeout", NULL};
270 int blocking = 1;
271 double timeout = -1;
272 PY_TIMEOUT_T microseconds;
273 long tid;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000274 PyLockStatus r = PY_LOCK_ACQUIRED;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist,
277 &blocking, &timeout))
278 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 if (!blocking && timeout != -1) {
281 PyErr_SetString(PyExc_ValueError, "can't specify a timeout "
282 "for a non-blocking call");
283 return NULL;
284 }
285 if (timeout < 0 && timeout != -1) {
286 PyErr_SetString(PyExc_ValueError, "timeout value must be "
287 "strictly positive");
288 return NULL;
289 }
290 if (!blocking)
291 microseconds = 0;
292 else if (timeout == -1)
293 microseconds = -1;
294 else {
295 timeout *= 1e6;
296 if (timeout >= (double) PY_TIMEOUT_MAX) {
297 PyErr_SetString(PyExc_OverflowError,
298 "timeout value is too large");
299 return NULL;
300 }
301 microseconds = (PY_TIMEOUT_T) timeout;
302 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 tid = PyThread_get_thread_ident();
305 if (self->rlock_count > 0 && tid == self->rlock_owner) {
306 unsigned long count = self->rlock_count + 1;
307 if (count <= self->rlock_count) {
308 PyErr_SetString(PyExc_OverflowError,
309 "Internal lock count overflowed");
310 return NULL;
311 }
312 self->rlock_count = count;
313 Py_RETURN_TRUE;
314 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 if (self->rlock_count > 0 ||
317 !PyThread_acquire_lock(self->rlock_lock, 0)) {
318 if (microseconds == 0) {
319 Py_RETURN_FALSE;
320 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000321 r = acquire_timed(self->rlock_lock, microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000323 if (r == PY_LOCK_ACQUIRED) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324 assert(self->rlock_count == 0);
325 self->rlock_owner = tid;
326 self->rlock_count = 1;
327 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000328 else if (r == PY_LOCK_INTR) {
329 return NULL;
330 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331
Antoine Pitrou810023d2010-12-15 22:59:16 +0000332 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000333}
334
335PyDoc_STRVAR(rlock_acquire_doc,
336"acquire(blocking=True) -> bool\n\
337\n\
338Lock the lock. `blocking` indicates whether we should wait\n\
339for the lock to be available or not. If `blocking` is False\n\
340and another thread holds the lock, the method will return False\n\
341immediately. If `blocking` is True and another thread holds\n\
342the lock, the method will wait for the lock to be released,\n\
343take it and then return True.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000344(note: the blocking operation is interruptible.)\n\
Antoine Pitrou434736a2009-11-10 18:46:01 +0000345\n\
346In all other cases, the method will return True immediately.\n\
347Precisely, if the current thread already holds the lock, its\n\
348internal counter is simply incremented. If nobody holds the lock,\n\
349the lock is taken and its internal counter initialized to 1.");
350
351static PyObject *
352rlock_release(rlockobject *self)
353{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 long tid = PyThread_get_thread_ident();
Antoine Pitrou434736a2009-11-10 18:46:01 +0000355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 if (self->rlock_count == 0 || self->rlock_owner != tid) {
357 PyErr_SetString(PyExc_RuntimeError,
358 "cannot release un-acquired lock");
359 return NULL;
360 }
361 if (--self->rlock_count == 0) {
362 self->rlock_owner = 0;
363 PyThread_release_lock(self->rlock_lock);
364 }
365 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000366}
367
368PyDoc_STRVAR(rlock_release_doc,
369"release()\n\
370\n\
371Release the lock, allowing another thread that is blocked waiting for\n\
372the lock to acquire the lock. The lock must be in the locked state,\n\
373and must be locked by the same thread that unlocks it; otherwise a\n\
374`RuntimeError` is raised.\n\
375\n\
376Do note that if the lock was acquire()d several times in a row by the\n\
377current thread, release() needs to be called as many times for the lock\n\
378to be available for other threads.");
379
380static PyObject *
381rlock_acquire_restore(rlockobject *self, PyObject *arg)
382{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000383 long owner;
384 unsigned long count;
385 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000387 if (!PyArg_ParseTuple(arg, "kl:_acquire_restore", &count, &owner))
388 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
391 Py_BEGIN_ALLOW_THREADS
392 r = PyThread_acquire_lock(self->rlock_lock, 1);
393 Py_END_ALLOW_THREADS
394 }
395 if (!r) {
396 PyErr_SetString(ThreadError, "couldn't acquire lock");
397 return NULL;
398 }
399 assert(self->rlock_count == 0);
400 self->rlock_owner = owner;
401 self->rlock_count = count;
402 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000403}
404
405PyDoc_STRVAR(rlock_acquire_restore_doc,
406"_acquire_restore(state) -> None\n\
407\n\
408For internal use by `threading.Condition`.");
409
410static PyObject *
411rlock_release_save(rlockobject *self)
412{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 long owner;
414 unsigned long count;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 owner = self->rlock_owner;
417 count = self->rlock_count;
418 self->rlock_count = 0;
419 self->rlock_owner = 0;
420 PyThread_release_lock(self->rlock_lock);
421 return Py_BuildValue("kl", count, owner);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000422}
423
424PyDoc_STRVAR(rlock_release_save_doc,
425"_release_save() -> tuple\n\
426\n\
427For internal use by `threading.Condition`.");
428
429
430static PyObject *
431rlock_is_owned(rlockobject *self)
432{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000433 long tid = PyThread_get_thread_ident();
434
435 if (self->rlock_count > 0 && self->rlock_owner == tid) {
436 Py_RETURN_TRUE;
437 }
438 Py_RETURN_FALSE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000439}
440
441PyDoc_STRVAR(rlock_is_owned_doc,
442"_is_owned() -> bool\n\
443\n\
444For internal use by `threading.Condition`.");
445
446static PyObject *
447rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
448{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 rlockobject *self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 self = (rlockobject *) type->tp_alloc(type, 0);
452 if (self != NULL) {
453 self->rlock_lock = PyThread_allocate_lock();
454 if (self->rlock_lock == NULL) {
455 type->tp_free(self);
456 PyErr_SetString(ThreadError, "can't allocate lock");
457 return NULL;
458 }
459 self->in_weakreflist = NULL;
460 self->rlock_owner = 0;
461 self->rlock_count = 0;
462 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 return (PyObject *) self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000465}
466
467static PyObject *
468rlock_repr(rlockobject *self)
469{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 return PyUnicode_FromFormat("<%s owner=%ld count=%lu>",
471 Py_TYPE(self)->tp_name, self->rlock_owner, self->rlock_count);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000472}
473
474
475static PyMethodDef rlock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 {"acquire", (PyCFunction)rlock_acquire,
477 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
478 {"release", (PyCFunction)rlock_release,
479 METH_NOARGS, rlock_release_doc},
480 {"_is_owned", (PyCFunction)rlock_is_owned,
481 METH_NOARGS, rlock_is_owned_doc},
482 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
483 METH_O, rlock_acquire_restore_doc},
484 {"_release_save", (PyCFunction)rlock_release_save,
485 METH_NOARGS, rlock_release_save_doc},
486 {"__enter__", (PyCFunction)rlock_acquire,
487 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
488 {"__exit__", (PyCFunction)rlock_release,
489 METH_VARARGS, rlock_release_doc},
490 {NULL, NULL} /* sentinel */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000491};
492
493
494static PyTypeObject RLocktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 PyVarObject_HEAD_INIT(&PyType_Type, 0)
496 "_thread.RLock", /*tp_name*/
497 sizeof(rlockobject), /*tp_size*/
498 0, /*tp_itemsize*/
499 /* methods */
500 (destructor)rlock_dealloc, /*tp_dealloc*/
501 0, /*tp_print*/
502 0, /*tp_getattr*/
503 0, /*tp_setattr*/
504 0, /*tp_reserved*/
505 (reprfunc)rlock_repr, /*tp_repr*/
506 0, /*tp_as_number*/
507 0, /*tp_as_sequence*/
508 0, /*tp_as_mapping*/
509 0, /*tp_hash*/
510 0, /*tp_call*/
511 0, /*tp_str*/
512 0, /*tp_getattro*/
513 0, /*tp_setattro*/
514 0, /*tp_as_buffer*/
515 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
516 0, /*tp_doc*/
517 0, /*tp_traverse*/
518 0, /*tp_clear*/
519 0, /*tp_richcompare*/
520 offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
521 0, /*tp_iter*/
522 0, /*tp_iternext*/
523 rlock_methods, /*tp_methods*/
524 0, /* tp_members */
525 0, /* tp_getset */
526 0, /* tp_base */
527 0, /* tp_dict */
528 0, /* tp_descr_get */
529 0, /* tp_descr_set */
530 0, /* tp_dictoffset */
531 0, /* tp_init */
532 PyType_GenericAlloc, /* tp_alloc */
533 rlock_new /* tp_new */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000534};
535
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000536static lockobject *
537newlockobject(void)
538{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 lockobject *self;
540 self = PyObject_New(lockobject, &Locktype);
541 if (self == NULL)
542 return NULL;
543 self->lock_lock = PyThread_allocate_lock();
544 self->in_weakreflist = NULL;
545 if (self->lock_lock == NULL) {
546 Py_DECREF(self);
547 PyErr_SetString(ThreadError, "can't allocate lock");
548 return NULL;
549 }
550 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000551}
552
Jim Fultond15dc062004-07-14 19:11:50 +0000553/* Thread-local objects */
554
555#include "structmember.h"
556
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000557/* Quick overview:
558
559 We need to be able to reclaim reference cycles as soon as possible
560 (both when a thread is being terminated, or a thread-local object
561 becomes unreachable from user data). Constraints:
562 - it must not be possible for thread-state dicts to be involved in
563 reference cycles (otherwise the cyclic GC will refuse to consider
564 objects referenced from a reachable thread-state dict, even though
565 local_dealloc would clear them)
566 - the death of a thread-state dict must still imply destruction of the
567 corresponding local dicts in all thread-local objects.
568
569 Our implementation uses small "localdummy" objects in order to break
570 the reference chain. These trivial objects are hashable (using the
571 default scheme of identity hashing) and weakrefable.
572 Each thread-state holds a separate localdummy for each local object
573 (as a /strong reference/),
574 and each thread-local object holds a dict mapping /weak references/
575 of localdummies to local dicts.
576
577 Therefore:
578 - only the thread-state dict holds a strong reference to the dummies
579 - only the thread-local object holds a strong reference to the local dicts
580 - only outside objects (application- or library-level) hold strong
581 references to the thread-local objects
582 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
583 dummies attached to that thread are called, and destroy the corresponding
584 local dicts from thread-local objects
585 - as soon as a thread-local object is destroyed, its local dicts are
586 destroyed and its dummies are manually removed from all thread states
587 - the GC can do its work correctly when a thread-local object is dangling,
588 without any interference from the thread-state dicts
589
590 As an additional optimization, each localdummy holds a borrowed reference
591 to the corresponding localdict. This borrowed reference is only used
592 by the thread-local object which has created the localdummy, which should
593 guarantee that the localdict still exists when accessed.
594*/
595
596typedef struct {
597 PyObject_HEAD
598 PyObject *localdict; /* Borrowed reference! */
599 PyObject *weakreflist; /* List of weak references to self */
600} localdummyobject;
601
602static void
603localdummy_dealloc(localdummyobject *self)
604{
605 if (self->weakreflist != NULL)
606 PyObject_ClearWeakRefs((PyObject *) self);
607 Py_TYPE(self)->tp_free((PyObject*)self);
608}
609
610static PyTypeObject localdummytype = {
611 PyVarObject_HEAD_INIT(NULL, 0)
612 /* tp_name */ "_thread._localdummy",
613 /* tp_basicsize */ sizeof(localdummyobject),
614 /* tp_itemsize */ 0,
615 /* tp_dealloc */ (destructor)localdummy_dealloc,
616 /* tp_print */ 0,
617 /* tp_getattr */ 0,
618 /* tp_setattr */ 0,
619 /* tp_reserved */ 0,
620 /* tp_repr */ 0,
621 /* tp_as_number */ 0,
622 /* tp_as_sequence */ 0,
623 /* tp_as_mapping */ 0,
624 /* tp_hash */ 0,
625 /* tp_call */ 0,
626 /* tp_str */ 0,
627 /* tp_getattro */ 0,
628 /* tp_setattro */ 0,
629 /* tp_as_buffer */ 0,
630 /* tp_flags */ Py_TPFLAGS_DEFAULT,
631 /* tp_doc */ "Thread-local dummy",
632 /* tp_traverse */ 0,
633 /* tp_clear */ 0,
634 /* tp_richcompare */ 0,
635 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
636};
637
638
Jim Fultond15dc062004-07-14 19:11:50 +0000639typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 PyObject_HEAD
641 PyObject *key;
642 PyObject *args;
643 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000644 PyObject *weakreflist; /* List of weak references to self */
645 /* A {localdummy weakref -> localdict} dict */
646 PyObject *dummies;
647 /* The callback for weakrefs to localdummies */
648 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000649} localobject;
650
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000651/* Forward declaration */
652static PyObject *_ldict(localobject *self);
653static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
654
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000655/* Create and register the dummy for the current thread.
656 Returns a borrowed reference of the corresponding local dict */
657static PyObject *
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000658_local_create_dummy(localobject *self)
659{
660 PyObject *tdict, *ldict = NULL, *wr = NULL;
661 localdummyobject *dummy = NULL;
662 int r;
663
664 tdict = PyThreadState_GetDict();
665 if (tdict == NULL) {
666 PyErr_SetString(PyExc_SystemError,
667 "Couldn't get thread-state dictionary");
668 goto err;
669 }
670
671 ldict = PyDict_New();
672 if (ldict == NULL)
673 goto err;
674 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
675 if (dummy == NULL)
676 goto err;
677 dummy->localdict = ldict;
678 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
679 if (wr == NULL)
680 goto err;
681
682 /* As a side-effect, this will cache the weakref's hash before the
683 dummy gets deleted */
684 r = PyDict_SetItem(self->dummies, wr, ldict);
685 if (r < 0)
686 goto err;
687 Py_CLEAR(wr);
688 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
689 if (r < 0)
690 goto err;
691 Py_CLEAR(dummy);
692
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000693 Py_DECREF(ldict);
694 return ldict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000695
696err:
697 Py_XDECREF(ldict);
698 Py_XDECREF(wr);
699 Py_XDECREF(dummy);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000700 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000701}
702
Jim Fultond15dc062004-07-14 19:11:50 +0000703static PyObject *
704local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
705{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 localobject *self;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000707 PyObject *wr;
708 static PyMethodDef wr_callback_def = {
709 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
710 };
Jim Fultond15dc062004-07-14 19:11:50 +0000711
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000712 if (type->tp_init == PyBaseObject_Type.tp_init
713 && ((args && PyObject_IsTrue(args))
714 || (kw && PyObject_IsTrue(kw)))) {
715 PyErr_SetString(PyExc_TypeError,
716 "Initialization arguments are not supported");
717 return NULL;
718 }
Jim Fultond15dc062004-07-14 19:11:50 +0000719
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 self = (localobject *)type->tp_alloc(type, 0);
721 if (self == NULL)
722 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000723
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 Py_XINCREF(args);
725 self->args = args;
726 Py_XINCREF(kw);
727 self->kw = kw;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 self->key = PyUnicode_FromFormat("thread.local.%p", self);
729 if (self->key == NULL)
730 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000731
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000732 self->dummies = PyDict_New();
733 if (self->dummies == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000735
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000736 /* We use a weak reference to self in the callback closure
737 in order to avoid spurious reference cycles */
738 wr = PyWeakref_NewRef((PyObject *) self, NULL);
739 if (wr == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 goto err;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000741 self->wr_callback = PyCFunction_New(&wr_callback_def, wr);
742 Py_DECREF(wr);
743 if (self->wr_callback == NULL)
744 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000745
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000746 if (_local_create_dummy(self) == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000749 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000750
751 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000752 Py_DECREF(self);
753 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000754}
755
756static int
757local_traverse(localobject *self, visitproc visit, void *arg)
758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 Py_VISIT(self->args);
760 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000761 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000763}
764
765static int
766local_clear(localobject *self)
767{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000768 PyThreadState *tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 Py_CLEAR(self->args);
770 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000771 Py_CLEAR(self->dummies);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000772 Py_CLEAR(self->wr_callback);
773 /* Remove all strong references to dummies from the thread states */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000774 if (self->key
775 && (tstate = PyThreadState_Get())
776 && tstate->interp) {
777 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
778 tstate;
779 tstate = PyThreadState_Next(tstate))
780 if (tstate->dict &&
781 PyDict_GetItem(tstate->dict, self->key))
782 PyDict_DelItem(tstate->dict, self->key);
783 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000784 return 0;
785}
Jim Fultond15dc062004-07-14 19:11:50 +0000786
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000787static void
788local_dealloc(localobject *self)
789{
790 /* Weakrefs must be invalidated right now, otherwise they can be used
791 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
792 if (self->weakreflist != NULL)
793 PyObject_ClearWeakRefs((PyObject *) self);
794
795 PyObject_GC_UnTrack(self);
796
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000797 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000798 Py_XDECREF(self->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000799 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000800}
801
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000802/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000803static PyObject *
804_ldict(localobject *self)
805{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000806 PyObject *tdict, *ldict, *dummy;
Jim Fultond15dc062004-07-14 19:11:50 +0000807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 tdict = PyThreadState_GetDict();
809 if (tdict == NULL) {
810 PyErr_SetString(PyExc_SystemError,
811 "Couldn't get thread-state dictionary");
812 return NULL;
813 }
Jim Fultond15dc062004-07-14 19:11:50 +0000814
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000815 dummy = PyDict_GetItem(tdict, self->key);
816 if (dummy == NULL) {
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000817 ldict = _local_create_dummy(self);
818 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000819 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000820
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000821 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
822 Py_TYPE(self)->tp_init((PyObject*)self,
823 self->args, self->kw) < 0) {
824 /* we need to get rid of ldict from thread so
825 we create a new one the next time we do an attr
Ezio Melotti42da6632011-03-15 05:18:48 +0200826 access */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000827 PyDict_DelItem(tdict, self->key);
828 return NULL;
829 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000830 }
831 else {
832 assert(Py_TYPE(dummy) == &localdummytype);
833 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000834 }
Jim Fultond15dc062004-07-14 19:11:50 +0000835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000836 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000837}
838
Jim Fultond15dc062004-07-14 19:11:50 +0000839static int
840local_setattro(localobject *self, PyObject *name, PyObject *v)
841{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 PyObject *ldict;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000843 int r;
Jim Fultond15dc062004-07-14 19:11:50 +0000844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000845 ldict = _ldict(self);
846 if (ldict == NULL)
847 return -1;
848
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000849 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
850 if (r == 1) {
851 PyErr_Format(PyExc_AttributeError,
852 "'%.50s' object attribute '%U' is read-only",
853 Py_TYPE(self)->tp_name, name);
854 return -1;
855 }
856 if (r == -1)
857 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000858
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000859 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000860}
861
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000862static PyObject *local_getattro(localobject *, PyObject *);
863
Jim Fultond15dc062004-07-14 19:11:50 +0000864static PyTypeObject localtype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 PyVarObject_HEAD_INIT(NULL, 0)
866 /* tp_name */ "_thread._local",
867 /* tp_basicsize */ sizeof(localobject),
868 /* tp_itemsize */ 0,
869 /* tp_dealloc */ (destructor)local_dealloc,
870 /* tp_print */ 0,
871 /* tp_getattr */ 0,
872 /* tp_setattr */ 0,
873 /* tp_reserved */ 0,
874 /* tp_repr */ 0,
875 /* tp_as_number */ 0,
876 /* tp_as_sequence */ 0,
877 /* tp_as_mapping */ 0,
878 /* tp_hash */ 0,
879 /* tp_call */ 0,
880 /* tp_str */ 0,
881 /* tp_getattro */ (getattrofunc)local_getattro,
882 /* tp_setattro */ (setattrofunc)local_setattro,
883 /* tp_as_buffer */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000884 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
885 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 /* tp_doc */ "Thread-local data",
887 /* tp_traverse */ (traverseproc)local_traverse,
888 /* tp_clear */ (inquiry)local_clear,
889 /* tp_richcompare */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000890 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 /* tp_iter */ 0,
892 /* tp_iternext */ 0,
893 /* tp_methods */ 0,
894 /* tp_members */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000895 /* tp_getset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000896 /* tp_base */ 0,
897 /* tp_dict */ 0, /* internal use */
898 /* tp_descr_get */ 0,
899 /* tp_descr_set */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000900 /* tp_dictoffset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 /* tp_init */ 0,
902 /* tp_alloc */ 0,
903 /* tp_new */ local_new,
904 /* tp_free */ 0, /* Low-level free-mem routine */
905 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000906};
907
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000908static PyObject *
909local_getattro(localobject *self, PyObject *name)
910{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 PyObject *ldict, *value;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000912 int r;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000914 ldict = _ldict(self);
915 if (ldict == NULL)
916 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000917
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000918 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
919 if (r == 1) {
920 Py_INCREF(ldict);
921 return ldict;
922 }
923 if (r == -1)
924 return NULL;
925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 if (Py_TYPE(self) != &localtype)
927 /* use generic lookup for subtypes */
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000928 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 /* Optimization: just look in dict ourselves */
931 value = PyDict_GetItem(ldict, name);
932 if (value == NULL)
933 /* Fall back on generic to get __class__ and __dict__ */
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000934 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000936 Py_INCREF(value);
937 return value;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000938}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000939
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000940/* Called when a dummy is destroyed. */
941static PyObject *
942_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
943{
944 PyObject *obj;
945 localobject *self;
946 assert(PyWeakref_CheckRef(localweakref));
947 obj = PyWeakref_GET_OBJECT(localweakref);
948 if (obj == Py_None)
949 Py_RETURN_NONE;
950 Py_INCREF(obj);
951 assert(PyObject_TypeCheck(obj, &localtype));
952 /* If the thread-local object is still alive and not being cleared,
953 remove the corresponding local dict */
954 self = (localobject *) obj;
955 if (self->dummies != NULL) {
956 PyObject *ldict;
957 ldict = PyDict_GetItem(self->dummies, dummyweakref);
958 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000959 PyDict_DelItem(self->dummies, dummyweakref);
960 }
961 if (PyErr_Occurred())
962 PyErr_WriteUnraisable(obj);
963 }
964 Py_DECREF(obj);
965 Py_RETURN_NONE;
966}
967
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000968/* Module functions */
969
Guido van Rossuma027efa1997-05-05 20:56:21 +0000970struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 PyInterpreterState *interp;
972 PyObject *func;
973 PyObject *args;
974 PyObject *keyw;
975 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000976};
977
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000978static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000979t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 struct bootstate *boot = (struct bootstate *) boot_raw;
982 PyThreadState *tstate;
983 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 tstate = boot->tstate;
986 tstate->thread_id = PyThread_get_thread_ident();
987 _PyThreadState_Init(tstate);
988 PyEval_AcquireThread(tstate);
989 nb_threads++;
990 res = PyEval_CallObjectWithKeywords(
991 boot->func, boot->args, boot->keyw);
992 if (res == NULL) {
993 if (PyErr_ExceptionMatches(PyExc_SystemExit))
994 PyErr_Clear();
995 else {
996 PyObject *file;
997 PySys_WriteStderr(
998 "Unhandled exception in thread started by ");
999 file = PySys_GetObject("stderr");
1000 if (file != NULL && file != Py_None)
1001 PyFile_WriteObject(boot->func, file, 0);
1002 else
1003 PyObject_Print(boot->func, stderr, 0);
1004 PySys_WriteStderr("\n");
1005 PyErr_PrintEx(0);
1006 }
1007 }
1008 else
1009 Py_DECREF(res);
1010 Py_DECREF(boot->func);
1011 Py_DECREF(boot->args);
1012 Py_XDECREF(boot->keyw);
1013 PyMem_DEL(boot_raw);
1014 nb_threads--;
1015 PyThreadState_Clear(tstate);
1016 PyThreadState_DeleteCurrent();
1017 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001018}
1019
Barry Warsawd0c10421996-12-17 00:05:22 +00001020static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001021thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001022{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 PyObject *func, *args, *keyw = NULL;
1024 struct bootstate *boot;
1025 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
1028 &func, &args, &keyw))
1029 return NULL;
1030 if (!PyCallable_Check(func)) {
1031 PyErr_SetString(PyExc_TypeError,
1032 "first arg must be callable");
1033 return NULL;
1034 }
1035 if (!PyTuple_Check(args)) {
1036 PyErr_SetString(PyExc_TypeError,
1037 "2nd arg must be a tuple");
1038 return NULL;
1039 }
1040 if (keyw != NULL && !PyDict_Check(keyw)) {
1041 PyErr_SetString(PyExc_TypeError,
1042 "optional 3rd arg must be a dictionary");
1043 return NULL;
1044 }
1045 boot = PyMem_NEW(struct bootstate, 1);
1046 if (boot == NULL)
1047 return PyErr_NoMemory();
1048 boot->interp = PyThreadState_GET()->interp;
1049 boot->func = func;
1050 boot->args = args;
1051 boot->keyw = keyw;
1052 boot->tstate = _PyThreadState_Prealloc(boot->interp);
1053 if (boot->tstate == NULL) {
1054 PyMem_DEL(boot);
1055 return PyErr_NoMemory();
1056 }
1057 Py_INCREF(func);
1058 Py_INCREF(args);
1059 Py_XINCREF(keyw);
1060 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
1061 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
1062 if (ident == -1) {
1063 PyErr_SetString(ThreadError, "can't start new thread");
1064 Py_DECREF(func);
1065 Py_DECREF(args);
1066 Py_XDECREF(keyw);
1067 PyThreadState_Clear(boot->tstate);
1068 PyMem_DEL(boot);
1069 return NULL;
1070 }
1071 return PyLong_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001072}
1073
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001074PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001075"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001076(start_new() is an obsolete synonym)\n\
1077\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001078Start a new thread and return its identifier. The thread will call the\n\
1079function with positional arguments from the tuple args and keyword arguments\n\
1080taken from the optional dictionary kwargs. The thread exits when the\n\
1081function returns; the return value is ignored. The thread will also exit\n\
1082when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001083printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001084
Barry Warsawd0c10421996-12-17 00:05:22 +00001085static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001086thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001087{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088 PyErr_SetNone(PyExc_SystemExit);
1089 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001090}
1091
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001092PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001093"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001094(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001095\n\
1096This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001097thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001098
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001099static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001100thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 PyErr_SetInterrupt();
1103 Py_INCREF(Py_None);
1104 return Py_None;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001105}
1106
1107PyDoc_STRVAR(interrupt_doc,
1108"interrupt_main()\n\
1109\n\
1110Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001111A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001112);
1113
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001114static lockobject *newlockobject(void);
1115
Barry Warsawd0c10421996-12-17 00:05:22 +00001116static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001117thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001118{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001119 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001120}
1121
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001122PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001123"allocate_lock() -> lock object\n\
1124(allocate() is an obsolete synonym)\n\
1125\n\
Alexander Belopolsky977a6842010-08-16 20:17:07 +00001126Create a new lock object. See help(LockType) for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001127
Barry Warsawd0c10421996-12-17 00:05:22 +00001128static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001129thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001130{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 long ident;
1132 ident = PyThread_get_thread_ident();
1133 if (ident == -1) {
1134 PyErr_SetString(ThreadError, "no current thread ident");
1135 return NULL;
1136 }
1137 return PyLong_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001138}
1139
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001140PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001141"get_ident() -> integer\n\
1142\n\
1143Return a non-zero integer that uniquely identifies the current thread\n\
1144amongst other threads that exist simultaneously.\n\
1145This may be used to identify per-thread resources.\n\
1146Even though on some platforms threads identities may appear to be\n\
1147allocated consecutive numbers starting at 1, this behavior should not\n\
1148be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001149A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001150
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001151static PyObject *
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001152thread__count(PyObject *self)
1153{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 return PyLong_FromLong(nb_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001155}
1156
1157PyDoc_STRVAR(_count_doc,
1158"_count() -> integer\n\
1159\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001160\
1161Return the number of currently running Python threads, excluding \n\
1162the main thread. The returned number comprises all threads created\n\
1163through `start_new_thread()` as well as `threading.Thread`, and not\n\
1164yet finished.\n\
1165\n\
1166This function is meant for internal and specialized purposes only.\n\
1167In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001168
1169static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001170thread_stack_size(PyObject *self, PyObject *args)
1171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 size_t old_size;
1173 Py_ssize_t new_size = 0;
1174 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001176 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1177 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 if (new_size < 0) {
1180 PyErr_SetString(PyExc_ValueError,
1181 "size must be 0 or a positive value");
1182 return NULL;
1183 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 rc = PyThread_set_stacksize((size_t) new_size);
1188 if (rc == -1) {
1189 PyErr_Format(PyExc_ValueError,
1190 "size not valid: %zd bytes",
1191 new_size);
1192 return NULL;
1193 }
1194 if (rc == -2) {
1195 PyErr_SetString(ThreadError,
1196 "setting stack size not supported");
1197 return NULL;
1198 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001201}
1202
1203PyDoc_STRVAR(stack_size_doc,
1204"stack_size([size]) -> size\n\
1205\n\
1206Return the thread stack size used when creating new threads. The\n\
1207optional size argument specifies the stack size (in bytes) to be used\n\
1208for subsequently created threads, and must be 0 (use platform or\n\
1209configured default) or a positive integer value of at least 32,768 (32k).\n\
1210If changing the thread stack size is unsupported, a ThreadError\n\
1211exception is raised. If the specified size is invalid, a ValueError\n\
1212exception is raised, and the stack size is unmodified. 32k bytes\n\
1213 currently the minimum supported stack size value to guarantee\n\
1214sufficient stack space for the interpreter itself.\n\
1215\n\
1216Note that some platforms may have particular restrictions on values for\n\
1217the stack size, such as requiring a minimum stack size larger than 32kB or\n\
1218requiring allocation in multiples of the system memory page size\n\
1219- platform documentation should be referred to for more information\n\
1220(4kB pages are common; using multiples of 4096 for the stack size is\n\
1221the suggested approach in the absence of more specific information).");
1222
Barry Warsawd0c10421996-12-17 00:05:22 +00001223static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
1225 METH_VARARGS,
1226 start_new_doc},
1227 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
1228 METH_VARARGS,
1229 start_new_doc},
1230 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
1231 METH_NOARGS, allocate_doc},
1232 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
1233 METH_NOARGS, allocate_doc},
1234 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
1235 METH_NOARGS, exit_doc},
1236 {"exit", (PyCFunction)thread_PyThread_exit_thread,
1237 METH_NOARGS, exit_doc},
1238 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
1239 METH_NOARGS, interrupt_doc},
1240 {"get_ident", (PyCFunction)thread_get_ident,
1241 METH_NOARGS, get_ident_doc},
1242 {"_count", (PyCFunction)thread__count,
1243 METH_NOARGS, _count_doc},
1244 {"stack_size", (PyCFunction)thread_stack_size,
1245 METH_VARARGS,
1246 stack_size_doc},
1247 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001248};
1249
1250
1251/* Initialization function */
1252
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001253PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001254"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001255The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001256
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001257PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001258"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +00001259call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001260\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001261acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1262release() -- unlock of the lock\n\
1263locked() -- test whether the lock is currently locked\n\
1264\n\
1265A lock is not owned by the thread that locked it; another thread may\n\
1266unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001267will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001268
Martin v. Löwis1a214512008-06-11 05:26:20 +00001269static struct PyModuleDef threadmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 PyModuleDef_HEAD_INIT,
1271 "_thread",
1272 thread_doc,
1273 -1,
1274 thread_methods,
1275 NULL,
1276 NULL,
1277 NULL,
1278 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001279};
1280
1281
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001282PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001283PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001284{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 PyObject *m, *d, *timeout_max;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 /* Initialize types: */
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001288 if (PyType_Ready(&localdummytype) < 0)
1289 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 if (PyType_Ready(&localtype) < 0)
1291 return NULL;
1292 if (PyType_Ready(&Locktype) < 0)
1293 return NULL;
1294 if (PyType_Ready(&RLocktype) < 0)
1295 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 /* Create the module and add the functions */
1298 m = PyModule_Create(&threadmodule);
1299 if (m == NULL)
1300 return NULL;
Antoine Pitrou7c3e5772010-04-14 15:44:10 +00001301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 timeout_max = PyFloat_FromDouble(PY_TIMEOUT_MAX / 1000000);
1303 if (!timeout_max)
1304 return NULL;
1305 if (PyModule_AddObject(m, "TIMEOUT_MAX", timeout_max) < 0)
1306 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 /* Add a symbolic constant */
1309 d = PyModule_GetDict(m);
1310 ThreadError = PyErr_NewException("_thread.error", NULL, NULL);
1311 PyDict_SetItemString(d, "error", ThreadError);
1312 Locktype.tp_doc = lock_doc;
1313 Py_INCREF(&Locktype);
1314 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Antoine Pitrou434736a2009-11-10 18:46:01 +00001315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 Py_INCREF(&RLocktype);
1317 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1318 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 Py_INCREF(&localtype);
1321 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1322 return NULL;
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 nb_threads = 0;
1325
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +00001326 str_dict = PyUnicode_InternFromString("__dict__");
1327 if (str_dict == NULL)
1328 return NULL;
1329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 /* Initialize the C thread library */
1331 PyThread_init_thread();
1332 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001333}