blob: cbb29014b5d8d3dbd5c9095739aeb7a09bd80693 [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;
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000026 char locked; /* for sanity checking */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000027} lockobject;
28
Guido van Rossum1984f1e1992-08-04 12:41:02 +000029static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000030lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000031{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000032 if (self->in_weakreflist != NULL)
33 PyObject_ClearWeakRefs((PyObject *) self);
34 if (self->lock_lock != NULL) {
35 /* Unlock the lock so it's safe to free it */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000036 if (self->locked)
37 PyThread_release_lock(self->lock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000038 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 {
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000065 /* first a simple non-blocking try without releasing the GIL */
66 r = PyThread_acquire_lock_timed(lock, 0, 0);
67 if (r == PY_LOCK_FAILURE && microseconds != 0) {
68 Py_BEGIN_ALLOW_THREADS
69 r = PyThread_acquire_lock_timed(lock, microseconds, 1);
70 Py_END_ALLOW_THREADS
71 }
Antoine Pitrou810023d2010-12-15 22:59:16 +000072
73 if (r == PY_LOCK_INTR) {
74 /* Run signal handlers if we were interrupted. Propagate
75 * exceptions from signal handlers, such as KeyboardInterrupt, by
76 * passing up PY_LOCK_INTR. */
77 if (Py_MakePendingCalls() < 0) {
78 return PY_LOCK_INTR;
79 }
80
81 /* If we're using a timeout, recompute the timeout after processing
82 * signals, since those can take time. */
Antoine Pitrou125d5c82011-03-06 08:40:35 +010083 if (microseconds > 0) {
Antoine Pitrou810023d2010-12-15 22:59:16 +000084 _PyTime_gettimeofday(&curtime);
85 microseconds = ((endtime.tv_sec - curtime.tv_sec) * 1000000 +
86 (endtime.tv_usec - curtime.tv_usec));
87
88 /* Check for negative values, since those mean block forever.
89 */
90 if (microseconds <= 0) {
91 r = PY_LOCK_FAILURE;
92 }
93 }
94 }
95 } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */
96
97 return r;
98}
99
Barry Warsawd0c10421996-12-17 00:05:22 +0000100static PyObject *
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000101lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000102{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000103 char *kwlist[] = {"blocking", "timeout", NULL};
104 int blocking = 1;
105 double timeout = -1;
106 PY_TIMEOUT_T microseconds;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000107 PyLockStatus r;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist,
110 &blocking, &timeout))
111 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 if (!blocking && timeout != -1) {
114 PyErr_SetString(PyExc_ValueError, "can't specify a timeout "
115 "for a non-blocking call");
116 return NULL;
117 }
118 if (timeout < 0 && timeout != -1) {
119 PyErr_SetString(PyExc_ValueError, "timeout value must be "
120 "strictly positive");
121 return NULL;
122 }
123 if (!blocking)
124 microseconds = 0;
125 else if (timeout == -1)
126 microseconds = -1;
127 else {
128 timeout *= 1e6;
129 if (timeout >= (double) PY_TIMEOUT_MAX) {
130 PyErr_SetString(PyExc_OverflowError,
131 "timeout value is too large");
132 return NULL;
133 }
134 microseconds = (PY_TIMEOUT_T) timeout;
135 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000136
Antoine Pitrou810023d2010-12-15 22:59:16 +0000137 r = acquire_timed(self->lock_lock, microseconds);
138 if (r == PY_LOCK_INTR) {
139 return NULL;
140 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000141
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000142 if (r == PY_LOCK_ACQUIRED)
143 self->locked = 1;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000144 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000145}
146
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000147PyDoc_STRVAR(acquire_doc,
R David Murray95b71102013-02-04 10:15:58 -0500148"acquire([wait]) -> bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000149(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000150\n\
151Lock the lock. Without argument, this blocks if the lock is already\n\
152locked (even by the same thread), waiting for another thread to release\n\
R David Murray95b71102013-02-04 10:15:58 -0500153the lock, and return True once the lock is acquired.\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000154With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000155and the return value reflects whether the lock is acquired.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000156The blocking operation is interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000157
Barry Warsawd0c10421996-12-17 00:05:22 +0000158static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000159lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000160{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000161 /* Sanity check: the lock must be locked */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000162 if (!self->locked) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 PyErr_SetString(ThreadError, "release unlocked lock");
164 return NULL;
165 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 PyThread_release_lock(self->lock_lock);
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000168 self->locked = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 Py_INCREF(Py_None);
170 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000171}
172
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000173PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000174"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000175(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000176\n\
177Release the lock, allowing another thread that is blocked waiting for\n\
178the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000179but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000180
Barry Warsawd0c10421996-12-17 00:05:22 +0000181static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000182lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000183{
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000184 return PyBool_FromLong((long)self->locked);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000185}
186
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000187PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000188"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000189(locked_lock() is an obsolete synonym)\n\
190\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000191Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000192
Barry Warsawd0c10421996-12-17 00:05:22 +0000193static PyMethodDef lock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
195 METH_VARARGS | METH_KEYWORDS, acquire_doc},
196 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
197 METH_VARARGS | METH_KEYWORDS, acquire_doc},
198 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
199 METH_NOARGS, release_doc},
200 {"release", (PyCFunction)lock_PyThread_release_lock,
201 METH_NOARGS, release_doc},
202 {"locked_lock", (PyCFunction)lock_locked_lock,
203 METH_NOARGS, locked_doc},
204 {"locked", (PyCFunction)lock_locked_lock,
205 METH_NOARGS, locked_doc},
206 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
207 METH_VARARGS | METH_KEYWORDS, acquire_doc},
208 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
209 METH_VARARGS, release_doc},
210 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000211};
212
Barry Warsawd0c10421996-12-17 00:05:22 +0000213static PyTypeObject Locktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 PyVarObject_HEAD_INIT(&PyType_Type, 0)
215 "_thread.lock", /*tp_name*/
216 sizeof(lockobject), /*tp_size*/
217 0, /*tp_itemsize*/
218 /* methods */
219 (destructor)lock_dealloc, /*tp_dealloc*/
220 0, /*tp_print*/
221 0, /*tp_getattr*/
222 0, /*tp_setattr*/
223 0, /*tp_reserved*/
224 0, /*tp_repr*/
225 0, /*tp_as_number*/
226 0, /*tp_as_sequence*/
227 0, /*tp_as_mapping*/
228 0, /*tp_hash*/
229 0, /*tp_call*/
230 0, /*tp_str*/
231 0, /*tp_getattro*/
232 0, /*tp_setattro*/
233 0, /*tp_as_buffer*/
234 Py_TPFLAGS_DEFAULT, /*tp_flags*/
235 0, /*tp_doc*/
236 0, /*tp_traverse*/
237 0, /*tp_clear*/
238 0, /*tp_richcompare*/
239 offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
240 0, /*tp_iter*/
241 0, /*tp_iternext*/
242 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000243};
244
Antoine Pitrou434736a2009-11-10 18:46:01 +0000245/* Recursive lock objects */
246
247typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 PyObject_HEAD
249 PyThread_type_lock rlock_lock;
250 long rlock_owner;
251 unsigned long rlock_count;
252 PyObject *in_weakreflist;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000253} rlockobject;
254
255static void
256rlock_dealloc(rlockobject *self)
257{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258 assert(self->rlock_lock);
259 if (self->in_weakreflist != NULL)
260 PyObject_ClearWeakRefs((PyObject *) self);
261 /* Unlock the lock so it's safe to free it */
262 if (self->rlock_count > 0)
263 PyThread_release_lock(self->rlock_lock);
264
265 PyThread_free_lock(self->rlock_lock);
266 Py_TYPE(self)->tp_free(self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000267}
268
269static PyObject *
270rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
271{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000272 char *kwlist[] = {"blocking", "timeout", NULL};
273 int blocking = 1;
274 double timeout = -1;
275 PY_TIMEOUT_T microseconds;
276 long tid;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000277 PyLockStatus r = PY_LOCK_ACQUIRED;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist,
280 &blocking, &timeout))
281 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 if (!blocking && timeout != -1) {
284 PyErr_SetString(PyExc_ValueError, "can't specify a timeout "
285 "for a non-blocking call");
286 return NULL;
287 }
288 if (timeout < 0 && timeout != -1) {
289 PyErr_SetString(PyExc_ValueError, "timeout value must be "
290 "strictly positive");
291 return NULL;
292 }
293 if (!blocking)
294 microseconds = 0;
295 else if (timeout == -1)
296 microseconds = -1;
297 else {
298 timeout *= 1e6;
299 if (timeout >= (double) PY_TIMEOUT_MAX) {
300 PyErr_SetString(PyExc_OverflowError,
301 "timeout value is too large");
302 return NULL;
303 }
304 microseconds = (PY_TIMEOUT_T) timeout;
305 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 tid = PyThread_get_thread_ident();
308 if (self->rlock_count > 0 && tid == self->rlock_owner) {
309 unsigned long count = self->rlock_count + 1;
310 if (count <= self->rlock_count) {
311 PyErr_SetString(PyExc_OverflowError,
312 "Internal lock count overflowed");
313 return NULL;
314 }
315 self->rlock_count = count;
316 Py_RETURN_TRUE;
317 }
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000318 r = acquire_timed(self->rlock_lock, microseconds);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000319 if (r == PY_LOCK_ACQUIRED) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 assert(self->rlock_count == 0);
321 self->rlock_owner = tid;
322 self->rlock_count = 1;
323 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000324 else if (r == PY_LOCK_INTR) {
325 return NULL;
326 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327
Antoine Pitrou810023d2010-12-15 22:59:16 +0000328 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000329}
330
331PyDoc_STRVAR(rlock_acquire_doc,
332"acquire(blocking=True) -> bool\n\
333\n\
334Lock the lock. `blocking` indicates whether we should wait\n\
335for the lock to be available or not. If `blocking` is False\n\
336and another thread holds the lock, the method will return False\n\
337immediately. If `blocking` is True and another thread holds\n\
338the lock, the method will wait for the lock to be released,\n\
339take it and then return True.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000340(note: the blocking operation is interruptible.)\n\
Antoine Pitrou434736a2009-11-10 18:46:01 +0000341\n\
342In all other cases, the method will return True immediately.\n\
343Precisely, if the current thread already holds the lock, its\n\
344internal counter is simply incremented. If nobody holds the lock,\n\
345the lock is taken and its internal counter initialized to 1.");
346
347static PyObject *
348rlock_release(rlockobject *self)
349{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 long tid = PyThread_get_thread_ident();
Antoine Pitrou434736a2009-11-10 18:46:01 +0000351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 if (self->rlock_count == 0 || self->rlock_owner != tid) {
353 PyErr_SetString(PyExc_RuntimeError,
354 "cannot release un-acquired lock");
355 return NULL;
356 }
357 if (--self->rlock_count == 0) {
358 self->rlock_owner = 0;
359 PyThread_release_lock(self->rlock_lock);
360 }
361 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000362}
363
364PyDoc_STRVAR(rlock_release_doc,
365"release()\n\
366\n\
367Release the lock, allowing another thread that is blocked waiting for\n\
368the lock to acquire the lock. The lock must be in the locked state,\n\
369and must be locked by the same thread that unlocks it; otherwise a\n\
370`RuntimeError` is raised.\n\
371\n\
372Do note that if the lock was acquire()d several times in a row by the\n\
373current thread, release() needs to be called as many times for the lock\n\
374to be available for other threads.");
375
376static PyObject *
377rlock_acquire_restore(rlockobject *self, PyObject *arg)
378{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 long owner;
380 unsigned long count;
381 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000383 if (!PyArg_ParseTuple(arg, "kl:_acquire_restore", &count, &owner))
384 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
387 Py_BEGIN_ALLOW_THREADS
388 r = PyThread_acquire_lock(self->rlock_lock, 1);
389 Py_END_ALLOW_THREADS
390 }
391 if (!r) {
392 PyErr_SetString(ThreadError, "couldn't acquire lock");
393 return NULL;
394 }
395 assert(self->rlock_count == 0);
396 self->rlock_owner = owner;
397 self->rlock_count = count;
398 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000399}
400
401PyDoc_STRVAR(rlock_acquire_restore_doc,
402"_acquire_restore(state) -> None\n\
403\n\
404For internal use by `threading.Condition`.");
405
406static PyObject *
407rlock_release_save(rlockobject *self)
408{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 long owner;
410 unsigned long count;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000411
Victor Stinnerc2824d42011-04-24 23:41:33 +0200412 if (self->rlock_count == 0) {
413 PyErr_SetString(PyExc_RuntimeError,
414 "cannot release un-acquired lock");
415 return NULL;
416 }
417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 owner = self->rlock_owner;
419 count = self->rlock_count;
420 self->rlock_count = 0;
421 self->rlock_owner = 0;
422 PyThread_release_lock(self->rlock_lock);
423 return Py_BuildValue("kl", count, owner);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000424}
425
426PyDoc_STRVAR(rlock_release_save_doc,
427"_release_save() -> tuple\n\
428\n\
429For internal use by `threading.Condition`.");
430
431
432static PyObject *
433rlock_is_owned(rlockobject *self)
434{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 long tid = PyThread_get_thread_ident();
436
437 if (self->rlock_count > 0 && self->rlock_owner == tid) {
438 Py_RETURN_TRUE;
439 }
440 Py_RETURN_FALSE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000441}
442
443PyDoc_STRVAR(rlock_is_owned_doc,
444"_is_owned() -> bool\n\
445\n\
446For internal use by `threading.Condition`.");
447
448static PyObject *
449rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
450{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 rlockobject *self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 self = (rlockobject *) type->tp_alloc(type, 0);
454 if (self != NULL) {
455 self->rlock_lock = PyThread_allocate_lock();
456 if (self->rlock_lock == NULL) {
457 type->tp_free(self);
458 PyErr_SetString(ThreadError, "can't allocate lock");
459 return NULL;
460 }
461 self->in_weakreflist = NULL;
462 self->rlock_owner = 0;
463 self->rlock_count = 0;
464 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 return (PyObject *) self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000467}
468
469static PyObject *
470rlock_repr(rlockobject *self)
471{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 return PyUnicode_FromFormat("<%s owner=%ld count=%lu>",
473 Py_TYPE(self)->tp_name, self->rlock_owner, self->rlock_count);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000474}
475
476
477static PyMethodDef rlock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 {"acquire", (PyCFunction)rlock_acquire,
479 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
480 {"release", (PyCFunction)rlock_release,
481 METH_NOARGS, rlock_release_doc},
482 {"_is_owned", (PyCFunction)rlock_is_owned,
483 METH_NOARGS, rlock_is_owned_doc},
484 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
485 METH_O, rlock_acquire_restore_doc},
486 {"_release_save", (PyCFunction)rlock_release_save,
487 METH_NOARGS, rlock_release_save_doc},
488 {"__enter__", (PyCFunction)rlock_acquire,
489 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
490 {"__exit__", (PyCFunction)rlock_release,
491 METH_VARARGS, rlock_release_doc},
492 {NULL, NULL} /* sentinel */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000493};
494
495
496static PyTypeObject RLocktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 PyVarObject_HEAD_INIT(&PyType_Type, 0)
498 "_thread.RLock", /*tp_name*/
499 sizeof(rlockobject), /*tp_size*/
500 0, /*tp_itemsize*/
501 /* methods */
502 (destructor)rlock_dealloc, /*tp_dealloc*/
503 0, /*tp_print*/
504 0, /*tp_getattr*/
505 0, /*tp_setattr*/
506 0, /*tp_reserved*/
507 (reprfunc)rlock_repr, /*tp_repr*/
508 0, /*tp_as_number*/
509 0, /*tp_as_sequence*/
510 0, /*tp_as_mapping*/
511 0, /*tp_hash*/
512 0, /*tp_call*/
513 0, /*tp_str*/
514 0, /*tp_getattro*/
515 0, /*tp_setattro*/
516 0, /*tp_as_buffer*/
517 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
518 0, /*tp_doc*/
519 0, /*tp_traverse*/
520 0, /*tp_clear*/
521 0, /*tp_richcompare*/
522 offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
523 0, /*tp_iter*/
524 0, /*tp_iternext*/
525 rlock_methods, /*tp_methods*/
526 0, /* tp_members */
527 0, /* tp_getset */
528 0, /* tp_base */
529 0, /* tp_dict */
530 0, /* tp_descr_get */
531 0, /* tp_descr_set */
532 0, /* tp_dictoffset */
533 0, /* tp_init */
534 PyType_GenericAlloc, /* tp_alloc */
535 rlock_new /* tp_new */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000536};
537
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000538static lockobject *
539newlockobject(void)
540{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 lockobject *self;
542 self = PyObject_New(lockobject, &Locktype);
543 if (self == NULL)
544 return NULL;
545 self->lock_lock = PyThread_allocate_lock();
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000546 self->locked = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 self->in_weakreflist = NULL;
548 if (self->lock_lock == NULL) {
549 Py_DECREF(self);
550 PyErr_SetString(ThreadError, "can't allocate lock");
551 return NULL;
552 }
553 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000554}
555
Jim Fultond15dc062004-07-14 19:11:50 +0000556/* Thread-local objects */
557
558#include "structmember.h"
559
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000560/* Quick overview:
561
562 We need to be able to reclaim reference cycles as soon as possible
563 (both when a thread is being terminated, or a thread-local object
564 becomes unreachable from user data). Constraints:
565 - it must not be possible for thread-state dicts to be involved in
566 reference cycles (otherwise the cyclic GC will refuse to consider
567 objects referenced from a reachable thread-state dict, even though
568 local_dealloc would clear them)
569 - the death of a thread-state dict must still imply destruction of the
570 corresponding local dicts in all thread-local objects.
571
572 Our implementation uses small "localdummy" objects in order to break
573 the reference chain. These trivial objects are hashable (using the
574 default scheme of identity hashing) and weakrefable.
575 Each thread-state holds a separate localdummy for each local object
576 (as a /strong reference/),
577 and each thread-local object holds a dict mapping /weak references/
578 of localdummies to local dicts.
579
580 Therefore:
581 - only the thread-state dict holds a strong reference to the dummies
582 - only the thread-local object holds a strong reference to the local dicts
583 - only outside objects (application- or library-level) hold strong
584 references to the thread-local objects
585 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
586 dummies attached to that thread are called, and destroy the corresponding
587 local dicts from thread-local objects
588 - as soon as a thread-local object is destroyed, its local dicts are
589 destroyed and its dummies are manually removed from all thread states
590 - the GC can do its work correctly when a thread-local object is dangling,
591 without any interference from the thread-state dicts
592
593 As an additional optimization, each localdummy holds a borrowed reference
594 to the corresponding localdict. This borrowed reference is only used
595 by the thread-local object which has created the localdummy, which should
596 guarantee that the localdict still exists when accessed.
597*/
598
599typedef struct {
600 PyObject_HEAD
601 PyObject *localdict; /* Borrowed reference! */
602 PyObject *weakreflist; /* List of weak references to self */
603} localdummyobject;
604
605static void
606localdummy_dealloc(localdummyobject *self)
607{
608 if (self->weakreflist != NULL)
609 PyObject_ClearWeakRefs((PyObject *) self);
610 Py_TYPE(self)->tp_free((PyObject*)self);
611}
612
613static PyTypeObject localdummytype = {
614 PyVarObject_HEAD_INIT(NULL, 0)
615 /* tp_name */ "_thread._localdummy",
616 /* tp_basicsize */ sizeof(localdummyobject),
617 /* tp_itemsize */ 0,
618 /* tp_dealloc */ (destructor)localdummy_dealloc,
619 /* tp_print */ 0,
620 /* tp_getattr */ 0,
621 /* tp_setattr */ 0,
622 /* tp_reserved */ 0,
623 /* tp_repr */ 0,
624 /* tp_as_number */ 0,
625 /* tp_as_sequence */ 0,
626 /* tp_as_mapping */ 0,
627 /* tp_hash */ 0,
628 /* tp_call */ 0,
629 /* tp_str */ 0,
630 /* tp_getattro */ 0,
631 /* tp_setattro */ 0,
632 /* tp_as_buffer */ 0,
633 /* tp_flags */ Py_TPFLAGS_DEFAULT,
634 /* tp_doc */ "Thread-local dummy",
635 /* tp_traverse */ 0,
636 /* tp_clear */ 0,
637 /* tp_richcompare */ 0,
638 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
639};
640
641
Jim Fultond15dc062004-07-14 19:11:50 +0000642typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 PyObject_HEAD
644 PyObject *key;
645 PyObject *args;
646 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000647 PyObject *weakreflist; /* List of weak references to self */
648 /* A {localdummy weakref -> localdict} dict */
649 PyObject *dummies;
650 /* The callback for weakrefs to localdummies */
651 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000652} localobject;
653
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000654/* Forward declaration */
655static PyObject *_ldict(localobject *self);
656static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
657
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000658/* Create and register the dummy for the current thread.
659 Returns a borrowed reference of the corresponding local dict */
660static PyObject *
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000661_local_create_dummy(localobject *self)
662{
663 PyObject *tdict, *ldict = NULL, *wr = NULL;
664 localdummyobject *dummy = NULL;
665 int r;
666
667 tdict = PyThreadState_GetDict();
668 if (tdict == NULL) {
669 PyErr_SetString(PyExc_SystemError,
670 "Couldn't get thread-state dictionary");
671 goto err;
672 }
673
674 ldict = PyDict_New();
675 if (ldict == NULL)
676 goto err;
677 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
678 if (dummy == NULL)
679 goto err;
680 dummy->localdict = ldict;
681 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
682 if (wr == NULL)
683 goto err;
684
685 /* As a side-effect, this will cache the weakref's hash before the
686 dummy gets deleted */
687 r = PyDict_SetItem(self->dummies, wr, ldict);
688 if (r < 0)
689 goto err;
690 Py_CLEAR(wr);
691 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
692 if (r < 0)
693 goto err;
694 Py_CLEAR(dummy);
695
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000696 Py_DECREF(ldict);
697 return ldict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000698
699err:
700 Py_XDECREF(ldict);
701 Py_XDECREF(wr);
702 Py_XDECREF(dummy);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000703 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000704}
705
Jim Fultond15dc062004-07-14 19:11:50 +0000706static PyObject *
707local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
708{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 localobject *self;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000710 PyObject *wr;
711 static PyMethodDef wr_callback_def = {
712 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
713 };
Jim Fultond15dc062004-07-14 19:11:50 +0000714
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 if (type->tp_init == PyBaseObject_Type.tp_init
716 && ((args && PyObject_IsTrue(args))
717 || (kw && PyObject_IsTrue(kw)))) {
718 PyErr_SetString(PyExc_TypeError,
719 "Initialization arguments are not supported");
720 return NULL;
721 }
Jim Fultond15dc062004-07-14 19:11:50 +0000722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 self = (localobject *)type->tp_alloc(type, 0);
724 if (self == NULL)
725 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727 Py_XINCREF(args);
728 self->args = args;
729 Py_XINCREF(kw);
730 self->kw = kw;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 self->key = PyUnicode_FromFormat("thread.local.%p", self);
732 if (self->key == NULL)
733 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000734
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000735 self->dummies = PyDict_New();
736 if (self->dummies == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000738
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000739 /* We use a weak reference to self in the callback closure
740 in order to avoid spurious reference cycles */
741 wr = PyWeakref_NewRef((PyObject *) self, NULL);
742 if (wr == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 goto err;
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200744 self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000745 Py_DECREF(wr);
746 if (self->wr_callback == NULL)
747 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000748
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000749 if (_local_create_dummy(self) == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000751
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000752 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000753
754 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000755 Py_DECREF(self);
756 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000757}
758
759static int
760local_traverse(localobject *self, visitproc visit, void *arg)
761{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 Py_VISIT(self->args);
763 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000764 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000766}
767
768static int
769local_clear(localobject *self)
770{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000771 PyThreadState *tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000772 Py_CLEAR(self->args);
773 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000774 Py_CLEAR(self->dummies);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000775 Py_CLEAR(self->wr_callback);
776 /* Remove all strong references to dummies from the thread states */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000777 if (self->key
778 && (tstate = PyThreadState_Get())
779 && tstate->interp) {
780 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
781 tstate;
782 tstate = PyThreadState_Next(tstate))
783 if (tstate->dict &&
784 PyDict_GetItem(tstate->dict, self->key))
785 PyDict_DelItem(tstate->dict, self->key);
786 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000787 return 0;
788}
Jim Fultond15dc062004-07-14 19:11:50 +0000789
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000790static void
791local_dealloc(localobject *self)
792{
793 /* Weakrefs must be invalidated right now, otherwise they can be used
794 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
795 if (self->weakreflist != NULL)
796 PyObject_ClearWeakRefs((PyObject *) self);
797
798 PyObject_GC_UnTrack(self);
799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000801 Py_XDECREF(self->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000803}
804
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000805/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000806static PyObject *
807_ldict(localobject *self)
808{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000809 PyObject *tdict, *ldict, *dummy;
Jim Fultond15dc062004-07-14 19:11:50 +0000810
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000811 tdict = PyThreadState_GetDict();
812 if (tdict == NULL) {
813 PyErr_SetString(PyExc_SystemError,
814 "Couldn't get thread-state dictionary");
815 return NULL;
816 }
Jim Fultond15dc062004-07-14 19:11:50 +0000817
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000818 dummy = PyDict_GetItem(tdict, self->key);
819 if (dummy == NULL) {
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000820 ldict = _local_create_dummy(self);
821 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000822 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000823
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000824 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
825 Py_TYPE(self)->tp_init((PyObject*)self,
826 self->args, self->kw) < 0) {
827 /* we need to get rid of ldict from thread so
828 we create a new one the next time we do an attr
Ezio Melotti42da6632011-03-15 05:18:48 +0200829 access */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000830 PyDict_DelItem(tdict, self->key);
831 return NULL;
832 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000833 }
834 else {
835 assert(Py_TYPE(dummy) == &localdummytype);
836 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000837 }
Jim Fultond15dc062004-07-14 19:11:50 +0000838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000839 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000840}
841
Jim Fultond15dc062004-07-14 19:11:50 +0000842static int
843local_setattro(localobject *self, PyObject *name, PyObject *v)
844{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000845 PyObject *ldict;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000846 int r;
Jim Fultond15dc062004-07-14 19:11:50 +0000847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 ldict = _ldict(self);
849 if (ldict == NULL)
850 return -1;
851
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000852 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
853 if (r == 1) {
854 PyErr_Format(PyExc_AttributeError,
855 "'%.50s' object attribute '%U' is read-only",
856 Py_TYPE(self)->tp_name, name);
857 return -1;
858 }
859 if (r == -1)
860 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000861
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000862 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000863}
864
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000865static PyObject *local_getattro(localobject *, PyObject *);
866
Jim Fultond15dc062004-07-14 19:11:50 +0000867static PyTypeObject localtype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 PyVarObject_HEAD_INIT(NULL, 0)
869 /* tp_name */ "_thread._local",
870 /* tp_basicsize */ sizeof(localobject),
871 /* tp_itemsize */ 0,
872 /* tp_dealloc */ (destructor)local_dealloc,
873 /* tp_print */ 0,
874 /* tp_getattr */ 0,
875 /* tp_setattr */ 0,
876 /* tp_reserved */ 0,
877 /* tp_repr */ 0,
878 /* tp_as_number */ 0,
879 /* tp_as_sequence */ 0,
880 /* tp_as_mapping */ 0,
881 /* tp_hash */ 0,
882 /* tp_call */ 0,
883 /* tp_str */ 0,
884 /* tp_getattro */ (getattrofunc)local_getattro,
885 /* tp_setattro */ (setattrofunc)local_setattro,
886 /* tp_as_buffer */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000887 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
888 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 /* tp_doc */ "Thread-local data",
890 /* tp_traverse */ (traverseproc)local_traverse,
891 /* tp_clear */ (inquiry)local_clear,
892 /* tp_richcompare */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000893 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 /* tp_iter */ 0,
895 /* tp_iternext */ 0,
896 /* tp_methods */ 0,
897 /* tp_members */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000898 /* tp_getset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000899 /* tp_base */ 0,
900 /* tp_dict */ 0, /* internal use */
901 /* tp_descr_get */ 0,
902 /* tp_descr_set */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000903 /* tp_dictoffset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000904 /* tp_init */ 0,
905 /* tp_alloc */ 0,
906 /* tp_new */ local_new,
907 /* tp_free */ 0, /* Low-level free-mem routine */
908 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000909};
910
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000911static PyObject *
912local_getattro(localobject *self, PyObject *name)
913{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000914 PyObject *ldict, *value;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000915 int r;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000916
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000917 ldict = _ldict(self);
918 if (ldict == NULL)
919 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000920
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000921 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
922 if (r == 1) {
923 Py_INCREF(ldict);
924 return ldict;
925 }
926 if (r == -1)
927 return NULL;
928
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000929 if (Py_TYPE(self) != &localtype)
930 /* use generic lookup for subtypes */
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000931 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 /* Optimization: just look in dict ourselves */
934 value = PyDict_GetItem(ldict, name);
935 if (value == NULL)
936 /* Fall back on generic to get __class__ and __dict__ */
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000937 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000939 Py_INCREF(value);
940 return value;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000941}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000942
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000943/* Called when a dummy is destroyed. */
944static PyObject *
945_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
946{
947 PyObject *obj;
948 localobject *self;
949 assert(PyWeakref_CheckRef(localweakref));
950 obj = PyWeakref_GET_OBJECT(localweakref);
951 if (obj == Py_None)
952 Py_RETURN_NONE;
953 Py_INCREF(obj);
954 assert(PyObject_TypeCheck(obj, &localtype));
955 /* If the thread-local object is still alive and not being cleared,
956 remove the corresponding local dict */
957 self = (localobject *) obj;
958 if (self->dummies != NULL) {
959 PyObject *ldict;
960 ldict = PyDict_GetItem(self->dummies, dummyweakref);
961 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000962 PyDict_DelItem(self->dummies, dummyweakref);
963 }
964 if (PyErr_Occurred())
965 PyErr_WriteUnraisable(obj);
966 }
967 Py_DECREF(obj);
968 Py_RETURN_NONE;
969}
970
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000971/* Module functions */
972
Guido van Rossuma027efa1997-05-05 20:56:21 +0000973struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 PyInterpreterState *interp;
975 PyObject *func;
976 PyObject *args;
977 PyObject *keyw;
978 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000979};
980
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000981static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000982t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000983{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 struct bootstate *boot = (struct bootstate *) boot_raw;
985 PyThreadState *tstate;
986 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 tstate = boot->tstate;
989 tstate->thread_id = PyThread_get_thread_ident();
990 _PyThreadState_Init(tstate);
991 PyEval_AcquireThread(tstate);
992 nb_threads++;
993 res = PyEval_CallObjectWithKeywords(
994 boot->func, boot->args, boot->keyw);
995 if (res == NULL) {
996 if (PyErr_ExceptionMatches(PyExc_SystemExit))
997 PyErr_Clear();
998 else {
999 PyObject *file;
Benjamin Petersone9000962012-04-02 11:15:17 -04001000 PyObject *exc, *value, *tb;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 PySys_WriteStderr(
1002 "Unhandled exception in thread started by ");
Benjamin Petersone9000962012-04-02 11:15:17 -04001003 PyErr_Fetch(&exc, &value, &tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 file = PySys_GetObject("stderr");
1005 if (file != NULL && file != Py_None)
1006 PyFile_WriteObject(boot->func, file, 0);
1007 else
1008 PyObject_Print(boot->func, stderr, 0);
1009 PySys_WriteStderr("\n");
Benjamin Petersone9000962012-04-02 11:15:17 -04001010 PyErr_Restore(exc, value, tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 PyErr_PrintEx(0);
1012 }
1013 }
1014 else
1015 Py_DECREF(res);
1016 Py_DECREF(boot->func);
1017 Py_DECREF(boot->args);
1018 Py_XDECREF(boot->keyw);
1019 PyMem_DEL(boot_raw);
1020 nb_threads--;
1021 PyThreadState_Clear(tstate);
1022 PyThreadState_DeleteCurrent();
1023 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001024}
1025
Barry Warsawd0c10421996-12-17 00:05:22 +00001026static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001027thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001028{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 PyObject *func, *args, *keyw = NULL;
1030 struct bootstate *boot;
1031 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001032
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
1034 &func, &args, &keyw))
1035 return NULL;
1036 if (!PyCallable_Check(func)) {
1037 PyErr_SetString(PyExc_TypeError,
1038 "first arg must be callable");
1039 return NULL;
1040 }
1041 if (!PyTuple_Check(args)) {
1042 PyErr_SetString(PyExc_TypeError,
1043 "2nd arg must be a tuple");
1044 return NULL;
1045 }
1046 if (keyw != NULL && !PyDict_Check(keyw)) {
1047 PyErr_SetString(PyExc_TypeError,
1048 "optional 3rd arg must be a dictionary");
1049 return NULL;
1050 }
1051 boot = PyMem_NEW(struct bootstate, 1);
1052 if (boot == NULL)
1053 return PyErr_NoMemory();
1054 boot->interp = PyThreadState_GET()->interp;
1055 boot->func = func;
1056 boot->args = args;
1057 boot->keyw = keyw;
1058 boot->tstate = _PyThreadState_Prealloc(boot->interp);
1059 if (boot->tstate == NULL) {
1060 PyMem_DEL(boot);
1061 return PyErr_NoMemory();
1062 }
1063 Py_INCREF(func);
1064 Py_INCREF(args);
1065 Py_XINCREF(keyw);
1066 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
1067 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
1068 if (ident == -1) {
1069 PyErr_SetString(ThreadError, "can't start new thread");
1070 Py_DECREF(func);
1071 Py_DECREF(args);
1072 Py_XDECREF(keyw);
1073 PyThreadState_Clear(boot->tstate);
1074 PyMem_DEL(boot);
1075 return NULL;
1076 }
1077 return PyLong_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001078}
1079
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001080PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001081"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001082(start_new() is an obsolete synonym)\n\
1083\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001084Start a new thread and return its identifier. The thread will call the\n\
1085function with positional arguments from the tuple args and keyword arguments\n\
1086taken from the optional dictionary kwargs. The thread exits when the\n\
1087function returns; the return value is ignored. The thread will also exit\n\
1088when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001089printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001090
Barry Warsawd0c10421996-12-17 00:05:22 +00001091static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001092thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001093{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 PyErr_SetNone(PyExc_SystemExit);
1095 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001096}
1097
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001098PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001099"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001100(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001101\n\
1102This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001103thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001104
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001105static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001106thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001107{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001108 PyErr_SetInterrupt();
1109 Py_INCREF(Py_None);
1110 return Py_None;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001111}
1112
1113PyDoc_STRVAR(interrupt_doc,
1114"interrupt_main()\n\
1115\n\
1116Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001117A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001118);
1119
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001120static lockobject *newlockobject(void);
1121
Barry Warsawd0c10421996-12-17 00:05:22 +00001122static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001123thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001124{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001126}
1127
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001128PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001129"allocate_lock() -> lock object\n\
1130(allocate() is an obsolete synonym)\n\
1131\n\
Alexander Belopolsky977a6842010-08-16 20:17:07 +00001132Create a new lock object. See help(LockType) for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001133
Barry Warsawd0c10421996-12-17 00:05:22 +00001134static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001135thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001136{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001137 long ident;
1138 ident = PyThread_get_thread_ident();
1139 if (ident == -1) {
1140 PyErr_SetString(ThreadError, "no current thread ident");
1141 return NULL;
1142 }
1143 return PyLong_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001144}
1145
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001146PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001147"get_ident() -> integer\n\
1148\n\
1149Return a non-zero integer that uniquely identifies the current thread\n\
1150amongst other threads that exist simultaneously.\n\
1151This may be used to identify per-thread resources.\n\
1152Even though on some platforms threads identities may appear to be\n\
1153allocated consecutive numbers starting at 1, this behavior should not\n\
1154be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001155A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001156
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001157static PyObject *
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001158thread__count(PyObject *self)
1159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 return PyLong_FromLong(nb_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001161}
1162
1163PyDoc_STRVAR(_count_doc,
1164"_count() -> integer\n\
1165\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001166\
1167Return the number of currently running Python threads, excluding \n\
1168the main thread. The returned number comprises all threads created\n\
1169through `start_new_thread()` as well as `threading.Thread`, and not\n\
1170yet finished.\n\
1171\n\
1172This function is meant for internal and specialized purposes only.\n\
1173In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001174
1175static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001176thread_stack_size(PyObject *self, PyObject *args)
1177{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 size_t old_size;
1179 Py_ssize_t new_size = 0;
1180 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001181
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001182 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1183 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 if (new_size < 0) {
1186 PyErr_SetString(PyExc_ValueError,
1187 "size must be 0 or a positive value");
1188 return NULL;
1189 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001191 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 rc = PyThread_set_stacksize((size_t) new_size);
1194 if (rc == -1) {
1195 PyErr_Format(PyExc_ValueError,
1196 "size not valid: %zd bytes",
1197 new_size);
1198 return NULL;
1199 }
1200 if (rc == -2) {
1201 PyErr_SetString(ThreadError,
1202 "setting stack size not supported");
1203 return NULL;
1204 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001207}
1208
1209PyDoc_STRVAR(stack_size_doc,
1210"stack_size([size]) -> size\n\
1211\n\
1212Return the thread stack size used when creating new threads. The\n\
1213optional size argument specifies the stack size (in bytes) to be used\n\
1214for subsequently created threads, and must be 0 (use platform or\n\
1215configured default) or a positive integer value of at least 32,768 (32k).\n\
1216If changing the thread stack size is unsupported, a ThreadError\n\
1217exception is raised. If the specified size is invalid, a ValueError\n\
1218exception is raised, and the stack size is unmodified. 32k bytes\n\
1219 currently the minimum supported stack size value to guarantee\n\
1220sufficient stack space for the interpreter itself.\n\
1221\n\
1222Note that some platforms may have particular restrictions on values for\n\
1223the stack size, such as requiring a minimum stack size larger than 32kB or\n\
1224requiring allocation in multiples of the system memory page size\n\
1225- platform documentation should be referred to for more information\n\
1226(4kB pages are common; using multiples of 4096 for the stack size is\n\
1227the suggested approach in the absence of more specific information).");
1228
Barry Warsawd0c10421996-12-17 00:05:22 +00001229static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001231 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001233 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
1235 METH_NOARGS, allocate_doc},
1236 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
1237 METH_NOARGS, allocate_doc},
1238 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
1239 METH_NOARGS, exit_doc},
1240 {"exit", (PyCFunction)thread_PyThread_exit_thread,
1241 METH_NOARGS, exit_doc},
1242 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
1243 METH_NOARGS, interrupt_doc},
1244 {"get_ident", (PyCFunction)thread_get_ident,
1245 METH_NOARGS, get_ident_doc},
1246 {"_count", (PyCFunction)thread__count,
1247 METH_NOARGS, _count_doc},
1248 {"stack_size", (PyCFunction)thread_stack_size,
Victor Stinner754851f2011-04-19 23:58:51 +02001249 METH_VARARGS, stack_size_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001251};
1252
1253
1254/* Initialization function */
1255
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001256PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001257"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001258The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001259
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001260PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001261"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +00001262call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001263\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001264acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1265release() -- unlock of the lock\n\
1266locked() -- test whether the lock is currently locked\n\
1267\n\
1268A lock is not owned by the thread that locked it; another thread may\n\
1269unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001270will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001271
Martin v. Löwis1a214512008-06-11 05:26:20 +00001272static struct PyModuleDef threadmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 PyModuleDef_HEAD_INIT,
1274 "_thread",
1275 thread_doc,
1276 -1,
1277 thread_methods,
1278 NULL,
1279 NULL,
1280 NULL,
1281 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001282};
1283
1284
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001285PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001286PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001287{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 PyObject *m, *d, *timeout_max;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 /* Initialize types: */
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001291 if (PyType_Ready(&localdummytype) < 0)
1292 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 if (PyType_Ready(&localtype) < 0)
1294 return NULL;
1295 if (PyType_Ready(&Locktype) < 0)
1296 return NULL;
1297 if (PyType_Ready(&RLocktype) < 0)
1298 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 /* Create the module and add the functions */
1301 m = PyModule_Create(&threadmodule);
1302 if (m == NULL)
1303 return NULL;
Antoine Pitrou7c3e5772010-04-14 15:44:10 +00001304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 timeout_max = PyFloat_FromDouble(PY_TIMEOUT_MAX / 1000000);
1306 if (!timeout_max)
1307 return NULL;
1308 if (PyModule_AddObject(m, "TIMEOUT_MAX", timeout_max) < 0)
1309 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 /* Add a symbolic constant */
1312 d = PyModule_GetDict(m);
Antoine Pitroufcf81fd2011-02-28 22:03:34 +00001313 ThreadError = PyExc_RuntimeError;
1314 Py_INCREF(ThreadError);
Victor Stinner754851f2011-04-19 23:58:51 +02001315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 PyDict_SetItemString(d, "error", ThreadError);
1317 Locktype.tp_doc = lock_doc;
1318 Py_INCREF(&Locktype);
1319 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Antoine Pitrou434736a2009-11-10 18:46:01 +00001320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 Py_INCREF(&RLocktype);
1322 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1323 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 Py_INCREF(&localtype);
1326 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1327 return NULL;
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 nb_threads = 0;
1330
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +00001331 str_dict = PyUnicode_InternFromString("__dict__");
1332 if (str_dict == NULL)
1333 return NULL;
1334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 /* Initialize the C thread library */
1336 PyThread_init_thread();
1337 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001338}