blob: 6e39ca047e96db3b5360570499e38acd3977d7a2 [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
Brett Cannonb94767f2011-02-22 20:15:44 +000056
Antoine Pitrou810023d2010-12-15 22:59:16 +000057 if (microseconds > 0) {
Antoine Pitrou125d5c82011-03-06 08:40:35 +010058 _PyTime_gettimeofday(&endtime);
Antoine Pitrou810023d2010-12-15 22:59:16 +000059 endtime.tv_sec += microseconds / (1000 * 1000);
60 endtime.tv_usec += microseconds % (1000 * 1000);
61 }
62
63
64 do {
65 Py_BEGIN_ALLOW_THREADS
66 r = PyThread_acquire_lock_timed(lock, microseconds, 1);
67 Py_END_ALLOW_THREADS
68
69 if (r == PY_LOCK_INTR) {
70 /* Run signal handlers if we were interrupted. Propagate
71 * exceptions from signal handlers, such as KeyboardInterrupt, by
72 * passing up PY_LOCK_INTR. */
73 if (Py_MakePendingCalls() < 0) {
74 return PY_LOCK_INTR;
75 }
76
77 /* If we're using a timeout, recompute the timeout after processing
78 * signals, since those can take time. */
Antoine Pitrou125d5c82011-03-06 08:40:35 +010079 if (microseconds > 0) {
Antoine Pitrou810023d2010-12-15 22:59:16 +000080 _PyTime_gettimeofday(&curtime);
81 microseconds = ((endtime.tv_sec - curtime.tv_sec) * 1000000 +
82 (endtime.tv_usec - curtime.tv_usec));
83
84 /* Check for negative values, since those mean block forever.
85 */
86 if (microseconds <= 0) {
87 r = PY_LOCK_FAILURE;
88 }
89 }
90 }
91 } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */
92
93 return r;
94}
95
Barry Warsawd0c10421996-12-17 00:05:22 +000096static PyObject *
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000097lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 char *kwlist[] = {"blocking", "timeout", NULL};
100 int blocking = 1;
101 double timeout = -1;
102 PY_TIMEOUT_T microseconds;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000103 PyLockStatus r;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000104
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist,
106 &blocking, &timeout))
107 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 if (!blocking && timeout != -1) {
110 PyErr_SetString(PyExc_ValueError, "can't specify a timeout "
111 "for a non-blocking call");
112 return NULL;
113 }
114 if (timeout < 0 && timeout != -1) {
115 PyErr_SetString(PyExc_ValueError, "timeout value must be "
116 "strictly positive");
117 return NULL;
118 }
119 if (!blocking)
120 microseconds = 0;
121 else if (timeout == -1)
122 microseconds = -1;
123 else {
124 timeout *= 1e6;
125 if (timeout >= (double) PY_TIMEOUT_MAX) {
126 PyErr_SetString(PyExc_OverflowError,
127 "timeout value is too large");
128 return NULL;
129 }
130 microseconds = (PY_TIMEOUT_T) timeout;
131 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000132
Antoine Pitrou810023d2010-12-15 22:59:16 +0000133 r = acquire_timed(self->lock_lock, microseconds);
134 if (r == PY_LOCK_INTR) {
135 return NULL;
136 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137
Antoine Pitrou810023d2010-12-15 22:59:16 +0000138 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000139}
140
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000141PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000142"acquire([wait]) -> None or bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000143(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000144\n\
145Lock the lock. Without argument, this blocks if the lock is already\n\
146locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000147the lock, and return None once the lock is acquired.\n\
148With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000149and the return value reflects whether the lock is acquired.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000150The blocking operation is interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000151
Barry Warsawd0c10421996-12-17 00:05:22 +0000152static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000153lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000154{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 /* Sanity check: the lock must be locked */
156 if (PyThread_acquire_lock(self->lock_lock, 0)) {
157 PyThread_release_lock(self->lock_lock);
158 PyErr_SetString(ThreadError, "release unlocked lock");
159 return NULL;
160 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 PyThread_release_lock(self->lock_lock);
163 Py_INCREF(Py_None);
164 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000165}
166
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000167PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000168"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000169(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000170\n\
171Release the lock, allowing another thread that is blocked waiting for\n\
172the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000173but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000174
Barry Warsawd0c10421996-12-17 00:05:22 +0000175static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000176lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000177{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000178 if (PyThread_acquire_lock(self->lock_lock, 0)) {
179 PyThread_release_lock(self->lock_lock);
180 return PyBool_FromLong(0L);
181 }
182 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000183}
184
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000185PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000186"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000187(locked_lock() is an obsolete synonym)\n\
188\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000189Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000190
Barry Warsawd0c10421996-12-17 00:05:22 +0000191static PyMethodDef lock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
193 METH_VARARGS | METH_KEYWORDS, acquire_doc},
194 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
195 METH_VARARGS | METH_KEYWORDS, acquire_doc},
196 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
197 METH_NOARGS, release_doc},
198 {"release", (PyCFunction)lock_PyThread_release_lock,
199 METH_NOARGS, release_doc},
200 {"locked_lock", (PyCFunction)lock_locked_lock,
201 METH_NOARGS, locked_doc},
202 {"locked", (PyCFunction)lock_locked_lock,
203 METH_NOARGS, locked_doc},
204 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
205 METH_VARARGS | METH_KEYWORDS, acquire_doc},
206 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
207 METH_VARARGS, release_doc},
208 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000209};
210
Barry Warsawd0c10421996-12-17 00:05:22 +0000211static PyTypeObject Locktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212 PyVarObject_HEAD_INIT(&PyType_Type, 0)
213 "_thread.lock", /*tp_name*/
214 sizeof(lockobject), /*tp_size*/
215 0, /*tp_itemsize*/
216 /* methods */
217 (destructor)lock_dealloc, /*tp_dealloc*/
218 0, /*tp_print*/
219 0, /*tp_getattr*/
220 0, /*tp_setattr*/
221 0, /*tp_reserved*/
222 0, /*tp_repr*/
223 0, /*tp_as_number*/
224 0, /*tp_as_sequence*/
225 0, /*tp_as_mapping*/
226 0, /*tp_hash*/
227 0, /*tp_call*/
228 0, /*tp_str*/
229 0, /*tp_getattro*/
230 0, /*tp_setattro*/
231 0, /*tp_as_buffer*/
232 Py_TPFLAGS_DEFAULT, /*tp_flags*/
233 0, /*tp_doc*/
234 0, /*tp_traverse*/
235 0, /*tp_clear*/
236 0, /*tp_richcompare*/
237 offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
238 0, /*tp_iter*/
239 0, /*tp_iternext*/
240 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000241};
242
Antoine Pitrou434736a2009-11-10 18:46:01 +0000243/* Recursive lock objects */
244
245typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 PyObject_HEAD
247 PyThread_type_lock rlock_lock;
248 long rlock_owner;
249 unsigned long rlock_count;
250 PyObject *in_weakreflist;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000251} rlockobject;
252
253static void
254rlock_dealloc(rlockobject *self)
255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 assert(self->rlock_lock);
257 if (self->in_weakreflist != NULL)
258 PyObject_ClearWeakRefs((PyObject *) self);
259 /* Unlock the lock so it's safe to free it */
260 if (self->rlock_count > 0)
261 PyThread_release_lock(self->rlock_lock);
262
263 PyThread_free_lock(self->rlock_lock);
264 Py_TYPE(self)->tp_free(self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000265}
266
267static PyObject *
268rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
269{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 char *kwlist[] = {"blocking", "timeout", NULL};
271 int blocking = 1;
272 double timeout = -1;
273 PY_TIMEOUT_T microseconds;
274 long tid;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000275 PyLockStatus r = PY_LOCK_ACQUIRED;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist,
278 &blocking, &timeout))
279 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 if (!blocking && timeout != -1) {
282 PyErr_SetString(PyExc_ValueError, "can't specify a timeout "
283 "for a non-blocking call");
284 return NULL;
285 }
286 if (timeout < 0 && timeout != -1) {
287 PyErr_SetString(PyExc_ValueError, "timeout value must be "
288 "strictly positive");
289 return NULL;
290 }
291 if (!blocking)
292 microseconds = 0;
293 else if (timeout == -1)
294 microseconds = -1;
295 else {
296 timeout *= 1e6;
297 if (timeout >= (double) PY_TIMEOUT_MAX) {
298 PyErr_SetString(PyExc_OverflowError,
299 "timeout value is too large");
300 return NULL;
301 }
302 microseconds = (PY_TIMEOUT_T) timeout;
303 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 tid = PyThread_get_thread_ident();
306 if (self->rlock_count > 0 && tid == self->rlock_owner) {
307 unsigned long count = self->rlock_count + 1;
308 if (count <= self->rlock_count) {
309 PyErr_SetString(PyExc_OverflowError,
310 "Internal lock count overflowed");
311 return NULL;
312 }
313 self->rlock_count = count;
314 Py_RETURN_TRUE;
315 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 if (self->rlock_count > 0 ||
318 !PyThread_acquire_lock(self->rlock_lock, 0)) {
319 if (microseconds == 0) {
320 Py_RETURN_FALSE;
321 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000322 r = acquire_timed(self->rlock_lock, microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000324 if (r == PY_LOCK_ACQUIRED) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 assert(self->rlock_count == 0);
326 self->rlock_owner = tid;
327 self->rlock_count = 1;
328 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000329 else if (r == PY_LOCK_INTR) {
330 return NULL;
331 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332
Antoine Pitrou810023d2010-12-15 22:59:16 +0000333 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000334}
335
336PyDoc_STRVAR(rlock_acquire_doc,
337"acquire(blocking=True) -> bool\n\
338\n\
339Lock the lock. `blocking` indicates whether we should wait\n\
340for the lock to be available or not. If `blocking` is False\n\
341and another thread holds the lock, the method will return False\n\
342immediately. If `blocking` is True and another thread holds\n\
343the lock, the method will wait for the lock to be released,\n\
344take it and then return True.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000345(note: the blocking operation is interruptible.)\n\
Antoine Pitrou434736a2009-11-10 18:46:01 +0000346\n\
347In all other cases, the method will return True immediately.\n\
348Precisely, if the current thread already holds the lock, its\n\
349internal counter is simply incremented. If nobody holds the lock,\n\
350the lock is taken and its internal counter initialized to 1.");
351
352static PyObject *
353rlock_release(rlockobject *self)
354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 long tid = PyThread_get_thread_ident();
Antoine Pitrou434736a2009-11-10 18:46:01 +0000356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 if (self->rlock_count == 0 || self->rlock_owner != tid) {
358 PyErr_SetString(PyExc_RuntimeError,
359 "cannot release un-acquired lock");
360 return NULL;
361 }
362 if (--self->rlock_count == 0) {
363 self->rlock_owner = 0;
364 PyThread_release_lock(self->rlock_lock);
365 }
366 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000367}
368
369PyDoc_STRVAR(rlock_release_doc,
370"release()\n\
371\n\
372Release the lock, allowing another thread that is blocked waiting for\n\
373the lock to acquire the lock. The lock must be in the locked state,\n\
374and must be locked by the same thread that unlocks it; otherwise a\n\
375`RuntimeError` is raised.\n\
376\n\
377Do note that if the lock was acquire()d several times in a row by the\n\
378current thread, release() needs to be called as many times for the lock\n\
379to be available for other threads.");
380
381static PyObject *
382rlock_acquire_restore(rlockobject *self, PyObject *arg)
383{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 long owner;
385 unsigned long count;
386 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 if (!PyArg_ParseTuple(arg, "kl:_acquire_restore", &count, &owner))
389 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
392 Py_BEGIN_ALLOW_THREADS
393 r = PyThread_acquire_lock(self->rlock_lock, 1);
394 Py_END_ALLOW_THREADS
395 }
396 if (!r) {
397 PyErr_SetString(ThreadError, "couldn't acquire lock");
398 return NULL;
399 }
400 assert(self->rlock_count == 0);
401 self->rlock_owner = owner;
402 self->rlock_count = count;
403 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000404}
405
406PyDoc_STRVAR(rlock_acquire_restore_doc,
407"_acquire_restore(state) -> None\n\
408\n\
409For internal use by `threading.Condition`.");
410
411static PyObject *
412rlock_release_save(rlockobject *self)
413{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 long owner;
415 unsigned long count;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000416
Victor Stinnerc2824d42011-04-24 23:41:33 +0200417 if (self->rlock_count == 0) {
418 PyErr_SetString(PyExc_RuntimeError,
419 "cannot release un-acquired lock");
420 return NULL;
421 }
422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 owner = self->rlock_owner;
424 count = self->rlock_count;
425 self->rlock_count = 0;
426 self->rlock_owner = 0;
427 PyThread_release_lock(self->rlock_lock);
428 return Py_BuildValue("kl", count, owner);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000429}
430
431PyDoc_STRVAR(rlock_release_save_doc,
432"_release_save() -> tuple\n\
433\n\
434For internal use by `threading.Condition`.");
435
436
437static PyObject *
438rlock_is_owned(rlockobject *self)
439{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000440 long tid = PyThread_get_thread_ident();
441
442 if (self->rlock_count > 0 && self->rlock_owner == tid) {
443 Py_RETURN_TRUE;
444 }
445 Py_RETURN_FALSE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000446}
447
448PyDoc_STRVAR(rlock_is_owned_doc,
449"_is_owned() -> bool\n\
450\n\
451For internal use by `threading.Condition`.");
452
453static PyObject *
454rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
455{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 rlockobject *self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 self = (rlockobject *) type->tp_alloc(type, 0);
459 if (self != NULL) {
460 self->rlock_lock = PyThread_allocate_lock();
461 if (self->rlock_lock == NULL) {
462 type->tp_free(self);
463 PyErr_SetString(ThreadError, "can't allocate lock");
464 return NULL;
465 }
466 self->in_weakreflist = NULL;
467 self->rlock_owner = 0;
468 self->rlock_count = 0;
469 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 return (PyObject *) self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000472}
473
474static PyObject *
475rlock_repr(rlockobject *self)
476{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 return PyUnicode_FromFormat("<%s owner=%ld count=%lu>",
478 Py_TYPE(self)->tp_name, self->rlock_owner, self->rlock_count);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000479}
480
481
482static PyMethodDef rlock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 {"acquire", (PyCFunction)rlock_acquire,
484 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
485 {"release", (PyCFunction)rlock_release,
486 METH_NOARGS, rlock_release_doc},
487 {"_is_owned", (PyCFunction)rlock_is_owned,
488 METH_NOARGS, rlock_is_owned_doc},
489 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
490 METH_O, rlock_acquire_restore_doc},
491 {"_release_save", (PyCFunction)rlock_release_save,
492 METH_NOARGS, rlock_release_save_doc},
493 {"__enter__", (PyCFunction)rlock_acquire,
494 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
495 {"__exit__", (PyCFunction)rlock_release,
496 METH_VARARGS, rlock_release_doc},
497 {NULL, NULL} /* sentinel */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000498};
499
500
501static PyTypeObject RLocktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 PyVarObject_HEAD_INIT(&PyType_Type, 0)
503 "_thread.RLock", /*tp_name*/
504 sizeof(rlockobject), /*tp_size*/
505 0, /*tp_itemsize*/
506 /* methods */
507 (destructor)rlock_dealloc, /*tp_dealloc*/
508 0, /*tp_print*/
509 0, /*tp_getattr*/
510 0, /*tp_setattr*/
511 0, /*tp_reserved*/
512 (reprfunc)rlock_repr, /*tp_repr*/
513 0, /*tp_as_number*/
514 0, /*tp_as_sequence*/
515 0, /*tp_as_mapping*/
516 0, /*tp_hash*/
517 0, /*tp_call*/
518 0, /*tp_str*/
519 0, /*tp_getattro*/
520 0, /*tp_setattro*/
521 0, /*tp_as_buffer*/
522 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
523 0, /*tp_doc*/
524 0, /*tp_traverse*/
525 0, /*tp_clear*/
526 0, /*tp_richcompare*/
527 offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
528 0, /*tp_iter*/
529 0, /*tp_iternext*/
530 rlock_methods, /*tp_methods*/
531 0, /* tp_members */
532 0, /* tp_getset */
533 0, /* tp_base */
534 0, /* tp_dict */
535 0, /* tp_descr_get */
536 0, /* tp_descr_set */
537 0, /* tp_dictoffset */
538 0, /* tp_init */
539 PyType_GenericAlloc, /* tp_alloc */
540 rlock_new /* tp_new */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000541};
542
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000543static lockobject *
544newlockobject(void)
545{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 lockobject *self;
547 self = PyObject_New(lockobject, &Locktype);
548 if (self == NULL)
549 return NULL;
550 self->lock_lock = PyThread_allocate_lock();
551 self->in_weakreflist = NULL;
552 if (self->lock_lock == NULL) {
553 Py_DECREF(self);
554 PyErr_SetString(ThreadError, "can't allocate lock");
555 return NULL;
556 }
557 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000558}
559
Jim Fultond15dc062004-07-14 19:11:50 +0000560/* Thread-local objects */
561
562#include "structmember.h"
563
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000564/* Quick overview:
565
566 We need to be able to reclaim reference cycles as soon as possible
567 (both when a thread is being terminated, or a thread-local object
568 becomes unreachable from user data). Constraints:
569 - it must not be possible for thread-state dicts to be involved in
570 reference cycles (otherwise the cyclic GC will refuse to consider
571 objects referenced from a reachable thread-state dict, even though
572 local_dealloc would clear them)
573 - the death of a thread-state dict must still imply destruction of the
574 corresponding local dicts in all thread-local objects.
575
576 Our implementation uses small "localdummy" objects in order to break
577 the reference chain. These trivial objects are hashable (using the
578 default scheme of identity hashing) and weakrefable.
579 Each thread-state holds a separate localdummy for each local object
580 (as a /strong reference/),
581 and each thread-local object holds a dict mapping /weak references/
582 of localdummies to local dicts.
583
584 Therefore:
585 - only the thread-state dict holds a strong reference to the dummies
586 - only the thread-local object holds a strong reference to the local dicts
587 - only outside objects (application- or library-level) hold strong
588 references to the thread-local objects
589 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
590 dummies attached to that thread are called, and destroy the corresponding
591 local dicts from thread-local objects
592 - as soon as a thread-local object is destroyed, its local dicts are
593 destroyed and its dummies are manually removed from all thread states
594 - the GC can do its work correctly when a thread-local object is dangling,
595 without any interference from the thread-state dicts
596
597 As an additional optimization, each localdummy holds a borrowed reference
598 to the corresponding localdict. This borrowed reference is only used
599 by the thread-local object which has created the localdummy, which should
600 guarantee that the localdict still exists when accessed.
601*/
602
603typedef struct {
604 PyObject_HEAD
605 PyObject *localdict; /* Borrowed reference! */
606 PyObject *weakreflist; /* List of weak references to self */
607} localdummyobject;
608
609static void
610localdummy_dealloc(localdummyobject *self)
611{
612 if (self->weakreflist != NULL)
613 PyObject_ClearWeakRefs((PyObject *) self);
614 Py_TYPE(self)->tp_free((PyObject*)self);
615}
616
617static PyTypeObject localdummytype = {
618 PyVarObject_HEAD_INIT(NULL, 0)
619 /* tp_name */ "_thread._localdummy",
620 /* tp_basicsize */ sizeof(localdummyobject),
621 /* tp_itemsize */ 0,
622 /* tp_dealloc */ (destructor)localdummy_dealloc,
623 /* tp_print */ 0,
624 /* tp_getattr */ 0,
625 /* tp_setattr */ 0,
626 /* tp_reserved */ 0,
627 /* tp_repr */ 0,
628 /* tp_as_number */ 0,
629 /* tp_as_sequence */ 0,
630 /* tp_as_mapping */ 0,
631 /* tp_hash */ 0,
632 /* tp_call */ 0,
633 /* tp_str */ 0,
634 /* tp_getattro */ 0,
635 /* tp_setattro */ 0,
636 /* tp_as_buffer */ 0,
637 /* tp_flags */ Py_TPFLAGS_DEFAULT,
638 /* tp_doc */ "Thread-local dummy",
639 /* tp_traverse */ 0,
640 /* tp_clear */ 0,
641 /* tp_richcompare */ 0,
642 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
643};
644
645
Jim Fultond15dc062004-07-14 19:11:50 +0000646typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000647 PyObject_HEAD
648 PyObject *key;
649 PyObject *args;
650 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000651 PyObject *weakreflist; /* List of weak references to self */
652 /* A {localdummy weakref -> localdict} dict */
653 PyObject *dummies;
654 /* The callback for weakrefs to localdummies */
655 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000656} localobject;
657
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000658/* Forward declaration */
659static PyObject *_ldict(localobject *self);
660static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
661
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000662/* Create and register the dummy for the current thread.
663 Returns a borrowed reference of the corresponding local dict */
664static PyObject *
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000665_local_create_dummy(localobject *self)
666{
667 PyObject *tdict, *ldict = NULL, *wr = NULL;
668 localdummyobject *dummy = NULL;
669 int r;
670
671 tdict = PyThreadState_GetDict();
672 if (tdict == NULL) {
673 PyErr_SetString(PyExc_SystemError,
674 "Couldn't get thread-state dictionary");
675 goto err;
676 }
677
678 ldict = PyDict_New();
679 if (ldict == NULL)
680 goto err;
681 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
682 if (dummy == NULL)
683 goto err;
684 dummy->localdict = ldict;
685 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
686 if (wr == NULL)
687 goto err;
688
689 /* As a side-effect, this will cache the weakref's hash before the
690 dummy gets deleted */
691 r = PyDict_SetItem(self->dummies, wr, ldict);
692 if (r < 0)
693 goto err;
694 Py_CLEAR(wr);
695 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
696 if (r < 0)
697 goto err;
698 Py_CLEAR(dummy);
699
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000700 Py_DECREF(ldict);
701 return ldict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000702
703err:
704 Py_XDECREF(ldict);
705 Py_XDECREF(wr);
706 Py_XDECREF(dummy);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000707 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000708}
709
Jim Fultond15dc062004-07-14 19:11:50 +0000710static PyObject *
711local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
712{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000713 localobject *self;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000714 PyObject *wr;
715 static PyMethodDef wr_callback_def = {
716 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
717 };
Jim Fultond15dc062004-07-14 19:11:50 +0000718
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 if (type->tp_init == PyBaseObject_Type.tp_init
720 && ((args && PyObject_IsTrue(args))
721 || (kw && PyObject_IsTrue(kw)))) {
722 PyErr_SetString(PyExc_TypeError,
723 "Initialization arguments are not supported");
724 return NULL;
725 }
Jim Fultond15dc062004-07-14 19:11:50 +0000726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727 self = (localobject *)type->tp_alloc(type, 0);
728 if (self == NULL)
729 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000730
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 Py_XINCREF(args);
732 self->args = args;
733 Py_XINCREF(kw);
734 self->kw = kw;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 self->key = PyUnicode_FromFormat("thread.local.%p", self);
736 if (self->key == NULL)
737 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000738
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000739 self->dummies = PyDict_New();
740 if (self->dummies == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000742
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000743 /* We use a weak reference to self in the callback closure
744 in order to avoid spurious reference cycles */
745 wr = PyWeakref_NewRef((PyObject *) self, NULL);
746 if (wr == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 goto err;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000748 self->wr_callback = PyCFunction_New(&wr_callback_def, wr);
749 Py_DECREF(wr);
750 if (self->wr_callback == NULL)
751 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000752
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000753 if (_local_create_dummy(self) == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000756 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000757
758 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 Py_DECREF(self);
760 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000761}
762
763static int
764local_traverse(localobject *self, visitproc visit, void *arg)
765{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000766 Py_VISIT(self->args);
767 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000768 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000770}
771
772static int
773local_clear(localobject *self)
774{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000775 PyThreadState *tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 Py_CLEAR(self->args);
777 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000778 Py_CLEAR(self->dummies);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000779 Py_CLEAR(self->wr_callback);
780 /* Remove all strong references to dummies from the thread states */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000781 if (self->key
782 && (tstate = PyThreadState_Get())
783 && tstate->interp) {
784 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
785 tstate;
786 tstate = PyThreadState_Next(tstate))
787 if (tstate->dict &&
788 PyDict_GetItem(tstate->dict, self->key))
789 PyDict_DelItem(tstate->dict, self->key);
790 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000791 return 0;
792}
Jim Fultond15dc062004-07-14 19:11:50 +0000793
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000794static void
795local_dealloc(localobject *self)
796{
797 /* Weakrefs must be invalidated right now, otherwise they can be used
798 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
799 if (self->weakreflist != NULL)
800 PyObject_ClearWeakRefs((PyObject *) self);
801
802 PyObject_GC_UnTrack(self);
803
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000804 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000805 Py_XDECREF(self->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000806 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000807}
808
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000809/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000810static PyObject *
811_ldict(localobject *self)
812{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000813 PyObject *tdict, *ldict, *dummy;
Jim Fultond15dc062004-07-14 19:11:50 +0000814
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000815 tdict = PyThreadState_GetDict();
816 if (tdict == NULL) {
817 PyErr_SetString(PyExc_SystemError,
818 "Couldn't get thread-state dictionary");
819 return NULL;
820 }
Jim Fultond15dc062004-07-14 19:11:50 +0000821
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000822 dummy = PyDict_GetItem(tdict, self->key);
823 if (dummy == NULL) {
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000824 ldict = _local_create_dummy(self);
825 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000828 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
829 Py_TYPE(self)->tp_init((PyObject*)self,
830 self->args, self->kw) < 0) {
831 /* we need to get rid of ldict from thread so
832 we create a new one the next time we do an attr
Ezio Melotti42da6632011-03-15 05:18:48 +0200833 access */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000834 PyDict_DelItem(tdict, self->key);
835 return NULL;
836 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000837 }
838 else {
839 assert(Py_TYPE(dummy) == &localdummytype);
840 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 }
Jim Fultond15dc062004-07-14 19:11:50 +0000842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000843 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000844}
845
Jim Fultond15dc062004-07-14 19:11:50 +0000846static int
847local_setattro(localobject *self, PyObject *name, PyObject *v)
848{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000849 PyObject *ldict;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000850 int r;
Jim Fultond15dc062004-07-14 19:11:50 +0000851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000852 ldict = _ldict(self);
853 if (ldict == NULL)
854 return -1;
855
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000856 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
857 if (r == 1) {
858 PyErr_Format(PyExc_AttributeError,
859 "'%.50s' object attribute '%U' is read-only",
860 Py_TYPE(self)->tp_name, name);
861 return -1;
862 }
863 if (r == -1)
864 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000865
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000866 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000867}
868
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000869static PyObject *local_getattro(localobject *, PyObject *);
870
Jim Fultond15dc062004-07-14 19:11:50 +0000871static PyTypeObject localtype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000872 PyVarObject_HEAD_INIT(NULL, 0)
873 /* tp_name */ "_thread._local",
874 /* tp_basicsize */ sizeof(localobject),
875 /* tp_itemsize */ 0,
876 /* tp_dealloc */ (destructor)local_dealloc,
877 /* tp_print */ 0,
878 /* tp_getattr */ 0,
879 /* tp_setattr */ 0,
880 /* tp_reserved */ 0,
881 /* tp_repr */ 0,
882 /* tp_as_number */ 0,
883 /* tp_as_sequence */ 0,
884 /* tp_as_mapping */ 0,
885 /* tp_hash */ 0,
886 /* tp_call */ 0,
887 /* tp_str */ 0,
888 /* tp_getattro */ (getattrofunc)local_getattro,
889 /* tp_setattro */ (setattrofunc)local_setattro,
890 /* tp_as_buffer */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000891 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
892 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000893 /* tp_doc */ "Thread-local data",
894 /* tp_traverse */ (traverseproc)local_traverse,
895 /* tp_clear */ (inquiry)local_clear,
896 /* tp_richcompare */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000897 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 /* tp_iter */ 0,
899 /* tp_iternext */ 0,
900 /* tp_methods */ 0,
901 /* tp_members */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000902 /* tp_getset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 /* tp_base */ 0,
904 /* tp_dict */ 0, /* internal use */
905 /* tp_descr_get */ 0,
906 /* tp_descr_set */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000907 /* tp_dictoffset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000908 /* tp_init */ 0,
909 /* tp_alloc */ 0,
910 /* tp_new */ local_new,
911 /* tp_free */ 0, /* Low-level free-mem routine */
912 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000913};
914
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000915static PyObject *
916local_getattro(localobject *self, PyObject *name)
917{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000918 PyObject *ldict, *value;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000919 int r;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000920
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 ldict = _ldict(self);
922 if (ldict == NULL)
923 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000924
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000925 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
926 if (r == 1) {
927 Py_INCREF(ldict);
928 return ldict;
929 }
930 if (r == -1)
931 return NULL;
932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 if (Py_TYPE(self) != &localtype)
934 /* use generic lookup for subtypes */
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000935 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000937 /* Optimization: just look in dict ourselves */
938 value = PyDict_GetItem(ldict, name);
939 if (value == NULL)
940 /* Fall back on generic to get __class__ and __dict__ */
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000941 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 Py_INCREF(value);
944 return value;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000945}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000946
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000947/* Called when a dummy is destroyed. */
948static PyObject *
949_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
950{
951 PyObject *obj;
952 localobject *self;
953 assert(PyWeakref_CheckRef(localweakref));
954 obj = PyWeakref_GET_OBJECT(localweakref);
955 if (obj == Py_None)
956 Py_RETURN_NONE;
957 Py_INCREF(obj);
958 assert(PyObject_TypeCheck(obj, &localtype));
959 /* If the thread-local object is still alive and not being cleared,
960 remove the corresponding local dict */
961 self = (localobject *) obj;
962 if (self->dummies != NULL) {
963 PyObject *ldict;
964 ldict = PyDict_GetItem(self->dummies, dummyweakref);
965 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000966 PyDict_DelItem(self->dummies, dummyweakref);
967 }
968 if (PyErr_Occurred())
969 PyErr_WriteUnraisable(obj);
970 }
971 Py_DECREF(obj);
972 Py_RETURN_NONE;
973}
974
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000975/* Module functions */
976
Guido van Rossuma027efa1997-05-05 20:56:21 +0000977struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 PyInterpreterState *interp;
979 PyObject *func;
980 PyObject *args;
981 PyObject *keyw;
982 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000983};
984
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000985static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000986t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000987{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 struct bootstate *boot = (struct bootstate *) boot_raw;
989 PyThreadState *tstate;
990 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000992 tstate = boot->tstate;
993 tstate->thread_id = PyThread_get_thread_ident();
994 _PyThreadState_Init(tstate);
995 PyEval_AcquireThread(tstate);
996 nb_threads++;
997 res = PyEval_CallObjectWithKeywords(
998 boot->func, boot->args, boot->keyw);
999 if (res == NULL) {
1000 if (PyErr_ExceptionMatches(PyExc_SystemExit))
1001 PyErr_Clear();
1002 else {
1003 PyObject *file;
1004 PySys_WriteStderr(
1005 "Unhandled exception in thread started by ");
1006 file = PySys_GetObject("stderr");
1007 if (file != NULL && file != Py_None)
1008 PyFile_WriteObject(boot->func, file, 0);
1009 else
1010 PyObject_Print(boot->func, stderr, 0);
1011 PySys_WriteStderr("\n");
1012 PyErr_PrintEx(0);
1013 }
1014 }
1015 else
1016 Py_DECREF(res);
1017 Py_DECREF(boot->func);
1018 Py_DECREF(boot->args);
1019 Py_XDECREF(boot->keyw);
1020 PyMem_DEL(boot_raw);
1021 nb_threads--;
1022 PyThreadState_Clear(tstate);
1023 PyThreadState_DeleteCurrent();
1024 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001025}
1026
Barry Warsawd0c10421996-12-17 00:05:22 +00001027static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001028thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001029{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 PyObject *func, *args, *keyw = NULL;
1031 struct bootstate *boot;
1032 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
1035 &func, &args, &keyw))
1036 return NULL;
1037 if (!PyCallable_Check(func)) {
1038 PyErr_SetString(PyExc_TypeError,
1039 "first arg must be callable");
1040 return NULL;
1041 }
1042 if (!PyTuple_Check(args)) {
1043 PyErr_SetString(PyExc_TypeError,
1044 "2nd arg must be a tuple");
1045 return NULL;
1046 }
1047 if (keyw != NULL && !PyDict_Check(keyw)) {
1048 PyErr_SetString(PyExc_TypeError,
1049 "optional 3rd arg must be a dictionary");
1050 return NULL;
1051 }
1052 boot = PyMem_NEW(struct bootstate, 1);
1053 if (boot == NULL)
1054 return PyErr_NoMemory();
1055 boot->interp = PyThreadState_GET()->interp;
1056 boot->func = func;
1057 boot->args = args;
1058 boot->keyw = keyw;
1059 boot->tstate = _PyThreadState_Prealloc(boot->interp);
1060 if (boot->tstate == NULL) {
1061 PyMem_DEL(boot);
1062 return PyErr_NoMemory();
1063 }
1064 Py_INCREF(func);
1065 Py_INCREF(args);
1066 Py_XINCREF(keyw);
1067 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
1068 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
1069 if (ident == -1) {
1070 PyErr_SetString(ThreadError, "can't start new thread");
1071 Py_DECREF(func);
1072 Py_DECREF(args);
1073 Py_XDECREF(keyw);
1074 PyThreadState_Clear(boot->tstate);
1075 PyMem_DEL(boot);
1076 return NULL;
1077 }
1078 return PyLong_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001079}
1080
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001081PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001082"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001083(start_new() is an obsolete synonym)\n\
1084\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001085Start a new thread and return its identifier. The thread will call the\n\
1086function with positional arguments from the tuple args and keyword arguments\n\
1087taken from the optional dictionary kwargs. The thread exits when the\n\
1088function returns; the return value is ignored. The thread will also exit\n\
1089when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001090printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001091
Barry Warsawd0c10421996-12-17 00:05:22 +00001092static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001093thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001094{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 PyErr_SetNone(PyExc_SystemExit);
1096 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001097}
1098
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001099PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001100"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001101(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001102\n\
1103This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001104thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001105
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001106static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001107thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001108{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001109 PyErr_SetInterrupt();
1110 Py_INCREF(Py_None);
1111 return Py_None;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001112}
1113
1114PyDoc_STRVAR(interrupt_doc,
1115"interrupt_main()\n\
1116\n\
1117Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001118A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001119);
1120
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001121static lockobject *newlockobject(void);
1122
Barry Warsawd0c10421996-12-17 00:05:22 +00001123static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001124thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001125{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001126 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001127}
1128
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001129PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001130"allocate_lock() -> lock object\n\
1131(allocate() is an obsolete synonym)\n\
1132\n\
Alexander Belopolsky977a6842010-08-16 20:17:07 +00001133Create a new lock object. See help(LockType) for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001134
Barry Warsawd0c10421996-12-17 00:05:22 +00001135static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001136thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001137{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 long ident;
1139 ident = PyThread_get_thread_ident();
1140 if (ident == -1) {
1141 PyErr_SetString(ThreadError, "no current thread ident");
1142 return NULL;
1143 }
1144 return PyLong_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001145}
1146
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001147PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001148"get_ident() -> integer\n\
1149\n\
1150Return a non-zero integer that uniquely identifies the current thread\n\
1151amongst other threads that exist simultaneously.\n\
1152This may be used to identify per-thread resources.\n\
1153Even though on some platforms threads identities may appear to be\n\
1154allocated consecutive numbers starting at 1, this behavior should not\n\
1155be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001156A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001157
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001158static PyObject *
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001159thread__count(PyObject *self)
1160{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 return PyLong_FromLong(nb_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001162}
1163
1164PyDoc_STRVAR(_count_doc,
1165"_count() -> integer\n\
1166\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001167\
1168Return the number of currently running Python threads, excluding \n\
1169the main thread. The returned number comprises all threads created\n\
1170through `start_new_thread()` as well as `threading.Thread`, and not\n\
1171yet finished.\n\
1172\n\
1173This function is meant for internal and specialized purposes only.\n\
1174In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001175
1176static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001177thread_stack_size(PyObject *self, PyObject *args)
1178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 size_t old_size;
1180 Py_ssize_t new_size = 0;
1181 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1184 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 if (new_size < 0) {
1187 PyErr_SetString(PyExc_ValueError,
1188 "size must be 0 or a positive value");
1189 return NULL;
1190 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 rc = PyThread_set_stacksize((size_t) new_size);
1195 if (rc == -1) {
1196 PyErr_Format(PyExc_ValueError,
1197 "size not valid: %zd bytes",
1198 new_size);
1199 return NULL;
1200 }
1201 if (rc == -2) {
1202 PyErr_SetString(ThreadError,
1203 "setting stack size not supported");
1204 return NULL;
1205 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001208}
1209
1210PyDoc_STRVAR(stack_size_doc,
1211"stack_size([size]) -> size\n\
1212\n\
1213Return the thread stack size used when creating new threads. The\n\
1214optional size argument specifies the stack size (in bytes) to be used\n\
1215for subsequently created threads, and must be 0 (use platform or\n\
1216configured default) or a positive integer value of at least 32,768 (32k).\n\
1217If changing the thread stack size is unsupported, a ThreadError\n\
1218exception is raised. If the specified size is invalid, a ValueError\n\
1219exception is raised, and the stack size is unmodified. 32k bytes\n\
1220 currently the minimum supported stack size value to guarantee\n\
1221sufficient stack space for the interpreter itself.\n\
1222\n\
1223Note that some platforms may have particular restrictions on values for\n\
1224the stack size, such as requiring a minimum stack size larger than 32kB or\n\
1225requiring allocation in multiples of the system memory page size\n\
1226- platform documentation should be referred to for more information\n\
1227(4kB pages are common; using multiples of 4096 for the stack size is\n\
1228the suggested approach in the absence of more specific information).");
1229
Barry Warsawd0c10421996-12-17 00:05:22 +00001230static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001232 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001234 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
1236 METH_NOARGS, allocate_doc},
1237 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
1238 METH_NOARGS, allocate_doc},
1239 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
1240 METH_NOARGS, exit_doc},
1241 {"exit", (PyCFunction)thread_PyThread_exit_thread,
1242 METH_NOARGS, exit_doc},
1243 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
1244 METH_NOARGS, interrupt_doc},
1245 {"get_ident", (PyCFunction)thread_get_ident,
1246 METH_NOARGS, get_ident_doc},
1247 {"_count", (PyCFunction)thread__count,
1248 METH_NOARGS, _count_doc},
1249 {"stack_size", (PyCFunction)thread_stack_size,
Victor Stinner754851f2011-04-19 23:58:51 +02001250 METH_VARARGS, stack_size_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001252};
1253
1254
1255/* Initialization function */
1256
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001257PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001258"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001259The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001260
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001261PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001262"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +00001263call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001264\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001265acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1266release() -- unlock of the lock\n\
1267locked() -- test whether the lock is currently locked\n\
1268\n\
1269A lock is not owned by the thread that locked it; another thread may\n\
1270unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001271will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001272
Martin v. Löwis1a214512008-06-11 05:26:20 +00001273static struct PyModuleDef threadmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 PyModuleDef_HEAD_INIT,
1275 "_thread",
1276 thread_doc,
1277 -1,
1278 thread_methods,
1279 NULL,
1280 NULL,
1281 NULL,
1282 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001283};
1284
1285
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001286PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001287PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001288{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 PyObject *m, *d, *timeout_max;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 /* Initialize types: */
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001292 if (PyType_Ready(&localdummytype) < 0)
1293 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 if (PyType_Ready(&localtype) < 0)
1295 return NULL;
1296 if (PyType_Ready(&Locktype) < 0)
1297 return NULL;
1298 if (PyType_Ready(&RLocktype) < 0)
1299 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 /* Create the module and add the functions */
1302 m = PyModule_Create(&threadmodule);
1303 if (m == NULL)
1304 return NULL;
Antoine Pitrou7c3e5772010-04-14 15:44:10 +00001305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 timeout_max = PyFloat_FromDouble(PY_TIMEOUT_MAX / 1000000);
1307 if (!timeout_max)
1308 return NULL;
1309 if (PyModule_AddObject(m, "TIMEOUT_MAX", timeout_max) < 0)
1310 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 /* Add a symbolic constant */
1313 d = PyModule_GetDict(m);
Antoine Pitroufcf81fd2011-02-28 22:03:34 +00001314 ThreadError = PyExc_RuntimeError;
1315 Py_INCREF(ThreadError);
Victor Stinner754851f2011-04-19 23:58:51 +02001316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 PyDict_SetItemString(d, "error", ThreadError);
1318 Locktype.tp_doc = lock_doc;
1319 Py_INCREF(&Locktype);
1320 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Antoine Pitrou434736a2009-11-10 18:46:01 +00001321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 Py_INCREF(&RLocktype);
1323 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1324 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 Py_INCREF(&localtype);
1327 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1328 return NULL;
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 nb_threads = 0;
1331
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +00001332 str_dict = PyUnicode_InternFromString("__dict__");
1333 if (str_dict == NULL)
1334 return NULL;
1335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 /* Initialize the C thread library */
1337 PyThread_init_thread();
1338 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001339}