1
2 /* Thread module */
3 /* Interface to Sjoerd's portable C thread library */
4
5 #include "Python.h"
6 #include "structmember.h" /* offsetof */
7
8 #ifndef WITH_THREAD
9 #error "Error! The rest of Python is not compiled with thread support."
10 #error "Rerun configure, adding a --with-threads option."
11 #error "Then run `make clean' followed by `make'."
12 #endif
13
14 #include "pythread.h"
15
16 static PyObject *ThreadError;
17 static long nb_threads = 0;
18 static PyObject *str_dict;
19
20 _Py_IDENTIFIER(stderr);
21
22 /* Lock objects */
23
24 typedef struct {
25 PyObject_HEAD
26 PyThread_type_lock lock_lock;
27 PyObject *in_weakreflist;
28 char locked; /* for sanity checking */
29 } lockobject;
30
31 static void
lock_dealloc(lockobject * self)32 lock_dealloc(lockobject *self)
33 {
34 if (self->in_weakreflist != NULL)
35 PyObject_ClearWeakRefs((PyObject *) self);
36 if (self->lock_lock != NULL) {
37 /* Unlock the lock so it's safe to free it */
38 if (self->locked)
39 PyThread_release_lock(self->lock_lock);
40 PyThread_free_lock(self->lock_lock);
41 }
42 PyObject_Del(self);
43 }
44
45 /* Helper to acquire an interruptible lock with a timeout. If the lock acquire
46 * is interrupted, signal handlers are run, and if they raise an exception,
47 * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE
48 * are returned, depending on whether the lock can be acquired within the
49 * timeout.
50 */
51 static PyLockStatus
acquire_timed(PyThread_type_lock lock,_PyTime_t timeout)52 acquire_timed(PyThread_type_lock lock, _PyTime_t timeout)
53 {
54 PyLockStatus r;
55 _PyTime_t endtime = 0;
56 _PyTime_t microseconds;
57
58 if (timeout > 0)
59 endtime = _PyTime_GetMonotonicClock() + timeout;
60
61 do {
62 microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING);
63
64 /* first a simple non-blocking try without releasing the GIL */
65 r = PyThread_acquire_lock_timed(lock, 0, 0);
66 if (r == PY_LOCK_FAILURE && microseconds != 0) {
67 Py_BEGIN_ALLOW_THREADS
68 r = PyThread_acquire_lock_timed(lock, microseconds, 1);
69 Py_END_ALLOW_THREADS
70 }
71
72 if (r == PY_LOCK_INTR) {
73 /* Run signal handlers if we were interrupted. Propagate
74 * exceptions from signal handlers, such as KeyboardInterrupt, by
75 * passing up PY_LOCK_INTR. */
76 if (Py_MakePendingCalls() < 0) {
77 return PY_LOCK_INTR;
78 }
79
80 /* If we're using a timeout, recompute the timeout after processing
81 * signals, since those can take time. */
82 if (timeout > 0) {
83 timeout = endtime - _PyTime_GetMonotonicClock();
84
85 /* Check for negative values, since those mean block forever.
86 */
87 if (timeout < 0) {
88 r = PY_LOCK_FAILURE;
89 }
90 }
91 }
92 } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */
93
94 return r;
95 }
96
97 static int
lock_acquire_parse_args(PyObject * args,PyObject * kwds,_PyTime_t * timeout)98 lock_acquire_parse_args(PyObject *args, PyObject *kwds,
99 _PyTime_t *timeout)
100 {
101 char *kwlist[] = {"blocking", "timeout", NULL};
102 int blocking = 1;
103 PyObject *timeout_obj = NULL;
104 const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1);
105
106 *timeout = unset_timeout ;
107
108 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:acquire", kwlist,
109 &blocking, &timeout_obj))
110 return -1;
111
112 if (timeout_obj
113 && _PyTime_FromSecondsObject(timeout,
114 timeout_obj, _PyTime_ROUND_CEILING) < 0)
115 return -1;
116
117 if (!blocking && *timeout != unset_timeout ) {
118 PyErr_SetString(PyExc_ValueError,
119 "can't specify a timeout for a non-blocking call");
120 return -1;
121 }
122 if (*timeout < 0 && *timeout != unset_timeout) {
123 PyErr_SetString(PyExc_ValueError,
124 "timeout value must be positive");
125 return -1;
126 }
127 if (!blocking)
128 *timeout = 0;
129 else if (*timeout != unset_timeout) {
130 _PyTime_t microseconds;
131
132 microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_CEILING);
133 if (microseconds >= PY_TIMEOUT_MAX) {
134 PyErr_SetString(PyExc_OverflowError,
135 "timeout value is too large");
136 return -1;
137 }
138 }
139 return 0;
140 }
141
142 static PyObject *
lock_PyThread_acquire_lock(lockobject * self,PyObject * args,PyObject * kwds)143 lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
144 {
145 _PyTime_t timeout;
146 PyLockStatus r;
147
148 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
149 return NULL;
150
151 r = acquire_timed(self->lock_lock, timeout);
152 if (r == PY_LOCK_INTR) {
153 return NULL;
154 }
155
156 if (r == PY_LOCK_ACQUIRED)
157 self->locked = 1;
158 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
159 }
160
161 PyDoc_STRVAR(acquire_doc,
162 "acquire(blocking=True, timeout=-1) -> bool\n\
163 (acquire_lock() is an obsolete synonym)\n\
164 \n\
165 Lock the lock. Without argument, this blocks if the lock is already\n\
166 locked (even by the same thread), waiting for another thread to release\n\
167 the lock, and return True once the lock is acquired.\n\
168 With an argument, this will only block if the argument is true,\n\
169 and the return value reflects whether the lock is acquired.\n\
170 The blocking operation is interruptible.");
171
172 static PyObject *
lock_PyThread_release_lock(lockobject * self)173 lock_PyThread_release_lock(lockobject *self)
174 {
175 /* Sanity check: the lock must be locked */
176 if (!self->locked) {
177 PyErr_SetString(ThreadError, "release unlocked lock");
178 return NULL;
179 }
180
181 PyThread_release_lock(self->lock_lock);
182 self->locked = 0;
183 Py_INCREF(Py_None);
184 return Py_None;
185 }
186
187 PyDoc_STRVAR(release_doc,
188 "release()\n\
189 (release_lock() is an obsolete synonym)\n\
190 \n\
191 Release the lock, allowing another thread that is blocked waiting for\n\
192 the lock to acquire the lock. The lock must be in the locked state,\n\
193 but it needn't be locked by the same thread that unlocks it.");
194
195 static PyObject *
lock_locked_lock(lockobject * self)196 lock_locked_lock(lockobject *self)
197 {
198 return PyBool_FromLong((long)self->locked);
199 }
200
201 PyDoc_STRVAR(locked_doc,
202 "locked() -> bool\n\
203 (locked_lock() is an obsolete synonym)\n\
204 \n\
205 Return whether the lock is in the locked state.");
206
207 static PyObject *
lock_repr(lockobject * self)208 lock_repr(lockobject *self)
209 {
210 return PyUnicode_FromFormat("<%s %s object at %p>",
211 self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
212 }
213
214 static PyMethodDef lock_methods[] = {
215 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
216 METH_VARARGS | METH_KEYWORDS, acquire_doc},
217 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
218 METH_VARARGS | METH_KEYWORDS, acquire_doc},
219 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
220 METH_NOARGS, release_doc},
221 {"release", (PyCFunction)lock_PyThread_release_lock,
222 METH_NOARGS, release_doc},
223 {"locked_lock", (PyCFunction)lock_locked_lock,
224 METH_NOARGS, locked_doc},
225 {"locked", (PyCFunction)lock_locked_lock,
226 METH_NOARGS, locked_doc},
227 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
228 METH_VARARGS | METH_KEYWORDS, acquire_doc},
229 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
230 METH_VARARGS, release_doc},
231 {NULL, NULL} /* sentinel */
232 };
233
234 static PyTypeObject Locktype = {
235 PyVarObject_HEAD_INIT(&PyType_Type, 0)
236 "_thread.lock", /*tp_name*/
237 sizeof(lockobject), /*tp_size*/
238 0, /*tp_itemsize*/
239 /* methods */
240 (destructor)lock_dealloc, /*tp_dealloc*/
241 0, /*tp_print*/
242 0, /*tp_getattr*/
243 0, /*tp_setattr*/
244 0, /*tp_reserved*/
245 (reprfunc)lock_repr, /*tp_repr*/
246 0, /*tp_as_number*/
247 0, /*tp_as_sequence*/
248 0, /*tp_as_mapping*/
249 0, /*tp_hash*/
250 0, /*tp_call*/
251 0, /*tp_str*/
252 0, /*tp_getattro*/
253 0, /*tp_setattro*/
254 0, /*tp_as_buffer*/
255 Py_TPFLAGS_DEFAULT, /*tp_flags*/
256 0, /*tp_doc*/
257 0, /*tp_traverse*/
258 0, /*tp_clear*/
259 0, /*tp_richcompare*/
260 offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
261 0, /*tp_iter*/
262 0, /*tp_iternext*/
263 lock_methods, /*tp_methods*/
264 };
265
266 /* Recursive lock objects */
267
268 typedef struct {
269 PyObject_HEAD
270 PyThread_type_lock rlock_lock;
271 long rlock_owner;
272 unsigned long rlock_count;
273 PyObject *in_weakreflist;
274 } rlockobject;
275
276 static void
rlock_dealloc(rlockobject * self)277 rlock_dealloc(rlockobject *self)
278 {
279 if (self->in_weakreflist != NULL)
280 PyObject_ClearWeakRefs((PyObject *) self);
281 /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed
282 in rlock_new() */
283 if (self->rlock_lock != NULL) {
284 /* Unlock the lock so it's safe to free it */
285 if (self->rlock_count > 0)
286 PyThread_release_lock(self->rlock_lock);
287
288 PyThread_free_lock(self->rlock_lock);
289 }
290 Py_TYPE(self)->tp_free(self);
291 }
292
293 static PyObject *
rlock_acquire(rlockobject * self,PyObject * args,PyObject * kwds)294 rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
295 {
296 _PyTime_t timeout;
297 long tid;
298 PyLockStatus r = PY_LOCK_ACQUIRED;
299
300 if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
301 return NULL;
302
303 tid = PyThread_get_thread_ident();
304 if (self->rlock_count > 0 && tid == self->rlock_owner) {
305 unsigned long count = self->rlock_count + 1;
306 if (count <= self->rlock_count) {
307 PyErr_SetString(PyExc_OverflowError,
308 "Internal lock count overflowed");
309 return NULL;
310 }
311 self->rlock_count = count;
312 Py_RETURN_TRUE;
313 }
314 r = acquire_timed(self->rlock_lock, timeout);
315 if (r == PY_LOCK_ACQUIRED) {
316 assert(self->rlock_count == 0);
317 self->rlock_owner = tid;
318 self->rlock_count = 1;
319 }
320 else if (r == PY_LOCK_INTR) {
321 return NULL;
322 }
323
324 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
325 }
326
327 PyDoc_STRVAR(rlock_acquire_doc,
328 "acquire(blocking=True) -> bool\n\
329 \n\
330 Lock the lock. `blocking` indicates whether we should wait\n\
331 for the lock to be available or not. If `blocking` is False\n\
332 and another thread holds the lock, the method will return False\n\
333 immediately. If `blocking` is True and another thread holds\n\
334 the lock, the method will wait for the lock to be released,\n\
335 take it and then return True.\n\
336 (note: the blocking operation is interruptible.)\n\
337 \n\
338 In all other cases, the method will return True immediately.\n\
339 Precisely, if the current thread already holds the lock, its\n\
340 internal counter is simply incremented. If nobody holds the lock,\n\
341 the lock is taken and its internal counter initialized to 1.");
342
343 static PyObject *
rlock_release(rlockobject * self)344 rlock_release(rlockobject *self)
345 {
346 long tid = PyThread_get_thread_ident();
347
348 if (self->rlock_count == 0 || self->rlock_owner != tid) {
349 PyErr_SetString(PyExc_RuntimeError,
350 "cannot release un-acquired lock");
351 return NULL;
352 }
353 if (--self->rlock_count == 0) {
354 self->rlock_owner = 0;
355 PyThread_release_lock(self->rlock_lock);
356 }
357 Py_RETURN_NONE;
358 }
359
360 PyDoc_STRVAR(rlock_release_doc,
361 "release()\n\
362 \n\
363 Release the lock, allowing another thread that is blocked waiting for\n\
364 the lock to acquire the lock. The lock must be in the locked state,\n\
365 and must be locked by the same thread that unlocks it; otherwise a\n\
366 `RuntimeError` is raised.\n\
367 \n\
368 Do note that if the lock was acquire()d several times in a row by the\n\
369 current thread, release() needs to be called as many times for the lock\n\
370 to be available for other threads.");
371
372 static PyObject *
rlock_acquire_restore(rlockobject * self,PyObject * args)373 rlock_acquire_restore(rlockobject *self, PyObject *args)
374 {
375 long owner;
376 unsigned long count;
377 int r = 1;
378
379 if (!PyArg_ParseTuple(args, "(kl):_acquire_restore", &count, &owner))
380 return NULL;
381
382 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
383 Py_BEGIN_ALLOW_THREADS
384 r = PyThread_acquire_lock(self->rlock_lock, 1);
385 Py_END_ALLOW_THREADS
386 }
387 if (!r) {
388 PyErr_SetString(ThreadError, "couldn't acquire lock");
389 return NULL;
390 }
391 assert(self->rlock_count == 0);
392 self->rlock_owner = owner;
393 self->rlock_count = count;
394 Py_RETURN_NONE;
395 }
396
397 PyDoc_STRVAR(rlock_acquire_restore_doc,
398 "_acquire_restore(state) -> None\n\
399 \n\
400 For internal use by `threading.Condition`.");
401
402 static PyObject *
rlock_release_save(rlockobject * self)403 rlock_release_save(rlockobject *self)
404 {
405 long owner;
406 unsigned long count;
407
408 if (self->rlock_count == 0) {
409 PyErr_SetString(PyExc_RuntimeError,
410 "cannot release un-acquired lock");
411 return NULL;
412 }
413
414 owner = self->rlock_owner;
415 count = self->rlock_count;
416 self->rlock_count = 0;
417 self->rlock_owner = 0;
418 PyThread_release_lock(self->rlock_lock);
419 return Py_BuildValue("kl", count, owner);
420 }
421
422 PyDoc_STRVAR(rlock_release_save_doc,
423 "_release_save() -> tuple\n\
424 \n\
425 For internal use by `threading.Condition`.");
426
427
428 static PyObject *
rlock_is_owned(rlockobject * self)429 rlock_is_owned(rlockobject *self)
430 {
431 long tid = PyThread_get_thread_ident();
432
433 if (self->rlock_count > 0 && self->rlock_owner == tid) {
434 Py_RETURN_TRUE;
435 }
436 Py_RETURN_FALSE;
437 }
438
439 PyDoc_STRVAR(rlock_is_owned_doc,
440 "_is_owned() -> bool\n\
441 \n\
442 For internal use by `threading.Condition`.");
443
444 static PyObject *
rlock_new(PyTypeObject * type,PyObject * args,PyObject * kwds)445 rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
446 {
447 rlockobject *self;
448
449 self = (rlockobject *) type->tp_alloc(type, 0);
450 if (self != NULL) {
451 self->in_weakreflist = NULL;
452 self->rlock_owner = 0;
453 self->rlock_count = 0;
454
455 self->rlock_lock = PyThread_allocate_lock();
456 if (self->rlock_lock == NULL) {
457 Py_DECREF(self);
458 PyErr_SetString(ThreadError, "can't allocate lock");
459 return NULL;
460 }
461 }
462
463 return (PyObject *) self;
464 }
465
466 static PyObject *
rlock_repr(rlockobject * self)467 rlock_repr(rlockobject *self)
468 {
469 return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>",
470 self->rlock_count ? "locked" : "unlocked",
471 Py_TYPE(self)->tp_name, self->rlock_owner,
472 self->rlock_count, self);
473 }
474
475
476 static PyMethodDef rlock_methods[] = {
477 {"acquire", (PyCFunction)rlock_acquire,
478 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
479 {"release", (PyCFunction)rlock_release,
480 METH_NOARGS, rlock_release_doc},
481 {"_is_owned", (PyCFunction)rlock_is_owned,
482 METH_NOARGS, rlock_is_owned_doc},
483 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
484 METH_VARARGS, rlock_acquire_restore_doc},
485 {"_release_save", (PyCFunction)rlock_release_save,
486 METH_NOARGS, rlock_release_save_doc},
487 {"__enter__", (PyCFunction)rlock_acquire,
488 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
489 {"__exit__", (PyCFunction)rlock_release,
490 METH_VARARGS, rlock_release_doc},
491 {NULL, NULL} /* sentinel */
492 };
493
494
495 static PyTypeObject RLocktype = {
496 PyVarObject_HEAD_INIT(&PyType_Type, 0)
497 "_thread.RLock", /*tp_name*/
498 sizeof(rlockobject), /*tp_size*/
499 0, /*tp_itemsize*/
500 /* methods */
501 (destructor)rlock_dealloc, /*tp_dealloc*/
502 0, /*tp_print*/
503 0, /*tp_getattr*/
504 0, /*tp_setattr*/
505 0, /*tp_reserved*/
506 (reprfunc)rlock_repr, /*tp_repr*/
507 0, /*tp_as_number*/
508 0, /*tp_as_sequence*/
509 0, /*tp_as_mapping*/
510 0, /*tp_hash*/
511 0, /*tp_call*/
512 0, /*tp_str*/
513 0, /*tp_getattro*/
514 0, /*tp_setattro*/
515 0, /*tp_as_buffer*/
516 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
517 0, /*tp_doc*/
518 0, /*tp_traverse*/
519 0, /*tp_clear*/
520 0, /*tp_richcompare*/
521 offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
522 0, /*tp_iter*/
523 0, /*tp_iternext*/
524 rlock_methods, /*tp_methods*/
525 0, /* tp_members */
526 0, /* tp_getset */
527 0, /* tp_base */
528 0, /* tp_dict */
529 0, /* tp_descr_get */
530 0, /* tp_descr_set */
531 0, /* tp_dictoffset */
532 0, /* tp_init */
533 PyType_GenericAlloc, /* tp_alloc */
534 rlock_new /* tp_new */
535 };
536
537 static lockobject *
newlockobject(void)538 newlockobject(void)
539 {
540 lockobject *self;
541 self = PyObject_New(lockobject, &Locktype);
542 if (self == NULL)
543 return NULL;
544 self->lock_lock = PyThread_allocate_lock();
545 self->locked = 0;
546 self->in_weakreflist = NULL;
547 if (self->lock_lock == NULL) {
548 Py_DECREF(self);
549 PyErr_SetString(ThreadError, "can't allocate lock");
550 return NULL;
551 }
552 return self;
553 }
554
555 /* Thread-local objects */
556
557 #include "structmember.h"
558
559 /* Quick overview:
560
561 We need to be able to reclaim reference cycles as soon as possible
562 (both when a thread is being terminated, or a thread-local object
563 becomes unreachable from user data). Constraints:
564 - it must not be possible for thread-state dicts to be involved in
565 reference cycles (otherwise the cyclic GC will refuse to consider
566 objects referenced from a reachable thread-state dict, even though
567 local_dealloc would clear them)
568 - the death of a thread-state dict must still imply destruction of the
569 corresponding local dicts in all thread-local objects.
570
571 Our implementation uses small "localdummy" objects in order to break
572 the reference chain. These trivial objects are hashable (using the
573 default scheme of identity hashing) and weakrefable.
574 Each thread-state holds a separate localdummy for each local object
575 (as a /strong reference/),
576 and each thread-local object holds a dict mapping /weak references/
577 of localdummies to local dicts.
578
579 Therefore:
580 - only the thread-state dict holds a strong reference to the dummies
581 - only the thread-local object holds a strong reference to the local dicts
582 - only outside objects (application- or library-level) hold strong
583 references to the thread-local objects
584 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
585 dummies attached to that thread are called, and destroy the corresponding
586 local dicts from thread-local objects
587 - as soon as a thread-local object is destroyed, its local dicts are
588 destroyed and its dummies are manually removed from all thread states
589 - the GC can do its work correctly when a thread-local object is dangling,
590 without any interference from the thread-state dicts
591
592 As an additional optimization, each localdummy holds a borrowed reference
593 to the corresponding localdict. This borrowed reference is only used
594 by the thread-local object which has created the localdummy, which should
595 guarantee that the localdict still exists when accessed.
596 */
597
598 typedef struct {
599 PyObject_HEAD
600 PyObject *localdict; /* Borrowed reference! */
601 PyObject *weakreflist; /* List of weak references to self */
602 } localdummyobject;
603
604 static void
localdummy_dealloc(localdummyobject * self)605 localdummy_dealloc(localdummyobject *self)
606 {
607 if (self->weakreflist != NULL)
608 PyObject_ClearWeakRefs((PyObject *) self);
609 Py_TYPE(self)->tp_free((PyObject*)self);
610 }
611
612 static PyTypeObject localdummytype = {
613 PyVarObject_HEAD_INIT(NULL, 0)
614 /* tp_name */ "_thread._localdummy",
615 /* tp_basicsize */ sizeof(localdummyobject),
616 /* tp_itemsize */ 0,
617 /* tp_dealloc */ (destructor)localdummy_dealloc,
618 /* tp_print */ 0,
619 /* tp_getattr */ 0,
620 /* tp_setattr */ 0,
621 /* tp_reserved */ 0,
622 /* tp_repr */ 0,
623 /* tp_as_number */ 0,
624 /* tp_as_sequence */ 0,
625 /* tp_as_mapping */ 0,
626 /* tp_hash */ 0,
627 /* tp_call */ 0,
628 /* tp_str */ 0,
629 /* tp_getattro */ 0,
630 /* tp_setattro */ 0,
631 /* tp_as_buffer */ 0,
632 /* tp_flags */ Py_TPFLAGS_DEFAULT,
633 /* tp_doc */ "Thread-local dummy",
634 /* tp_traverse */ 0,
635 /* tp_clear */ 0,
636 /* tp_richcompare */ 0,
637 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
638 };
639
640
641 typedef struct {
642 PyObject_HEAD
643 PyObject *key;
644 PyObject *args;
645 PyObject *kw;
646 PyObject *weakreflist; /* List of weak references to self */
647 /* A {localdummy weakref -> localdict} dict */
648 PyObject *dummies;
649 /* The callback for weakrefs to localdummies */
650 PyObject *wr_callback;
651 } localobject;
652
653 /* Forward declaration */
654 static PyObject *_ldict(localobject *self);
655 static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
656
657 /* Create and register the dummy for the current thread.
658 Returns a borrowed reference of the corresponding local dict */
659 static PyObject *
_local_create_dummy(localobject * self)660 _local_create_dummy(localobject *self)
661 {
662 PyObject *tdict, *ldict = NULL, *wr = NULL;
663 localdummyobject *dummy = NULL;
664 int r;
665
666 tdict = PyThreadState_GetDict();
667 if (tdict == NULL) {
668 PyErr_SetString(PyExc_SystemError,
669 "Couldn't get thread-state dictionary");
670 goto err;
671 }
672
673 ldict = PyDict_New();
674 if (ldict == NULL)
675 goto err;
676 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
677 if (dummy == NULL)
678 goto err;
679 dummy->localdict = ldict;
680 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
681 if (wr == NULL)
682 goto err;
683
684 /* As a side-effect, this will cache the weakref's hash before the
685 dummy gets deleted */
686 r = PyDict_SetItem(self->dummies, wr, ldict);
687 if (r < 0)
688 goto err;
689 Py_CLEAR(wr);
690 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
691 if (r < 0)
692 goto err;
693 Py_CLEAR(dummy);
694
695 Py_DECREF(ldict);
696 return ldict;
697
698 err:
699 Py_XDECREF(ldict);
700 Py_XDECREF(wr);
701 Py_XDECREF(dummy);
702 return NULL;
703 }
704
705 static PyObject *
local_new(PyTypeObject * type,PyObject * args,PyObject * kw)706 local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
707 {
708 localobject *self;
709 PyObject *wr;
710 static PyMethodDef wr_callback_def = {
711 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
712 };
713
714 if (type->tp_init == PyBaseObject_Type.tp_init) {
715 int rc = 0;
716 if (args != NULL)
717 rc = PyObject_IsTrue(args);
718 if (rc == 0 && kw != NULL)
719 rc = PyObject_IsTrue(kw);
720 if (rc != 0) {
721 if (rc > 0)
722 PyErr_SetString(PyExc_TypeError,
723 "Initialization arguments are not supported");
724 return NULL;
725 }
726 }
727
728 self = (localobject *)type->tp_alloc(type, 0);
729 if (self == NULL)
730 return NULL;
731
732 Py_XINCREF(args);
733 self->args = args;
734 Py_XINCREF(kw);
735 self->kw = kw;
736 self->key = PyUnicode_FromFormat("thread.local.%p", self);
737 if (self->key == NULL)
738 goto err;
739
740 self->dummies = PyDict_New();
741 if (self->dummies == NULL)
742 goto err;
743
744 /* We use a weak reference to self in the callback closure
745 in order to avoid spurious reference cycles */
746 wr = PyWeakref_NewRef((PyObject *) self, NULL);
747 if (wr == NULL)
748 goto err;
749 self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL);
750 Py_DECREF(wr);
751 if (self->wr_callback == NULL)
752 goto err;
753
754 if (_local_create_dummy(self) == NULL)
755 goto err;
756
757 return (PyObject *)self;
758
759 err:
760 Py_DECREF(self);
761 return NULL;
762 }
763
764 static int
local_traverse(localobject * self,visitproc visit,void * arg)765 local_traverse(localobject *self, visitproc visit, void *arg)
766 {
767 Py_VISIT(self->args);
768 Py_VISIT(self->kw);
769 Py_VISIT(self->dummies);
770 return 0;
771 }
772
773 static int
local_clear(localobject * self)774 local_clear(localobject *self)
775 {
776 PyThreadState *tstate;
777 Py_CLEAR(self->args);
778 Py_CLEAR(self->kw);
779 Py_CLEAR(self->dummies);
780 Py_CLEAR(self->wr_callback);
781 /* Remove all strong references to dummies from the thread states */
782 if (self->key
783 && (tstate = PyThreadState_Get())
784 && tstate->interp) {
785 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
786 tstate;
787 tstate = PyThreadState_Next(tstate))
788 if (tstate->dict &&
789 PyDict_GetItem(tstate->dict, self->key))
790 PyDict_DelItem(tstate->dict, self->key);
791 }
792 return 0;
793 }
794
795 static void
local_dealloc(localobject * self)796 local_dealloc(localobject *self)
797 {
798 /* Weakrefs must be invalidated right now, otherwise they can be used
799 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
800 if (self->weakreflist != NULL)
801 PyObject_ClearWeakRefs((PyObject *) self);
802
803 PyObject_GC_UnTrack(self);
804
805 local_clear(self);
806 Py_XDECREF(self->key);
807 Py_TYPE(self)->tp_free((PyObject*)self);
808 }
809
810 /* Returns a borrowed reference to the local dict, creating it if necessary */
811 static PyObject *
_ldict(localobject * self)812 _ldict(localobject *self)
813 {
814 PyObject *tdict, *ldict, *dummy;
815
816 tdict = PyThreadState_GetDict();
817 if (tdict == NULL) {
818 PyErr_SetString(PyExc_SystemError,
819 "Couldn't get thread-state dictionary");
820 return NULL;
821 }
822
823 dummy = PyDict_GetItem(tdict, self->key);
824 if (dummy == NULL) {
825 ldict = _local_create_dummy(self);
826 if (ldict == NULL)
827 return NULL;
828
829 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
830 Py_TYPE(self)->tp_init((PyObject*)self,
831 self->args, self->kw) < 0) {
832 /* we need to get rid of ldict from thread so
833 we create a new one the next time we do an attr
834 access */
835 PyDict_DelItem(tdict, self->key);
836 return NULL;
837 }
838 }
839 else {
840 assert(Py_TYPE(dummy) == &localdummytype);
841 ldict = ((localdummyobject *) dummy)->localdict;
842 }
843
844 return ldict;
845 }
846
847 static int
local_setattro(localobject * self,PyObject * name,PyObject * v)848 local_setattro(localobject *self, PyObject *name, PyObject *v)
849 {
850 PyObject *ldict;
851 int r;
852
853 ldict = _ldict(self);
854 if (ldict == NULL)
855 return -1;
856
857 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
858 if (r == 1) {
859 PyErr_Format(PyExc_AttributeError,
860 "'%.50s' object attribute '%U' is read-only",
861 Py_TYPE(self)->tp_name, name);
862 return -1;
863 }
864 if (r == -1)
865 return -1;
866
867 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
868 }
869
870 static PyObject *local_getattro(localobject *, PyObject *);
871
872 static PyTypeObject localtype = {
873 PyVarObject_HEAD_INIT(NULL, 0)
874 /* tp_name */ "_thread._local",
875 /* tp_basicsize */ sizeof(localobject),
876 /* tp_itemsize */ 0,
877 /* tp_dealloc */ (destructor)local_dealloc,
878 /* tp_print */ 0,
879 /* tp_getattr */ 0,
880 /* tp_setattr */ 0,
881 /* tp_reserved */ 0,
882 /* tp_repr */ 0,
883 /* tp_as_number */ 0,
884 /* tp_as_sequence */ 0,
885 /* tp_as_mapping */ 0,
886 /* tp_hash */ 0,
887 /* tp_call */ 0,
888 /* tp_str */ 0,
889 /* tp_getattro */ (getattrofunc)local_getattro,
890 /* tp_setattro */ (setattrofunc)local_setattro,
891 /* tp_as_buffer */ 0,
892 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
893 | Py_TPFLAGS_HAVE_GC,
894 /* tp_doc */ "Thread-local data",
895 /* tp_traverse */ (traverseproc)local_traverse,
896 /* tp_clear */ (inquiry)local_clear,
897 /* tp_richcompare */ 0,
898 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
899 /* tp_iter */ 0,
900 /* tp_iternext */ 0,
901 /* tp_methods */ 0,
902 /* tp_members */ 0,
903 /* tp_getset */ 0,
904 /* tp_base */ 0,
905 /* tp_dict */ 0, /* internal use */
906 /* tp_descr_get */ 0,
907 /* tp_descr_set */ 0,
908 /* tp_dictoffset */ 0,
909 /* tp_init */ 0,
910 /* tp_alloc */ 0,
911 /* tp_new */ local_new,
912 /* tp_free */ 0, /* Low-level free-mem routine */
913 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
914 };
915
916 static PyObject *
local_getattro(localobject * self,PyObject * name)917 local_getattro(localobject *self, PyObject *name)
918 {
919 PyObject *ldict, *value;
920 int r;
921
922 ldict = _ldict(self);
923 if (ldict == NULL)
924 return NULL;
925
926 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
927 if (r == 1) {
928 Py_INCREF(ldict);
929 return ldict;
930 }
931 if (r == -1)
932 return NULL;
933
934 if (Py_TYPE(self) != &localtype)
935 /* use generic lookup for subtypes */
936 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
937
938 /* Optimization: just look in dict ourselves */
939 value = PyDict_GetItem(ldict, name);
940 if (value == NULL)
941 /* Fall back on generic to get __class__ and __dict__ */
942 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
943
944 Py_INCREF(value);
945 return value;
946 }
947
948 /* Called when a dummy is destroyed. */
949 static PyObject *
_localdummy_destroyed(PyObject * localweakref,PyObject * dummyweakref)950 _localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
951 {
952 PyObject *obj;
953 localobject *self;
954 assert(PyWeakref_CheckRef(localweakref));
955 obj = PyWeakref_GET_OBJECT(localweakref);
956 if (obj == Py_None)
957 Py_RETURN_NONE;
958 Py_INCREF(obj);
959 assert(PyObject_TypeCheck(obj, &localtype));
960 /* If the thread-local object is still alive and not being cleared,
961 remove the corresponding local dict */
962 self = (localobject *) obj;
963 if (self->dummies != NULL) {
964 PyObject *ldict;
965 ldict = PyDict_GetItem(self->dummies, dummyweakref);
966 if (ldict != NULL) {
967 PyDict_DelItem(self->dummies, dummyweakref);
968 }
969 if (PyErr_Occurred())
970 PyErr_WriteUnraisable(obj);
971 }
972 Py_DECREF(obj);
973 Py_RETURN_NONE;
974 }
975
976 /* Module functions */
977
978 struct bootstate {
979 PyInterpreterState *interp;
980 PyObject *func;
981 PyObject *args;
982 PyObject *keyw;
983 PyThreadState *tstate;
984 };
985
986 static void
t_bootstrap(void * boot_raw)987 t_bootstrap(void *boot_raw)
988 {
989 struct bootstate *boot = (struct bootstate *) boot_raw;
990 PyThreadState *tstate;
991 PyObject *res;
992
993 tstate = boot->tstate;
994 tstate->thread_id = PyThread_get_thread_ident();
995 _PyThreadState_Init(tstate);
996 PyEval_AcquireThread(tstate);
997 nb_threads++;
998 res = PyEval_CallObjectWithKeywords(
999 boot->func, boot->args, boot->keyw);
1000 if (res == NULL) {
1001 if (PyErr_ExceptionMatches(PyExc_SystemExit))
1002 PyErr_Clear();
1003 else {
1004 PyObject *file;
1005 PyObject *exc, *value, *tb;
1006 PySys_WriteStderr(
1007 "Unhandled exception in thread started by ");
1008 PyErr_Fetch(&exc, &value, &tb);
1009 file = _PySys_GetObjectId(&PyId_stderr);
1010 if (file != NULL && file != Py_None)
1011 PyFile_WriteObject(boot->func, file, 0);
1012 else
1013 PyObject_Print(boot->func, stderr, 0);
1014 PySys_WriteStderr("\n");
1015 PyErr_Restore(exc, value, tb);
1016 PyErr_PrintEx(0);
1017 }
1018 }
1019 else
1020 Py_DECREF(res);
1021 Py_DECREF(boot->func);
1022 Py_DECREF(boot->args);
1023 Py_XDECREF(boot->keyw);
1024 PyMem_DEL(boot_raw);
1025 nb_threads--;
1026 PyThreadState_Clear(tstate);
1027 PyThreadState_DeleteCurrent();
1028 PyThread_exit_thread();
1029 }
1030
1031 static PyObject *
thread_PyThread_start_new_thread(PyObject * self,PyObject * fargs)1032 thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
1033 {
1034 PyObject *func, *args, *keyw = NULL;
1035 struct bootstate *boot;
1036 long ident;
1037
1038 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
1039 &func, &args, &keyw))
1040 return NULL;
1041 if (!PyCallable_Check(func)) {
1042 PyErr_SetString(PyExc_TypeError,
1043 "first arg must be callable");
1044 return NULL;
1045 }
1046 if (!PyTuple_Check(args)) {
1047 PyErr_SetString(PyExc_TypeError,
1048 "2nd arg must be a tuple");
1049 return NULL;
1050 }
1051 if (keyw != NULL && !PyDict_Check(keyw)) {
1052 PyErr_SetString(PyExc_TypeError,
1053 "optional 3rd arg must be a dictionary");
1054 return NULL;
1055 }
1056 boot = PyMem_NEW(struct bootstate, 1);
1057 if (boot == NULL)
1058 return PyErr_NoMemory();
1059 boot->interp = PyThreadState_GET()->interp;
1060 boot->func = func;
1061 boot->args = args;
1062 boot->keyw = keyw;
1063 boot->tstate = _PyThreadState_Prealloc(boot->interp);
1064 if (boot->tstate == NULL) {
1065 PyMem_DEL(boot);
1066 return PyErr_NoMemory();
1067 }
1068 Py_INCREF(func);
1069 Py_INCREF(args);
1070 Py_XINCREF(keyw);
1071 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
1072 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
1073 if (ident == -1) {
1074 PyErr_SetString(ThreadError, "can't start new thread");
1075 Py_DECREF(func);
1076 Py_DECREF(args);
1077 Py_XDECREF(keyw);
1078 PyThreadState_Clear(boot->tstate);
1079 PyMem_DEL(boot);
1080 return NULL;
1081 }
1082 return PyLong_FromLong(ident);
1083 }
1084
1085 PyDoc_STRVAR(start_new_doc,
1086 "start_new_thread(function, args[, kwargs])\n\
1087 (start_new() is an obsolete synonym)\n\
1088 \n\
1089 Start a new thread and return its identifier. The thread will call the\n\
1090 function with positional arguments from the tuple args and keyword arguments\n\
1091 taken from the optional dictionary kwargs. The thread exits when the\n\
1092 function returns; the return value is ignored. The thread will also exit\n\
1093 when the function raises an unhandled exception; a stack trace will be\n\
1094 printed unless the exception is SystemExit.\n");
1095
1096 static PyObject *
thread_PyThread_exit_thread(PyObject * self)1097 thread_PyThread_exit_thread(PyObject *self)
1098 {
1099 PyErr_SetNone(PyExc_SystemExit);
1100 return NULL;
1101 }
1102
1103 PyDoc_STRVAR(exit_doc,
1104 "exit()\n\
1105 (exit_thread() is an obsolete synonym)\n\
1106 \n\
1107 This is synonymous to ``raise SystemExit''. It will cause the current\n\
1108 thread to exit silently unless the exception is caught.");
1109
1110 static PyObject *
thread_PyThread_interrupt_main(PyObject * self)1111 thread_PyThread_interrupt_main(PyObject * self)
1112 {
1113 PyErr_SetInterrupt();
1114 Py_INCREF(Py_None);
1115 return Py_None;
1116 }
1117
1118 PyDoc_STRVAR(interrupt_doc,
1119 "interrupt_main()\n\
1120 \n\
1121 Raise a KeyboardInterrupt in the main thread.\n\
1122 A subthread can use this function to interrupt the main thread."
1123 );
1124
1125 static lockobject *newlockobject(void);
1126
1127 static PyObject *
thread_PyThread_allocate_lock(PyObject * self)1128 thread_PyThread_allocate_lock(PyObject *self)
1129 {
1130 return (PyObject *) newlockobject();
1131 }
1132
1133 PyDoc_STRVAR(allocate_doc,
1134 "allocate_lock() -> lock object\n\
1135 (allocate() is an obsolete synonym)\n\
1136 \n\
1137 Create a new lock object. See help(type(threading.Lock())) for\n\
1138 information about locks.");
1139
1140 static PyObject *
thread_get_ident(PyObject * self)1141 thread_get_ident(PyObject *self)
1142 {
1143 long ident;
1144 ident = PyThread_get_thread_ident();
1145 if (ident == -1) {
1146 PyErr_SetString(ThreadError, "no current thread ident");
1147 return NULL;
1148 }
1149 return PyLong_FromLong(ident);
1150 }
1151
1152 PyDoc_STRVAR(get_ident_doc,
1153 "get_ident() -> integer\n\
1154 \n\
1155 Return a non-zero integer that uniquely identifies the current thread\n\
1156 amongst other threads that exist simultaneously.\n\
1157 This may be used to identify per-thread resources.\n\
1158 Even though on some platforms threads identities may appear to be\n\
1159 allocated consecutive numbers starting at 1, this behavior should not\n\
1160 be relied upon, and the number should be seen purely as a magic cookie.\n\
1161 A thread's identity may be reused for another thread after it exits.");
1162
1163 static PyObject *
thread__count(PyObject * self)1164 thread__count(PyObject *self)
1165 {
1166 return PyLong_FromLong(nb_threads);
1167 }
1168
1169 PyDoc_STRVAR(_count_doc,
1170 "_count() -> integer\n\
1171 \n\
1172 \
1173 Return the number of currently running Python threads, excluding \n\
1174 the main thread. The returned number comprises all threads created\n\
1175 through `start_new_thread()` as well as `threading.Thread`, and not\n\
1176 yet finished.\n\
1177 \n\
1178 This function is meant for internal and specialized purposes only.\n\
1179 In most applications `threading.enumerate()` should be used instead.");
1180
1181 static void
release_sentinel(void * wr)1182 release_sentinel(void *wr)
1183 {
1184 /* Tricky: this function is called when the current thread state
1185 is being deleted. Therefore, only simple C code can safely
1186 execute here. */
1187 PyObject *obj = PyWeakref_GET_OBJECT(wr);
1188 lockobject *lock;
1189 if (obj != Py_None) {
1190 assert(Py_TYPE(obj) == &Locktype);
1191 lock = (lockobject *) obj;
1192 if (lock->locked) {
1193 PyThread_release_lock(lock->lock_lock);
1194 lock->locked = 0;
1195 }
1196 }
1197 /* Deallocating a weakref with a NULL callback only calls
1198 PyObject_GC_Del(), which can't call any Python code. */
1199 Py_DECREF(wr);
1200 }
1201
1202 static PyObject *
thread__set_sentinel(PyObject * self)1203 thread__set_sentinel(PyObject *self)
1204 {
1205 PyObject *wr;
1206 PyThreadState *tstate = PyThreadState_Get();
1207 lockobject *lock;
1208
1209 if (tstate->on_delete_data != NULL) {
1210 /* We must support the re-creation of the lock from a
1211 fork()ed child. */
1212 assert(tstate->on_delete == &release_sentinel);
1213 wr = (PyObject *) tstate->on_delete_data;
1214 tstate->on_delete = NULL;
1215 tstate->on_delete_data = NULL;
1216 Py_DECREF(wr);
1217 }
1218 lock = newlockobject();
1219 if (lock == NULL)
1220 return NULL;
1221 /* The lock is owned by whoever called _set_sentinel(), but the weakref
1222 hangs to the thread state. */
1223 wr = PyWeakref_NewRef((PyObject *) lock, NULL);
1224 if (wr == NULL) {
1225 Py_DECREF(lock);
1226 return NULL;
1227 }
1228 tstate->on_delete_data = (void *) wr;
1229 tstate->on_delete = &release_sentinel;
1230 return (PyObject *) lock;
1231 }
1232
1233 PyDoc_STRVAR(_set_sentinel_doc,
1234 "_set_sentinel() -> lock\n\
1235 \n\
1236 Set a sentinel lock that will be released when the current thread\n\
1237 state is finalized (after it is untied from the interpreter).\n\
1238 \n\
1239 This is a private API for the threading module.");
1240
1241 static PyObject *
thread_stack_size(PyObject * self,PyObject * args)1242 thread_stack_size(PyObject *self, PyObject *args)
1243 {
1244 size_t old_size;
1245 Py_ssize_t new_size = 0;
1246 int rc;
1247
1248 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1249 return NULL;
1250
1251 if (new_size < 0) {
1252 PyErr_SetString(PyExc_ValueError,
1253 "size must be 0 or a positive value");
1254 return NULL;
1255 }
1256
1257 old_size = PyThread_get_stacksize();
1258
1259 rc = PyThread_set_stacksize((size_t) new_size);
1260 if (rc == -1) {
1261 PyErr_Format(PyExc_ValueError,
1262 "size not valid: %zd bytes",
1263 new_size);
1264 return NULL;
1265 }
1266 if (rc == -2) {
1267 PyErr_SetString(ThreadError,
1268 "setting stack size not supported");
1269 return NULL;
1270 }
1271
1272 return PyLong_FromSsize_t((Py_ssize_t) old_size);
1273 }
1274
1275 PyDoc_STRVAR(stack_size_doc,
1276 "stack_size([size]) -> size\n\
1277 \n\
1278 Return the thread stack size used when creating new threads. The\n\
1279 optional size argument specifies the stack size (in bytes) to be used\n\
1280 for subsequently created threads, and must be 0 (use platform or\n\
1281 configured default) or a positive integer value of at least 32,768 (32k).\n\
1282 If changing the thread stack size is unsupported, a ThreadError\n\
1283 exception is raised. If the specified size is invalid, a ValueError\n\
1284 exception is raised, and the stack size is unmodified. 32k bytes\n\
1285 currently the minimum supported stack size value to guarantee\n\
1286 sufficient stack space for the interpreter itself.\n\
1287 \n\
1288 Note that some platforms may have particular restrictions on values for\n\
1289 the stack size, such as requiring a minimum stack size larger than 32kB or\n\
1290 requiring allocation in multiples of the system memory page size\n\
1291 - platform documentation should be referred to for more information\n\
1292 (4kB pages are common; using multiples of 4096 for the stack size is\n\
1293 the suggested approach in the absence of more specific information).");
1294
1295 static PyMethodDef thread_methods[] = {
1296 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
1297 METH_VARARGS, start_new_doc},
1298 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
1299 METH_VARARGS, start_new_doc},
1300 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
1301 METH_NOARGS, allocate_doc},
1302 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
1303 METH_NOARGS, allocate_doc},
1304 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
1305 METH_NOARGS, exit_doc},
1306 {"exit", (PyCFunction)thread_PyThread_exit_thread,
1307 METH_NOARGS, exit_doc},
1308 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
1309 METH_NOARGS, interrupt_doc},
1310 {"get_ident", (PyCFunction)thread_get_ident,
1311 METH_NOARGS, get_ident_doc},
1312 {"_count", (PyCFunction)thread__count,
1313 METH_NOARGS, _count_doc},
1314 {"stack_size", (PyCFunction)thread_stack_size,
1315 METH_VARARGS, stack_size_doc},
1316 {"_set_sentinel", (PyCFunction)thread__set_sentinel,
1317 METH_NOARGS, _set_sentinel_doc},
1318 {NULL, NULL} /* sentinel */
1319 };
1320
1321
1322 /* Initialization function */
1323
1324 PyDoc_STRVAR(thread_doc,
1325 "This module provides primitive operations to write multi-threaded programs.\n\
1326 The 'threading' module provides a more convenient interface.");
1327
1328 PyDoc_STRVAR(lock_doc,
1329 "A lock object is a synchronization primitive. To create a lock,\n\
1330 call threading.Lock(). Methods are:\n\
1331 \n\
1332 acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1333 release() -- unlock of the lock\n\
1334 locked() -- test whether the lock is currently locked\n\
1335 \n\
1336 A lock is not owned by the thread that locked it; another thread may\n\
1337 unlock it. A thread attempting to lock a lock that it has already locked\n\
1338 will block until another thread unlocks it. Deadlocks may ensue.");
1339
1340 static struct PyModuleDef threadmodule = {
1341 PyModuleDef_HEAD_INIT,
1342 "_thread",
1343 thread_doc,
1344 -1,
1345 thread_methods,
1346 NULL,
1347 NULL,
1348 NULL,
1349 NULL
1350 };
1351
1352
1353 PyMODINIT_FUNC
PyInit__thread(void)1354 PyInit__thread(void)
1355 {
1356 PyObject *m, *d, *v;
1357 double time_max;
1358 double timeout_max;
1359
1360 /* Initialize types: */
1361 if (PyType_Ready(&localdummytype) < 0)
1362 return NULL;
1363 if (PyType_Ready(&localtype) < 0)
1364 return NULL;
1365 if (PyType_Ready(&Locktype) < 0)
1366 return NULL;
1367 if (PyType_Ready(&RLocktype) < 0)
1368 return NULL;
1369
1370 /* Create the module and add the functions */
1371 m = PyModule_Create(&threadmodule);
1372 if (m == NULL)
1373 return NULL;
1374
1375 timeout_max = PY_TIMEOUT_MAX / 1000000;
1376 time_max = floor(_PyTime_AsSecondsDouble(_PyTime_MAX));
1377 timeout_max = Py_MIN(timeout_max, time_max);
1378
1379 v = PyFloat_FromDouble(timeout_max);
1380 if (!v)
1381 return NULL;
1382 if (PyModule_AddObject(m, "TIMEOUT_MAX", v) < 0)
1383 return NULL;
1384
1385 /* Add a symbolic constant */
1386 d = PyModule_GetDict(m);
1387 ThreadError = PyExc_RuntimeError;
1388 Py_INCREF(ThreadError);
1389
1390 PyDict_SetItemString(d, "error", ThreadError);
1391 Locktype.tp_doc = lock_doc;
1392 Py_INCREF(&Locktype);
1393 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
1394
1395 Py_INCREF(&RLocktype);
1396 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1397 return NULL;
1398
1399 Py_INCREF(&localtype);
1400 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1401 return NULL;
1402
1403 nb_threads = 0;
1404
1405 str_dict = PyUnicode_InternFromString("__dict__");
1406 if (str_dict == NULL)
1407 return NULL;
1408
1409 /* Initialize the C thread library */
1410 PyThread_init_thread();
1411 return m;
1412 }
1413