blob: 016d5a0be78600d2dbcf294bb99332e5297da0d9 [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"
Gregory P. Smith4e63d542009-08-20 09:39:38 +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 Pitrou59c44f32009-10-30 17:07:08 +000017static long nb_threads = 0;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000018
19/* Lock objects */
20
21typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000022 PyObject_HEAD
23 PyThread_type_lock lock_lock;
24 PyObject *in_weakreflist;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000025} lockobject;
26
Guido van Rossum1984f1e1992-08-04 12:41:02 +000027static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000028lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000029{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000030 if (self->in_weakreflist != NULL)
31 PyObject_ClearWeakRefs((PyObject *) self);
32 if (self->lock_lock != NULL) {
33 /* Unlock the lock so it's safe to free it */
34 PyThread_acquire_lock(self->lock_lock, 0);
35 PyThread_release_lock(self->lock_lock);
36
37 PyThread_free_lock(self->lock_lock);
38 }
39 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000040}
41
Barry Warsawd0c10421996-12-17 00:05:22 +000042static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000043lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000044{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000045 int i = 1;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000046
Antoine Pitrouc83ea132010-05-09 14:46:46 +000047 if (!PyArg_ParseTuple(args, "|i:acquire", &i))
48 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000049
Antoine Pitrouc83ea132010-05-09 14:46:46 +000050 Py_BEGIN_ALLOW_THREADS
51 i = PyThread_acquire_lock(self->lock_lock, i);
52 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +000053
Antoine Pitrouc83ea132010-05-09 14:46:46 +000054 return PyBool_FromLong((long)i);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000055}
56
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000057PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000058"acquire([wait]) -> None or bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000059(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000060\n\
61Lock the lock. Without argument, this blocks if the lock is already\n\
62locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000063the lock, and return None once the lock is acquired.\n\
64With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000065and the return value reflects whether the lock is acquired.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000066The blocking operation is not interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000067
Barry Warsawd0c10421996-12-17 00:05:22 +000068static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000069lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000070{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000071 /* Sanity check: the lock must be locked */
72 if (PyThread_acquire_lock(self->lock_lock, 0)) {
73 PyThread_release_lock(self->lock_lock);
74 PyErr_SetString(ThreadError, "release unlocked lock");
75 return NULL;
76 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +000077
Antoine Pitrouc83ea132010-05-09 14:46:46 +000078 PyThread_release_lock(self->lock_lock);
79 Py_INCREF(Py_None);
80 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000081}
82
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000083PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +000084"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000085(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000086\n\
87Release the lock, allowing another thread that is blocked waiting for\n\
88the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000089but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000090
Barry Warsawd0c10421996-12-17 00:05:22 +000091static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000092lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000093{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000094 if (PyThread_acquire_lock(self->lock_lock, 0)) {
95 PyThread_release_lock(self->lock_lock);
96 return PyBool_FromLong(0L);
97 }
98 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000099}
100
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000101PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000102"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000103(locked_lock() is an obsolete synonym)\n\
104\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000105Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000106
Barry Warsawd0c10421996-12-17 00:05:22 +0000107static PyMethodDef lock_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000108 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
109 METH_VARARGS, acquire_doc},
110 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
111 METH_VARARGS, acquire_doc},
112 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
113 METH_NOARGS, release_doc},
114 {"release", (PyCFunction)lock_PyThread_release_lock,
115 METH_NOARGS, release_doc},
116 {"locked_lock", (PyCFunction)lock_locked_lock,
117 METH_NOARGS, locked_doc},
118 {"locked", (PyCFunction)lock_locked_lock,
119 METH_NOARGS, locked_doc},
120 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
121 METH_VARARGS, acquire_doc},
122 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
123 METH_VARARGS, release_doc},
124 {NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000125};
126
Barry Warsawd0c10421996-12-17 00:05:22 +0000127static PyTypeObject Locktype = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000128 PyVarObject_HEAD_INIT(&PyType_Type, 0)
129 "thread.lock", /*tp_name*/
130 sizeof(lockobject), /*tp_size*/
131 0, /*tp_itemsize*/
132 /* methods */
133 (destructor)lock_dealloc, /*tp_dealloc*/
134 0, /*tp_print*/
135 0, /*tp_getattr*/
136 0, /*tp_setattr*/
137 0, /*tp_compare*/
138 0, /*tp_repr*/
139 0, /* tp_as_number */
140 0, /* tp_as_sequence */
141 0, /* tp_as_mapping */
142 0, /* tp_hash */
143 0, /* tp_call */
144 0, /* tp_str */
145 0, /* tp_getattro */
146 0, /* tp_setattro */
147 0, /* tp_as_buffer */
148 Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
149 0, /* tp_doc */
150 0, /* tp_traverse */
151 0, /* tp_clear */
152 0, /* tp_richcompare */
153 offsetof(lockobject, in_weakreflist), /* tp_weaklistoffset */
154 0, /* tp_iter */
155 0, /* tp_iternext */
156 lock_methods, /* tp_methods */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000157};
158
Anthony Baxter5576b542006-04-12 04:08:46 +0000159static lockobject *
160newlockobject(void)
161{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000162 lockobject *self;
163 self = PyObject_New(lockobject, &Locktype);
164 if (self == NULL)
165 return NULL;
166 self->lock_lock = PyThread_allocate_lock();
167 self->in_weakreflist = NULL;
168 if (self->lock_lock == NULL) {
169 Py_DECREF(self);
170 PyErr_SetString(ThreadError, "can't allocate lock");
171 return NULL;
172 }
173 return self;
Anthony Baxter5576b542006-04-12 04:08:46 +0000174}
175
Jim Fultond15dc062004-07-14 19:11:50 +0000176/* Thread-local objects */
177
178#include "structmember.h"
179
180typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000181 PyObject_HEAD
182 PyObject *key;
183 PyObject *args;
184 PyObject *kw;
185 PyObject *dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000186} localobject;
187
Jim Fultond15dc062004-07-14 19:11:50 +0000188static PyObject *
189local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
190{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000191 localobject *self;
192 PyObject *tdict;
Jim Fultond15dc062004-07-14 19:11:50 +0000193
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000194 if (type->tp_init == PyBaseObject_Type.tp_init
195 && ((args && PyObject_IsTrue(args))
196 || (kw && PyObject_IsTrue(kw)))) {
197 PyErr_SetString(PyExc_TypeError,
198 "Initialization arguments are not supported");
199 return NULL;
200 }
Jim Fultond15dc062004-07-14 19:11:50 +0000201
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000202 self = (localobject *)type->tp_alloc(type, 0);
203 if (self == NULL)
204 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000205
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000206 Py_XINCREF(args);
207 self->args = args;
208 Py_XINCREF(kw);
209 self->kw = kw;
210 self->dict = NULL; /* making sure */
211 self->key = PyString_FromFormat("thread.local.%p", self);
212 if (self->key == NULL)
213 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000214
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000215 self->dict = PyDict_New();
216 if (self->dict == NULL)
217 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000218
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000219 tdict = PyThreadState_GetDict();
220 if (tdict == NULL) {
221 PyErr_SetString(PyExc_SystemError,
222 "Couldn't get thread-state dictionary");
223 goto err;
224 }
Jim Fultond15dc062004-07-14 19:11:50 +0000225
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000226 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
227 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000228
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000229 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000230
231 err:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000232 Py_DECREF(self);
233 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000234}
235
236static int
237local_traverse(localobject *self, visitproc visit, void *arg)
238{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000239 Py_VISIT(self->args);
240 Py_VISIT(self->kw);
241 Py_VISIT(self->dict);
242 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000243}
244
245static int
246local_clear(localobject *self)
247{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000248 Py_CLEAR(self->args);
249 Py_CLEAR(self->kw);
250 Py_CLEAR(self->dict);
251 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000252}
253
254static void
255local_dealloc(localobject *self)
256{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000257 PyThreadState *tstate;
258 if (self->key
259 && (tstate = PyThreadState_Get())
260 && tstate->interp) {
261 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
262 tstate;
263 tstate = PyThreadState_Next(tstate))
264 if (tstate->dict &&
265 PyDict_GetItem(tstate->dict, self->key))
266 PyDict_DelItem(tstate->dict, self->key);
267 }
Jim Fultond15dc062004-07-14 19:11:50 +0000268
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000269 Py_XDECREF(self->key);
270 local_clear(self);
271 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000272}
273
274static PyObject *
275_ldict(localobject *self)
276{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000277 PyObject *tdict, *ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000278
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000279 tdict = PyThreadState_GetDict();
280 if (tdict == NULL) {
281 PyErr_SetString(PyExc_SystemError,
282 "Couldn't get thread-state dictionary");
283 return NULL;
284 }
Jim Fultond15dc062004-07-14 19:11:50 +0000285
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000286 ldict = PyDict_GetItem(tdict, self->key);
287 if (ldict == NULL) {
288 ldict = PyDict_New(); /* we own ldict */
Jim Fultond15dc062004-07-14 19:11:50 +0000289
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000290 if (ldict == NULL)
291 return NULL;
292 else {
293 int i = PyDict_SetItem(tdict, self->key, ldict);
294 Py_DECREF(ldict); /* now ldict is borrowed */
295 if (i < 0)
296 return NULL;
297 }
Jim Fultond15dc062004-07-14 19:11:50 +0000298
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000299 Py_CLEAR(self->dict);
300 Py_INCREF(ldict);
301 self->dict = ldict; /* still borrowed */
Jim Fultond15dc062004-07-14 19:11:50 +0000302
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000303 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
304 Py_TYPE(self)->tp_init((PyObject*)self,
305 self->args, self->kw) < 0) {
306 /* we need to get rid of ldict from thread so
307 we create a new one the next time we do an attr
308 acces */
309 PyDict_DelItem(tdict, self->key);
310 return NULL;
311 }
Amaury Forgeot d'Arc1f40c8a2008-06-30 22:42:40 +0000312
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000313 }
Jim Fultond15dc062004-07-14 19:11:50 +0000314
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000315 /* The call to tp_init above may have caused another thread to run.
316 Install our ldict again. */
317 if (self->dict != ldict) {
318 Py_CLEAR(self->dict);
319 Py_INCREF(ldict);
320 self->dict = ldict;
321 }
322
323 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000324}
325
Jim Fultond15dc062004-07-14 19:11:50 +0000326static int
327local_setattro(localobject *self, PyObject *name, PyObject *v)
328{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000329 PyObject *ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000330
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000331 ldict = _ldict(self);
332 if (ldict == NULL)
333 return -1;
334
335 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000336}
337
338static PyObject *
339local_getdict(localobject *self, void *closure)
340{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000341 if (self->dict == NULL) {
342 PyErr_SetString(PyExc_AttributeError, "__dict__");
343 return NULL;
344 }
Jim Fultond15dc062004-07-14 19:11:50 +0000345
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000346 Py_INCREF(self->dict);
347 return self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000348}
349
350static PyGetSetDef local_getset[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000351 {"__dict__", (getter)local_getdict, (setter)NULL,
352 "Local-data dictionary", NULL},
353 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000354};
355
Anthony Baxter5576b542006-04-12 04:08:46 +0000356static PyObject *local_getattro(localobject *, PyObject *);
357
Jim Fultond15dc062004-07-14 19:11:50 +0000358static PyTypeObject localtype = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000359 PyVarObject_HEAD_INIT(NULL, 0)
360 /* tp_name */ "thread._local",
361 /* tp_basicsize */ sizeof(localobject),
362 /* tp_itemsize */ 0,
363 /* tp_dealloc */ (destructor)local_dealloc,
364 /* tp_print */ 0,
365 /* tp_getattr */ 0,
366 /* tp_setattr */ 0,
367 /* tp_compare */ 0,
368 /* tp_repr */ 0,
369 /* tp_as_number */ 0,
370 /* tp_as_sequence */ 0,
371 /* tp_as_mapping */ 0,
372 /* tp_hash */ 0,
373 /* tp_call */ 0,
374 /* tp_str */ 0,
375 /* tp_getattro */ (getattrofunc)local_getattro,
376 /* tp_setattro */ (setattrofunc)local_setattro,
377 /* tp_as_buffer */ 0,
378 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
379 /* tp_doc */ "Thread-local data",
380 /* tp_traverse */ (traverseproc)local_traverse,
381 /* tp_clear */ (inquiry)local_clear,
382 /* tp_richcompare */ 0,
383 /* tp_weaklistoffset */ 0,
384 /* tp_iter */ 0,
385 /* tp_iternext */ 0,
386 /* tp_methods */ 0,
387 /* tp_members */ 0,
388 /* tp_getset */ local_getset,
389 /* tp_base */ 0,
390 /* tp_dict */ 0, /* internal use */
391 /* tp_descr_get */ 0,
392 /* tp_descr_set */ 0,
393 /* tp_dictoffset */ offsetof(localobject, dict),
394 /* tp_init */ 0,
395 /* tp_alloc */ 0,
396 /* tp_new */ local_new,
397 /* tp_free */ 0, /* Low-level free-mem routine */
398 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000399};
400
Anthony Baxter5576b542006-04-12 04:08:46 +0000401static PyObject *
402local_getattro(localobject *self, PyObject *name)
403{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000404 PyObject *ldict, *value;
Anthony Baxter5576b542006-04-12 04:08:46 +0000405
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000406 ldict = _ldict(self);
407 if (ldict == NULL)
408 return NULL;
Anthony Baxter5576b542006-04-12 04:08:46 +0000409
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000410 if (Py_TYPE(self) != &localtype)
411 /* use generic lookup for subtypes */
412 return PyObject_GenericGetAttr((PyObject *)self, name);
Anthony Baxter5576b542006-04-12 04:08:46 +0000413
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000414 /* Optimization: just look in dict ourselves */
415 value = PyDict_GetItem(ldict, name);
416 if (value == NULL)
417 /* Fall back on generic to get __class__ and __dict__ */
418 return PyObject_GenericGetAttr((PyObject *)self, name);
Anthony Baxter5576b542006-04-12 04:08:46 +0000419
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000420 Py_INCREF(value);
421 return value;
Anthony Baxter5576b542006-04-12 04:08:46 +0000422}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000423
424/* Module functions */
425
Guido van Rossuma027efa1997-05-05 20:56:21 +0000426struct bootstate {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000427 PyInterpreterState *interp;
428 PyObject *func;
429 PyObject *args;
430 PyObject *keyw;
431 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000432};
433
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000434static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000435t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000436{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000437 struct bootstate *boot = (struct bootstate *) boot_raw;
438 PyThreadState *tstate;
439 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000440
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000441 tstate = boot->tstate;
442 tstate->thread_id = PyThread_get_thread_ident();
443 _PyThreadState_Init(tstate);
444 PyEval_AcquireThread(tstate);
445 nb_threads++;
446 res = PyEval_CallObjectWithKeywords(
447 boot->func, boot->args, boot->keyw);
448 if (res == NULL) {
449 if (PyErr_ExceptionMatches(PyExc_SystemExit))
450 PyErr_Clear();
451 else {
452 PyObject *file;
453 PySys_WriteStderr(
454 "Unhandled exception in thread started by ");
455 file = PySys_GetObject("stderr");
456 if (file)
457 PyFile_WriteObject(boot->func, file, 0);
458 else
459 PyObject_Print(boot->func, stderr, 0);
460 PySys_WriteStderr("\n");
461 PyErr_PrintEx(0);
462 }
463 }
464 else
465 Py_DECREF(res);
466 Py_DECREF(boot->func);
467 Py_DECREF(boot->args);
468 Py_XDECREF(boot->keyw);
469 PyMem_DEL(boot_raw);
470 nb_threads--;
471 PyThreadState_Clear(tstate);
472 PyThreadState_DeleteCurrent();
473 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000474}
475
Barry Warsawd0c10421996-12-17 00:05:22 +0000476static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000477thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000478{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000479 PyObject *func, *args, *keyw = NULL;
480 struct bootstate *boot;
481 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000482
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000483 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
484 &func, &args, &keyw))
485 return NULL;
486 if (!PyCallable_Check(func)) {
487 PyErr_SetString(PyExc_TypeError,
488 "first arg must be callable");
489 return NULL;
490 }
491 if (!PyTuple_Check(args)) {
492 PyErr_SetString(PyExc_TypeError,
493 "2nd arg must be a tuple");
494 return NULL;
495 }
496 if (keyw != NULL && !PyDict_Check(keyw)) {
497 PyErr_SetString(PyExc_TypeError,
498 "optional 3rd arg must be a dictionary");
499 return NULL;
500 }
501 boot = PyMem_NEW(struct bootstate, 1);
502 if (boot == NULL)
503 return PyErr_NoMemory();
504 boot->interp = PyThreadState_GET()->interp;
505 boot->func = func;
506 boot->args = args;
507 boot->keyw = keyw;
508 boot->tstate = _PyThreadState_Prealloc(boot->interp);
509 if (boot->tstate == NULL) {
510 PyMem_DEL(boot);
511 return PyErr_NoMemory();
512 }
513 Py_INCREF(func);
514 Py_INCREF(args);
515 Py_XINCREF(keyw);
516 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
517 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
518 if (ident == -1) {
519 PyErr_SetString(ThreadError, "can't start new thread");
520 Py_DECREF(func);
521 Py_DECREF(args);
522 Py_XDECREF(keyw);
523 PyThreadState_Clear(boot->tstate);
524 PyMem_DEL(boot);
525 return NULL;
526 }
527 return PyInt_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000528}
529
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000530PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000531"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000532(start_new() is an obsolete synonym)\n\
533\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000534Start a new thread and return its identifier. The thread will call the\n\
535function with positional arguments from the tuple args and keyword arguments\n\
536taken from the optional dictionary kwargs. The thread exits when the\n\
537function returns; the return value is ignored. The thread will also exit\n\
538when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000539printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000540
Barry Warsawd0c10421996-12-17 00:05:22 +0000541static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000542thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000543{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000544 PyErr_SetNone(PyExc_SystemExit);
545 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000546}
547
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000548PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000549"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000550(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000551\n\
552This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000553thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000554
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000555static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000556thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000557{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000558 PyErr_SetInterrupt();
559 Py_INCREF(Py_None);
560 return Py_None;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000561}
562
563PyDoc_STRVAR(interrupt_doc,
564"interrupt_main()\n\
565\n\
566Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000567A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000568);
569
Anthony Baxter5576b542006-04-12 04:08:46 +0000570static lockobject *newlockobject(void);
571
Barry Warsawd0c10421996-12-17 00:05:22 +0000572static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000573thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000574{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000575 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000576}
577
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000578PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000579"allocate_lock() -> lock object\n\
580(allocate() is an obsolete synonym)\n\
581\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000582Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000583
Barry Warsawd0c10421996-12-17 00:05:22 +0000584static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000585thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000586{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000587 long ident;
588 ident = PyThread_get_thread_ident();
589 if (ident == -1) {
590 PyErr_SetString(ThreadError, "no current thread ident");
591 return NULL;
592 }
593 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000594}
595
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000596PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000597"get_ident() -> integer\n\
598\n\
599Return a non-zero integer that uniquely identifies the current thread\n\
600amongst other threads that exist simultaneously.\n\
601This may be used to identify per-thread resources.\n\
602Even though on some platforms threads identities may appear to be\n\
603allocated consecutive numbers starting at 1, this behavior should not\n\
604be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000605A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000606
Andrew MacIntyre92913322006-06-13 15:04:24 +0000607static PyObject *
Antoine Pitrou59c44f32009-10-30 17:07:08 +0000608thread__count(PyObject *self)
609{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000610 return PyInt_FromLong(nb_threads);
Antoine Pitrou59c44f32009-10-30 17:07:08 +0000611}
612
613PyDoc_STRVAR(_count_doc,
614"_count() -> integer\n\
615\n\
Antoine Pitrou2c970a22009-10-30 22:19:09 +0000616\
617Return the number of currently running Python threads, excluding \n\
618the main thread. The returned number comprises all threads created\n\
619through `start_new_thread()` as well as `threading.Thread`, and not\n\
620yet finished.\n\
621\n\
622This function is meant for internal and specialized purposes only.\n\
623In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou59c44f32009-10-30 17:07:08 +0000624
625static PyObject *
Andrew MacIntyre92913322006-06-13 15:04:24 +0000626thread_stack_size(PyObject *self, PyObject *args)
627{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000628 size_t old_size;
629 Py_ssize_t new_size = 0;
630 int rc;
Andrew MacIntyre92913322006-06-13 15:04:24 +0000631
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000632 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
633 return NULL;
Andrew MacIntyre92913322006-06-13 15:04:24 +0000634
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000635 if (new_size < 0) {
636 PyErr_SetString(PyExc_ValueError,
637 "size must be 0 or a positive value");
638 return NULL;
639 }
Andrew MacIntyre92913322006-06-13 15:04:24 +0000640
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000641 old_size = PyThread_get_stacksize();
Andrew MacIntyre92913322006-06-13 15:04:24 +0000642
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000643 rc = PyThread_set_stacksize((size_t) new_size);
644 if (rc == -1) {
645 PyErr_Format(PyExc_ValueError,
646 "size not valid: %zd bytes",
647 new_size);
648 return NULL;
649 }
650 if (rc == -2) {
651 PyErr_SetString(ThreadError,
652 "setting stack size not supported");
653 return NULL;
654 }
Andrew MacIntyre92913322006-06-13 15:04:24 +0000655
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000656 return PyInt_FromSsize_t((Py_ssize_t) old_size);
Andrew MacIntyre92913322006-06-13 15:04:24 +0000657}
658
659PyDoc_STRVAR(stack_size_doc,
660"stack_size([size]) -> size\n\
661\n\
662Return the thread stack size used when creating new threads. The\n\
663optional size argument specifies the stack size (in bytes) to be used\n\
664for subsequently created threads, and must be 0 (use platform or\n\
665configured default) or a positive integer value of at least 32,768 (32k).\n\
666If changing the thread stack size is unsupported, a ThreadError\n\
667exception is raised. If the specified size is invalid, a ValueError\n\
668exception is raised, and the stack size is unmodified. 32k bytes\n\
669 currently the minimum supported stack size value to guarantee\n\
670sufficient stack space for the interpreter itself.\n\
671\n\
672Note that some platforms may have particular restrictions on values for\n\
673the stack size, such as requiring a minimum stack size larger than 32kB or\n\
674requiring allocation in multiples of the system memory page size\n\
675- platform documentation should be referred to for more information\n\
676(4kB pages are common; using multiples of 4096 for the stack size is\n\
677the suggested approach in the absence of more specific information).");
678
Barry Warsawd0c10421996-12-17 00:05:22 +0000679static PyMethodDef thread_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000680 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
681 METH_VARARGS,
682 start_new_doc},
683 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
684 METH_VARARGS,
685 start_new_doc},
686 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
687 METH_NOARGS, allocate_doc},
688 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
689 METH_NOARGS, allocate_doc},
690 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
691 METH_NOARGS, exit_doc},
692 {"exit", (PyCFunction)thread_PyThread_exit_thread,
693 METH_NOARGS, exit_doc},
694 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
695 METH_NOARGS, interrupt_doc},
696 {"get_ident", (PyCFunction)thread_get_ident,
697 METH_NOARGS, get_ident_doc},
698 {"_count", (PyCFunction)thread__count,
699 METH_NOARGS, _count_doc},
700 {"stack_size", (PyCFunction)thread_stack_size,
701 METH_VARARGS,
702 stack_size_doc},
703 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000704};
705
706
707/* Initialization function */
708
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000709PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000710"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000711The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000712
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000713PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000714"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000715call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000716\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000717acquire() -- lock the lock, possibly blocking until it can be obtained\n\
718release() -- unlock of the lock\n\
719locked() -- test whether the lock is currently locked\n\
720\n\
721A lock is not owned by the thread that locked it; another thread may\n\
722unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000723will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000724
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000725PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000726initthread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000727{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000728 PyObject *m, *d;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000729
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000730 /* Initialize types: */
731 if (PyType_Ready(&localtype) < 0)
732 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000733
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000734 /* Create the module and add the functions */
735 m = Py_InitModule3("thread", thread_methods, thread_doc);
736 if (m == NULL)
737 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000738
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000739 /* Add a symbolic constant */
740 d = PyModule_GetDict(m);
741 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
742 PyDict_SetItemString(d, "error", ThreadError);
743 Locktype.tp_doc = lock_doc;
744 if (PyType_Ready(&Locktype) < 0)
745 return;
746 Py_INCREF(&Locktype);
747 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Jim Fultond15dc062004-07-14 19:11:50 +0000748
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000749 Py_INCREF(&localtype);
750 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
751 return;
Antoine Pitrou59c44f32009-10-30 17:07:08 +0000752
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000753 nb_threads = 0;
754
755 /* Initialize the C thread library */
756 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000757}