Added updates with respect to recent changes to TimedRotatingFileHandler.
[python.git] / Modules / threadmodule.c
blob81bf2882047bee2c6756422f3b19ef38e8a43fa8
2 /* Thread module */
3 /* Interface to Sjoerd's portable C thread library */
5 #include "Python.h"
7 #ifndef WITH_THREAD
8 #error "Error! The rest of Python is not compiled with thread support."
9 #error "Rerun configure, adding a --with-threads option."
10 #error "Then run `make clean' followed by `make'."
11 #endif
13 #include "pythread.h"
15 static PyObject *ThreadError;
18 /* Lock objects */
20 typedef struct {
21 PyObject_HEAD
22 PyThread_type_lock lock_lock;
23 } lockobject;
25 static void
26 lock_dealloc(lockobject *self)
28 assert(self->lock_lock);
29 /* Unlock the lock so it's safe to free it */
30 PyThread_acquire_lock(self->lock_lock, 0);
31 PyThread_release_lock(self->lock_lock);
33 PyThread_free_lock(self->lock_lock);
34 PyObject_Del(self);
37 static PyObject *
38 lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
40 int i = 1;
42 if (!PyArg_ParseTuple(args, "|i:acquire", &i))
43 return NULL;
45 Py_BEGIN_ALLOW_THREADS
46 i = PyThread_acquire_lock(self->lock_lock, i);
47 Py_END_ALLOW_THREADS
49 return PyBool_FromLong((long)i);
52 PyDoc_STRVAR(acquire_doc,
53 "acquire([wait]) -> None or bool\n\
54 (acquire_lock() is an obsolete synonym)\n\
55 \n\
56 Lock the lock. Without argument, this blocks if the lock is already\n\
57 locked (even by the same thread), waiting for another thread to release\n\
58 the lock, and return None once the lock is acquired.\n\
59 With an argument, this will only block if the argument is true,\n\
60 and the return value reflects whether the lock is acquired.\n\
61 The blocking operation is not interruptible.");
63 static PyObject *
64 lock_PyThread_release_lock(lockobject *self)
66 /* Sanity check: the lock must be locked */
67 if (PyThread_acquire_lock(self->lock_lock, 0)) {
68 PyThread_release_lock(self->lock_lock);
69 PyErr_SetString(ThreadError, "release unlocked lock");
70 return NULL;
73 PyThread_release_lock(self->lock_lock);
74 Py_INCREF(Py_None);
75 return Py_None;
78 PyDoc_STRVAR(release_doc,
79 "release()\n\
80 (release_lock() is an obsolete synonym)\n\
81 \n\
82 Release the lock, allowing another thread that is blocked waiting for\n\
83 the lock to acquire the lock. The lock must be in the locked state,\n\
84 but it needn't be locked by the same thread that unlocks it.");
86 static PyObject *
87 lock_locked_lock(lockobject *self)
89 if (PyThread_acquire_lock(self->lock_lock, 0)) {
90 PyThread_release_lock(self->lock_lock);
91 return PyBool_FromLong(0L);
93 return PyBool_FromLong(1L);
96 PyDoc_STRVAR(locked_doc,
97 "locked() -> bool\n\
98 (locked_lock() is an obsolete synonym)\n\
99 \n\
100 Return whether the lock is in the locked state.");
102 static PyMethodDef lock_methods[] = {
103 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
104 METH_VARARGS, acquire_doc},
105 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
106 METH_VARARGS, acquire_doc},
107 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
108 METH_NOARGS, release_doc},
109 {"release", (PyCFunction)lock_PyThread_release_lock,
110 METH_NOARGS, release_doc},
111 {"locked_lock", (PyCFunction)lock_locked_lock,
112 METH_NOARGS, locked_doc},
113 {"locked", (PyCFunction)lock_locked_lock,
114 METH_NOARGS, locked_doc},
115 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
116 METH_VARARGS, acquire_doc},
117 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
118 METH_VARARGS, release_doc},
119 {NULL, NULL} /* sentinel */
122 static PyObject *
123 lock_getattr(lockobject *self, char *name)
125 return Py_FindMethod(lock_methods, (PyObject *)self, name);
128 static PyTypeObject Locktype = {
129 PyVarObject_HEAD_INIT(&PyType_Type, 0)
130 "thread.lock", /*tp_name*/
131 sizeof(lockobject), /*tp_size*/
132 0, /*tp_itemsize*/
133 /* methods */
134 (destructor)lock_dealloc, /*tp_dealloc*/
135 0, /*tp_print*/
136 (getattrfunc)lock_getattr, /*tp_getattr*/
137 0, /*tp_setattr*/
138 0, /*tp_compare*/
139 0, /*tp_repr*/
142 static lockobject *
143 newlockobject(void)
145 lockobject *self;
146 self = PyObject_New(lockobject, &Locktype);
147 if (self == NULL)
148 return NULL;
149 self->lock_lock = PyThread_allocate_lock();
150 if (self->lock_lock == NULL) {
151 PyObject_Del(self);
152 self = NULL;
153 PyErr_SetString(ThreadError, "can't allocate lock");
155 return self;
158 /* Thread-local objects */
160 #include "structmember.h"
162 typedef struct {
163 PyObject_HEAD
164 PyObject *key;
165 PyObject *args;
166 PyObject *kw;
167 PyObject *dict;
168 } localobject;
170 static PyObject *
171 local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
173 localobject *self;
174 PyObject *tdict;
176 if (type->tp_init == PyBaseObject_Type.tp_init
177 && ((args && PyObject_IsTrue(args))
178 || (kw && PyObject_IsTrue(kw)))) {
179 PyErr_SetString(PyExc_TypeError,
180 "Initialization arguments are not supported");
181 return NULL;
184 self = (localobject *)type->tp_alloc(type, 0);
185 if (self == NULL)
186 return NULL;
188 Py_XINCREF(args);
189 self->args = args;
190 Py_XINCREF(kw);
191 self->kw = kw;
192 self->dict = NULL; /* making sure */
193 self->key = PyString_FromFormat("thread.local.%p", self);
194 if (self->key == NULL)
195 goto err;
197 self->dict = PyDict_New();
198 if (self->dict == NULL)
199 goto err;
201 tdict = PyThreadState_GetDict();
202 if (tdict == NULL) {
203 PyErr_SetString(PyExc_SystemError,
204 "Couldn't get thread-state dictionary");
205 goto err;
208 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
209 goto err;
211 return (PyObject *)self;
213 err:
214 Py_DECREF(self);
215 return NULL;
218 static int
219 local_traverse(localobject *self, visitproc visit, void *arg)
221 Py_VISIT(self->args);
222 Py_VISIT(self->kw);
223 Py_VISIT(self->dict);
224 return 0;
227 static int
228 local_clear(localobject *self)
230 Py_CLEAR(self->key);
231 Py_CLEAR(self->args);
232 Py_CLEAR(self->kw);
233 Py_CLEAR(self->dict);
234 return 0;
237 static void
238 local_dealloc(localobject *self)
240 PyThreadState *tstate;
241 if (self->key
242 && (tstate = PyThreadState_Get())
243 && tstate->interp) {
244 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
245 tstate;
246 tstate = PyThreadState_Next(tstate))
247 if (tstate->dict &&
248 PyDict_GetItem(tstate->dict, self->key))
249 PyDict_DelItem(tstate->dict, self->key);
252 local_clear(self);
253 Py_TYPE(self)->tp_free((PyObject*)self);
256 static PyObject *
257 _ldict(localobject *self)
259 PyObject *tdict, *ldict;
261 tdict = PyThreadState_GetDict();
262 if (tdict == NULL) {
263 PyErr_SetString(PyExc_SystemError,
264 "Couldn't get thread-state dictionary");
265 return NULL;
268 ldict = PyDict_GetItem(tdict, self->key);
269 if (ldict == NULL) {
270 ldict = PyDict_New(); /* we own ldict */
272 if (ldict == NULL)
273 return NULL;
274 else {
275 int i = PyDict_SetItem(tdict, self->key, ldict);
276 Py_DECREF(ldict); /* now ldict is borrowed */
277 if (i < 0)
278 return NULL;
281 Py_CLEAR(self->dict);
282 Py_INCREF(ldict);
283 self->dict = ldict; /* still borrowed */
285 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
286 Py_TYPE(self)->tp_init((PyObject*)self,
287 self->args, self->kw) < 0) {
288 /* we need to get rid of ldict from thread so
289 we create a new one the next time we do an attr
290 acces */
291 PyDict_DelItem(tdict, self->key);
292 return NULL;
296 else if (self->dict != ldict) {
297 Py_CLEAR(self->dict);
298 Py_INCREF(ldict);
299 self->dict = ldict;
302 return ldict;
305 static int
306 local_setattro(localobject *self, PyObject *name, PyObject *v)
308 PyObject *ldict;
310 ldict = _ldict(self);
311 if (ldict == NULL)
312 return -1;
314 return PyObject_GenericSetAttr((PyObject *)self, name, v);
317 static PyObject *
318 local_getdict(localobject *self, void *closure)
320 if (self->dict == NULL) {
321 PyErr_SetString(PyExc_AttributeError, "__dict__");
322 return NULL;
325 Py_INCREF(self->dict);
326 return self->dict;
329 static PyGetSetDef local_getset[] = {
330 {"__dict__", (getter)local_getdict, (setter)NULL,
331 "Local-data dictionary", NULL},
332 {NULL} /* Sentinel */
335 static PyObject *local_getattro(localobject *, PyObject *);
337 static PyTypeObject localtype = {
338 PyVarObject_HEAD_INIT(NULL, 0)
339 /* tp_name */ "thread._local",
340 /* tp_basicsize */ sizeof(localobject),
341 /* tp_itemsize */ 0,
342 /* tp_dealloc */ (destructor)local_dealloc,
343 /* tp_print */ 0,
344 /* tp_getattr */ 0,
345 /* tp_setattr */ 0,
346 /* tp_compare */ 0,
347 /* tp_repr */ 0,
348 /* tp_as_number */ 0,
349 /* tp_as_sequence */ 0,
350 /* tp_as_mapping */ 0,
351 /* tp_hash */ 0,
352 /* tp_call */ 0,
353 /* tp_str */ 0,
354 /* tp_getattro */ (getattrofunc)local_getattro,
355 /* tp_setattro */ (setattrofunc)local_setattro,
356 /* tp_as_buffer */ 0,
357 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
358 /* tp_doc */ "Thread-local data",
359 /* tp_traverse */ (traverseproc)local_traverse,
360 /* tp_clear */ (inquiry)local_clear,
361 /* tp_richcompare */ 0,
362 /* tp_weaklistoffset */ 0,
363 /* tp_iter */ 0,
364 /* tp_iternext */ 0,
365 /* tp_methods */ 0,
366 /* tp_members */ 0,
367 /* tp_getset */ local_getset,
368 /* tp_base */ 0,
369 /* tp_dict */ 0, /* internal use */
370 /* tp_descr_get */ 0,
371 /* tp_descr_set */ 0,
372 /* tp_dictoffset */ offsetof(localobject, dict),
373 /* tp_init */ 0,
374 /* tp_alloc */ 0,
375 /* tp_new */ local_new,
376 /* tp_free */ 0, /* Low-level free-mem routine */
377 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
380 static PyObject *
381 local_getattro(localobject *self, PyObject *name)
383 PyObject *ldict, *value;
385 ldict = _ldict(self);
386 if (ldict == NULL)
387 return NULL;
389 if (Py_TYPE(self) != &localtype)
390 /* use generic lookup for subtypes */
391 return PyObject_GenericGetAttr((PyObject *)self, name);
393 /* Optimization: just look in dict ourselves */
394 value = PyDict_GetItem(ldict, name);
395 if (value == NULL)
396 /* Fall back on generic to get __class__ and __dict__ */
397 return PyObject_GenericGetAttr((PyObject *)self, name);
399 Py_INCREF(value);
400 return value;
403 /* Module functions */
405 struct bootstate {
406 PyInterpreterState *interp;
407 PyObject *func;
408 PyObject *args;
409 PyObject *keyw;
412 static void
413 t_bootstrap(void *boot_raw)
415 struct bootstate *boot = (struct bootstate *) boot_raw;
416 PyThreadState *tstate;
417 PyObject *res;
419 tstate = PyThreadState_New(boot->interp);
421 PyEval_AcquireThread(tstate);
422 res = PyEval_CallObjectWithKeywords(
423 boot->func, boot->args, boot->keyw);
424 if (res == NULL) {
425 if (PyErr_ExceptionMatches(PyExc_SystemExit))
426 PyErr_Clear();
427 else {
428 PyObject *file;
429 PySys_WriteStderr(
430 "Unhandled exception in thread started by ");
431 file = PySys_GetObject("stderr");
432 if (file)
433 PyFile_WriteObject(boot->func, file, 0);
434 else
435 PyObject_Print(boot->func, stderr, 0);
436 PySys_WriteStderr("\n");
437 PyErr_PrintEx(0);
440 else
441 Py_DECREF(res);
442 Py_DECREF(boot->func);
443 Py_DECREF(boot->args);
444 Py_XDECREF(boot->keyw);
445 PyMem_DEL(boot_raw);
446 PyThreadState_Clear(tstate);
447 PyThreadState_DeleteCurrent();
448 PyThread_exit_thread();
451 static PyObject *
452 thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
454 PyObject *func, *args, *keyw = NULL;
455 struct bootstate *boot;
456 long ident;
458 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
459 &func, &args, &keyw))
460 return NULL;
461 if (!PyCallable_Check(func)) {
462 PyErr_SetString(PyExc_TypeError,
463 "first arg must be callable");
464 return NULL;
466 if (!PyTuple_Check(args)) {
467 PyErr_SetString(PyExc_TypeError,
468 "2nd arg must be a tuple");
469 return NULL;
471 if (keyw != NULL && !PyDict_Check(keyw)) {
472 PyErr_SetString(PyExc_TypeError,
473 "optional 3rd arg must be a dictionary");
474 return NULL;
476 boot = PyMem_NEW(struct bootstate, 1);
477 if (boot == NULL)
478 return PyErr_NoMemory();
479 boot->interp = PyThreadState_GET()->interp;
480 boot->func = func;
481 boot->args = args;
482 boot->keyw = keyw;
483 Py_INCREF(func);
484 Py_INCREF(args);
485 Py_XINCREF(keyw);
486 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
487 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
488 if (ident == -1) {
489 PyErr_SetString(ThreadError, "can't start new thread");
490 Py_DECREF(func);
491 Py_DECREF(args);
492 Py_XDECREF(keyw);
493 PyMem_DEL(boot);
494 return NULL;
496 return PyInt_FromLong(ident);
499 PyDoc_STRVAR(start_new_doc,
500 "start_new_thread(function, args[, kwargs])\n\
501 (start_new() is an obsolete synonym)\n\
503 Start a new thread and return its identifier. The thread will call the\n\
504 function with positional arguments from the tuple args and keyword arguments\n\
505 taken from the optional dictionary kwargs. The thread exits when the\n\
506 function returns; the return value is ignored. The thread will also exit\n\
507 when the function raises an unhandled exception; a stack trace will be\n\
508 printed unless the exception is SystemExit.\n");
510 static PyObject *
511 thread_PyThread_exit_thread(PyObject *self)
513 PyErr_SetNone(PyExc_SystemExit);
514 return NULL;
517 PyDoc_STRVAR(exit_doc,
518 "exit()\n\
519 (PyThread_exit_thread() is an obsolete synonym)\n\
521 This is synonymous to ``raise SystemExit''. It will cause the current\n\
522 thread to exit silently unless the exception is caught.");
524 static PyObject *
525 thread_PyThread_interrupt_main(PyObject * self)
527 PyErr_SetInterrupt();
528 Py_INCREF(Py_None);
529 return Py_None;
532 PyDoc_STRVAR(interrupt_doc,
533 "interrupt_main()\n\
535 Raise a KeyboardInterrupt in the main thread.\n\
536 A subthread can use this function to interrupt the main thread."
539 #ifndef NO_EXIT_PROG
540 static PyObject *
541 thread_PyThread_exit_prog(PyObject *self, PyObject *args)
543 int sts;
544 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
545 return NULL;
546 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
547 for (;;) { } /* Should not be reached */
549 #endif
551 static lockobject *newlockobject(void);
553 static PyObject *
554 thread_PyThread_allocate_lock(PyObject *self)
556 return (PyObject *) newlockobject();
559 PyDoc_STRVAR(allocate_doc,
560 "allocate_lock() -> lock object\n\
561 (allocate() is an obsolete synonym)\n\
563 Create a new lock object. See LockType.__doc__ for information about locks.");
565 static PyObject *
566 thread_get_ident(PyObject *self)
568 long ident;
569 ident = PyThread_get_thread_ident();
570 if (ident == -1) {
571 PyErr_SetString(ThreadError, "no current thread ident");
572 return NULL;
574 return PyInt_FromLong(ident);
577 PyDoc_STRVAR(get_ident_doc,
578 "get_ident() -> integer\n\
580 Return a non-zero integer that uniquely identifies the current thread\n\
581 amongst other threads that exist simultaneously.\n\
582 This may be used to identify per-thread resources.\n\
583 Even though on some platforms threads identities may appear to be\n\
584 allocated consecutive numbers starting at 1, this behavior should not\n\
585 be relied upon, and the number should be seen purely as a magic cookie.\n\
586 A thread's identity may be reused for another thread after it exits.");
588 static PyObject *
589 thread_stack_size(PyObject *self, PyObject *args)
591 size_t old_size;
592 Py_ssize_t new_size = 0;
593 int rc;
595 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
596 return NULL;
598 if (new_size < 0) {
599 PyErr_SetString(PyExc_ValueError,
600 "size must be 0 or a positive value");
601 return NULL;
604 old_size = PyThread_get_stacksize();
606 rc = PyThread_set_stacksize((size_t) new_size);
607 if (rc == -1) {
608 PyErr_Format(PyExc_ValueError,
609 "size not valid: %zd bytes",
610 new_size);
611 return NULL;
613 if (rc == -2) {
614 PyErr_SetString(ThreadError,
615 "setting stack size not supported");
616 return NULL;
619 return PyInt_FromSsize_t((Py_ssize_t) old_size);
622 PyDoc_STRVAR(stack_size_doc,
623 "stack_size([size]) -> size\n\
625 Return the thread stack size used when creating new threads. The\n\
626 optional size argument specifies the stack size (in bytes) to be used\n\
627 for subsequently created threads, and must be 0 (use platform or\n\
628 configured default) or a positive integer value of at least 32,768 (32k).\n\
629 If changing the thread stack size is unsupported, a ThreadError\n\
630 exception is raised. If the specified size is invalid, a ValueError\n\
631 exception is raised, and the stack size is unmodified. 32k bytes\n\
632 currently the minimum supported stack size value to guarantee\n\
633 sufficient stack space for the interpreter itself.\n\
635 Note that some platforms may have particular restrictions on values for\n\
636 the stack size, such as requiring a minimum stack size larger than 32kB or\n\
637 requiring allocation in multiples of the system memory page size\n\
638 - platform documentation should be referred to for more information\n\
639 (4kB pages are common; using multiples of 4096 for the stack size is\n\
640 the suggested approach in the absence of more specific information).");
642 static PyMethodDef thread_methods[] = {
643 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
644 METH_VARARGS,
645 start_new_doc},
646 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
647 METH_VARARGS,
648 start_new_doc},
649 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
650 METH_NOARGS, allocate_doc},
651 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
652 METH_NOARGS, allocate_doc},
653 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
654 METH_NOARGS, exit_doc},
655 {"exit", (PyCFunction)thread_PyThread_exit_thread,
656 METH_NOARGS, exit_doc},
657 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
658 METH_NOARGS, interrupt_doc},
659 {"get_ident", (PyCFunction)thread_get_ident,
660 METH_NOARGS, get_ident_doc},
661 {"stack_size", (PyCFunction)thread_stack_size,
662 METH_VARARGS,
663 stack_size_doc},
664 #ifndef NO_EXIT_PROG
665 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
666 METH_VARARGS},
667 #endif
668 {NULL, NULL} /* sentinel */
672 /* Initialization function */
674 PyDoc_STRVAR(thread_doc,
675 "This module provides primitive operations to write multi-threaded programs.\n\
676 The 'threading' module provides a more convenient interface.");
678 PyDoc_STRVAR(lock_doc,
679 "A lock object is a synchronization primitive. To create a lock,\n\
680 call the PyThread_allocate_lock() function. Methods are:\n\
682 acquire() -- lock the lock, possibly blocking until it can be obtained\n\
683 release() -- unlock of the lock\n\
684 locked() -- test whether the lock is currently locked\n\
686 A lock is not owned by the thread that locked it; another thread may\n\
687 unlock it. A thread attempting to lock a lock that it has already locked\n\
688 will block until another thread unlocks it. Deadlocks may ensue.");
690 PyMODINIT_FUNC
691 initthread(void)
693 PyObject *m, *d;
695 /* Initialize types: */
696 if (PyType_Ready(&localtype) < 0)
697 return;
699 /* Create the module and add the functions */
700 m = Py_InitModule3("thread", thread_methods, thread_doc);
701 if (m == NULL)
702 return;
704 /* Add a symbolic constant */
705 d = PyModule_GetDict(m);
706 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
707 PyDict_SetItemString(d, "error", ThreadError);
708 Locktype.tp_doc = lock_doc;
709 Py_INCREF(&Locktype);
710 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
712 Py_INCREF(&localtype);
713 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
714 return;
716 /* Initialize the C thread library */
717 PyThread_init_thread();