blob: de34ae24c3543c8c4bc8851708409fb81fc88596 [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"
Guido van Rossum1984f1e1992-08-04 12:41:02 +00006
Guido van Rossumb6775db1994-08-01 11:34:53 +00007#ifndef WITH_THREAD
Guido van Rossuma027efa1997-05-05 20:56:21 +00008#error "Error! The rest of Python is not compiled with thread support."
Neal Norwitz884baa12002-09-05 21:31:04 +00009#error "Rerun configure, adding a --with-threads option."
Guido van Rossuma027efa1997-05-05 20:56:21 +000010#error "Then run `make clean' followed by `make'."
Guido van Rossumb6775db1994-08-01 11:34:53 +000011#endif
12
Guido van Rossum49b56061998-10-01 20:42:43 +000013#include "pythread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000014
Barry Warsawd0c10421996-12-17 00:05:22 +000015static PyObject *ThreadError;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000016
17
18/* Lock objects */
19
20typedef struct {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000021 PyObject_HEAD
22 PyThread_type_lock lock_lock;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000023} lockobject;
24
Guido van Rossum1984f1e1992-08-04 12:41:02 +000025static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000026lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000027{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000028 if (self->lock_lock != NULL) {
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);
32
33 PyThread_free_lock(self->lock_lock);
34 }
35 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000036}
37
Barry Warsawd0c10421996-12-17 00:05:22 +000038static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000039lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000040{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000041 int i = 1;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000042
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000043 if (!PyArg_ParseTuple(args, "|i:acquire", &i))
44 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000045
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000046 Py_BEGIN_ALLOW_THREADS
47 i = PyThread_acquire_lock(self->lock_lock, i);
48 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +000049
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000050 return PyBool_FromLong((long)i);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000051}
52
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000053PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000054"acquire([wait]) -> None or bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000055(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000056\n\
57Lock the lock. Without argument, this blocks if the lock is already\n\
58locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000059the lock, and return None once the lock is acquired.\n\
60With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000061and the return value reflects whether the lock is acquired.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000062The blocking operation is not interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000063
Barry Warsawd0c10421996-12-17 00:05:22 +000064static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000065lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000066{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000067 /* Sanity check: the lock must be locked */
68 if (PyThread_acquire_lock(self->lock_lock, 0)) {
69 PyThread_release_lock(self->lock_lock);
70 PyErr_SetString(ThreadError, "release unlocked lock");
71 return NULL;
72 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +000073
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000074 PyThread_release_lock(self->lock_lock);
75 Py_INCREF(Py_None);
76 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000077}
78
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000079PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +000080"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000081(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000082\n\
83Release the lock, allowing another thread that is blocked waiting for\n\
84the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000085but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000086
Barry Warsawd0c10421996-12-17 00:05:22 +000087static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000088lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000089{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000090 if (PyThread_acquire_lock(self->lock_lock, 0)) {
91 PyThread_release_lock(self->lock_lock);
92 return PyBool_FromLong(0L);
93 }
94 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000095}
96
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000097PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000098"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000099(locked_lock() is an obsolete synonym)\n\
100\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000101Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000102
Barry Warsawd0c10421996-12-17 00:05:22 +0000103static PyMethodDef lock_methods[] = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000104 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
105 METH_VARARGS, acquire_doc},
106 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
107 METH_VARARGS, acquire_doc},
108 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
109 METH_NOARGS, release_doc},
110 {"release", (PyCFunction)lock_PyThread_release_lock,
111 METH_NOARGS, release_doc},
112 {"locked_lock", (PyCFunction)lock_locked_lock,
113 METH_NOARGS, locked_doc},
114 {"locked", (PyCFunction)lock_locked_lock,
115 METH_NOARGS, locked_doc},
116 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
117 METH_VARARGS, acquire_doc},
118 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
119 METH_VARARGS, release_doc},
120 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000121};
122
Barry Warsawd0c10421996-12-17 00:05:22 +0000123static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000124lock_getattr(lockobject *self, char *name)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000125{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000126 return Py_FindMethod(lock_methods, (PyObject *)self, name);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000127}
128
Barry Warsawd0c10421996-12-17 00:05:22 +0000129static PyTypeObject Locktype = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000130 PyVarObject_HEAD_INIT(&PyType_Type, 0)
131 "thread.lock", /*tp_name*/
132 sizeof(lockobject), /*tp_size*/
133 0, /*tp_itemsize*/
134 /* methods */
135 (destructor)lock_dealloc, /*tp_dealloc*/
136 0, /*tp_print*/
137 (getattrfunc)lock_getattr, /*tp_getattr*/
138 0, /*tp_setattr*/
139 0, /*tp_compare*/
140 0, /*tp_repr*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000141};
142
Anthony Baxter5576b542006-04-12 04:08:46 +0000143static lockobject *
144newlockobject(void)
145{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000146 lockobject *self;
147 self = PyObject_New(lockobject, &Locktype);
148 if (self == NULL)
149 return NULL;
150 self->lock_lock = PyThread_allocate_lock();
151 if (self->lock_lock == NULL) {
152 Py_DECREF(self);
153 PyErr_SetString(ThreadError, "can't allocate lock");
154 return NULL;
155 }
156 return self;
Anthony Baxter5576b542006-04-12 04:08:46 +0000157}
158
Jim Fultond15dc062004-07-14 19:11:50 +0000159/* Thread-local objects */
160
161#include "structmember.h"
162
163typedef struct {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000164 PyObject_HEAD
165 PyObject *key;
166 PyObject *args;
167 PyObject *kw;
168 PyObject *dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000169} localobject;
170
Jim Fultond15dc062004-07-14 19:11:50 +0000171static PyObject *
172local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
173{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000174 localobject *self;
175 PyObject *tdict;
Jim Fultond15dc062004-07-14 19:11:50 +0000176
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000177 if (type->tp_init == PyBaseObject_Type.tp_init
178 && ((args && PyObject_IsTrue(args))
179 || (kw && PyObject_IsTrue(kw)))) {
180 PyErr_SetString(PyExc_TypeError,
181 "Initialization arguments are not supported");
182 return NULL;
183 }
Jim Fultond15dc062004-07-14 19:11:50 +0000184
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000185 self = (localobject *)type->tp_alloc(type, 0);
186 if (self == NULL)
187 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000188
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000189 Py_XINCREF(args);
190 self->args = args;
191 Py_XINCREF(kw);
192 self->kw = kw;
193 self->dict = NULL; /* making sure */
194 self->key = PyString_FromFormat("thread.local.%p", self);
195 if (self->key == NULL)
196 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000197
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000198 self->dict = PyDict_New();
199 if (self->dict == NULL)
200 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000201
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000202 tdict = PyThreadState_GetDict();
203 if (tdict == NULL) {
204 PyErr_SetString(PyExc_SystemError,
205 "Couldn't get thread-state dictionary");
206 goto err;
207 }
Jim Fultond15dc062004-07-14 19:11:50 +0000208
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000209 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
210 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000211
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000212 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000213
214 err:
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000215 Py_DECREF(self);
216 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000217}
218
219static int
220local_traverse(localobject *self, visitproc visit, void *arg)
221{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000222 Py_VISIT(self->args);
223 Py_VISIT(self->kw);
224 Py_VISIT(self->dict);
225 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000226}
227
228static int
229local_clear(localobject *self)
230{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000231 Py_CLEAR(self->args);
232 Py_CLEAR(self->kw);
233 Py_CLEAR(self->dict);
234 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000235}
236
237static void
238local_dealloc(localobject *self)
239{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000240 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);
250 }
Jim Fultond15dc062004-07-14 19:11:50 +0000251
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000252 Py_XDECREF(self->key);
253 local_clear(self);
254 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000255}
256
257static PyObject *
258_ldict(localobject *self)
259{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000260 PyObject *tdict, *ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000261
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000262 tdict = PyThreadState_GetDict();
263 if (tdict == NULL) {
264 PyErr_SetString(PyExc_SystemError,
265 "Couldn't get thread-state dictionary");
266 return NULL;
267 }
Jim Fultond15dc062004-07-14 19:11:50 +0000268
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000269 ldict = PyDict_GetItem(tdict, self->key);
270 if (ldict == NULL) {
271 ldict = PyDict_New(); /* we own ldict */
Jim Fultond15dc062004-07-14 19:11:50 +0000272
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000273 if (ldict == NULL)
274 return NULL;
275 else {
276 int i = PyDict_SetItem(tdict, self->key, ldict);
277 Py_DECREF(ldict); /* now ldict is borrowed */
278 if (i < 0)
279 return NULL;
280 }
Jim Fultond15dc062004-07-14 19:11:50 +0000281
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000282 Py_CLEAR(self->dict);
283 Py_INCREF(ldict);
284 self->dict = ldict; /* still borrowed */
Jim Fultond15dc062004-07-14 19:11:50 +0000285
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000286 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
287 Py_TYPE(self)->tp_init((PyObject*)self,
288 self->args, self->kw) < 0) {
289 /* we need to get rid of ldict from thread so
290 we create a new one the next time we do an attr
291 acces */
292 PyDict_DelItem(tdict, self->key);
293 return NULL;
294 }
Amaury Forgeot d'Arc1f40c8a2008-06-30 22:42:40 +0000295
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000296 }
Jim Fultond15dc062004-07-14 19:11:50 +0000297
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000298 /* The call to tp_init above may have caused another thread to run.
299 Install our ldict again. */
300 if (self->dict != ldict) {
301 Py_CLEAR(self->dict);
302 Py_INCREF(ldict);
303 self->dict = ldict;
304 }
305
306 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000307}
308
Jim Fultond15dc062004-07-14 19:11:50 +0000309static int
310local_setattro(localobject *self, PyObject *name, PyObject *v)
311{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000312 PyObject *ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000313
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000314 ldict = _ldict(self);
315 if (ldict == NULL)
316 return -1;
317
318 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000319}
320
321static PyObject *
322local_getdict(localobject *self, void *closure)
323{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000324 if (self->dict == NULL) {
325 PyErr_SetString(PyExc_AttributeError, "__dict__");
326 return NULL;
327 }
Jim Fultond15dc062004-07-14 19:11:50 +0000328
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000329 Py_INCREF(self->dict);
330 return self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000331}
332
333static PyGetSetDef local_getset[] = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000334 {"__dict__", (getter)local_getdict, (setter)NULL,
335 "Local-data dictionary", NULL},
336 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000337};
338
Anthony Baxter5576b542006-04-12 04:08:46 +0000339static PyObject *local_getattro(localobject *, PyObject *);
340
Jim Fultond15dc062004-07-14 19:11:50 +0000341static PyTypeObject localtype = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000342 PyVarObject_HEAD_INIT(NULL, 0)
343 /* tp_name */ "thread._local",
344 /* tp_basicsize */ sizeof(localobject),
345 /* tp_itemsize */ 0,
346 /* tp_dealloc */ (destructor)local_dealloc,
347 /* tp_print */ 0,
348 /* tp_getattr */ 0,
349 /* tp_setattr */ 0,
350 /* tp_compare */ 0,
351 /* tp_repr */ 0,
352 /* tp_as_number */ 0,
353 /* tp_as_sequence */ 0,
354 /* tp_as_mapping */ 0,
355 /* tp_hash */ 0,
356 /* tp_call */ 0,
357 /* tp_str */ 0,
358 /* tp_getattro */ (getattrofunc)local_getattro,
359 /* tp_setattro */ (setattrofunc)local_setattro,
360 /* tp_as_buffer */ 0,
361 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
362 /* tp_doc */ "Thread-local data",
363 /* tp_traverse */ (traverseproc)local_traverse,
364 /* tp_clear */ (inquiry)local_clear,
365 /* tp_richcompare */ 0,
366 /* tp_weaklistoffset */ 0,
367 /* tp_iter */ 0,
368 /* tp_iternext */ 0,
369 /* tp_methods */ 0,
370 /* tp_members */ 0,
371 /* tp_getset */ local_getset,
372 /* tp_base */ 0,
373 /* tp_dict */ 0, /* internal use */
374 /* tp_descr_get */ 0,
375 /* tp_descr_set */ 0,
376 /* tp_dictoffset */ offsetof(localobject, dict),
377 /* tp_init */ 0,
378 /* tp_alloc */ 0,
379 /* tp_new */ local_new,
380 /* tp_free */ 0, /* Low-level free-mem routine */
381 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000382};
383
Anthony Baxter5576b542006-04-12 04:08:46 +0000384static PyObject *
385local_getattro(localobject *self, PyObject *name)
386{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000387 PyObject *ldict, *value;
Anthony Baxter5576b542006-04-12 04:08:46 +0000388
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000389 ldict = _ldict(self);
390 if (ldict == NULL)
391 return NULL;
Anthony Baxter5576b542006-04-12 04:08:46 +0000392
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000393 if (Py_TYPE(self) != &localtype)
394 /* use generic lookup for subtypes */
395 return PyObject_GenericGetAttr((PyObject *)self, name);
Anthony Baxter5576b542006-04-12 04:08:46 +0000396
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000397 /* Optimization: just look in dict ourselves */
398 value = PyDict_GetItem(ldict, name);
399 if (value == NULL)
400 /* Fall back on generic to get __class__ and __dict__ */
401 return PyObject_GenericGetAttr((PyObject *)self, name);
Anthony Baxter5576b542006-04-12 04:08:46 +0000402
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000403 Py_INCREF(value);
404 return value;
Anthony Baxter5576b542006-04-12 04:08:46 +0000405}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000406
407/* Module functions */
408
Guido van Rossuma027efa1997-05-05 20:56:21 +0000409struct bootstate {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000410 PyInterpreterState *interp;
411 PyObject *func;
412 PyObject *args;
413 PyObject *keyw;
414 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000415};
416
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000417static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000418t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000419{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000420 struct bootstate *boot = (struct bootstate *) boot_raw;
421 PyThreadState *tstate;
422 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000423
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000424 tstate = boot->tstate;
425 tstate->thread_id = PyThread_get_thread_ident();
426 _PyThreadState_Init(tstate);
427 PyEval_AcquireThread(tstate);
428 res = PyEval_CallObjectWithKeywords(
429 boot->func, boot->args, boot->keyw);
430 if (res == NULL) {
431 if (PyErr_ExceptionMatches(PyExc_SystemExit))
432 PyErr_Clear();
433 else {
434 PyObject *file;
435 PySys_WriteStderr(
436 "Unhandled exception in thread started by ");
437 file = PySys_GetObject("stderr");
438 if (file)
439 PyFile_WriteObject(boot->func, file, 0);
440 else
441 PyObject_Print(boot->func, stderr, 0);
442 PySys_WriteStderr("\n");
443 PyErr_PrintEx(0);
444 }
445 }
446 else
447 Py_DECREF(res);
448 Py_DECREF(boot->func);
449 Py_DECREF(boot->args);
450 Py_XDECREF(boot->keyw);
451 PyMem_DEL(boot_raw);
452 PyThreadState_Clear(tstate);
453 PyThreadState_DeleteCurrent();
454 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000455}
456
Barry Warsawd0c10421996-12-17 00:05:22 +0000457static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000458thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000459{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000460 PyObject *func, *args, *keyw = NULL;
461 struct bootstate *boot;
462 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000463
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000464 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
465 &func, &args, &keyw))
466 return NULL;
467 if (!PyCallable_Check(func)) {
468 PyErr_SetString(PyExc_TypeError,
469 "first arg must be callable");
470 return NULL;
471 }
472 if (!PyTuple_Check(args)) {
473 PyErr_SetString(PyExc_TypeError,
474 "2nd arg must be a tuple");
475 return NULL;
476 }
477 if (keyw != NULL && !PyDict_Check(keyw)) {
478 PyErr_SetString(PyExc_TypeError,
479 "optional 3rd arg must be a dictionary");
480 return NULL;
481 }
482 boot = PyMem_NEW(struct bootstate, 1);
483 if (boot == NULL)
484 return PyErr_NoMemory();
485 boot->interp = PyThreadState_GET()->interp;
486 boot->func = func;
487 boot->args = args;
488 boot->keyw = keyw;
489 boot->tstate = _PyThreadState_Prealloc(boot->interp);
490 if (boot->tstate == NULL) {
491 PyMem_DEL(boot);
492 return PyErr_NoMemory();
493 }
494 Py_INCREF(func);
495 Py_INCREF(args);
496 Py_XINCREF(keyw);
497 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
498 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
499 if (ident == -1) {
500 PyErr_SetString(ThreadError, "can't start new thread");
501 Py_DECREF(func);
502 Py_DECREF(args);
503 Py_XDECREF(keyw);
504 PyThreadState_Clear(boot->tstate);
505 PyMem_DEL(boot);
506 return NULL;
507 }
508 return PyInt_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000509}
510
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000511PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000512"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000513(start_new() is an obsolete synonym)\n\
514\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000515Start a new thread and return its identifier. The thread will call the\n\
516function with positional arguments from the tuple args and keyword arguments\n\
517taken from the optional dictionary kwargs. The thread exits when the\n\
518function returns; the return value is ignored. The thread will also exit\n\
519when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000520printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000521
Barry Warsawd0c10421996-12-17 00:05:22 +0000522static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000523thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000524{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000525 PyErr_SetNone(PyExc_SystemExit);
526 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000527}
528
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000529PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000530"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000531(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000532\n\
533This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000534thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000535
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000536static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000537thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000538{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000539 PyErr_SetInterrupt();
540 Py_INCREF(Py_None);
541 return Py_None;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000542}
543
544PyDoc_STRVAR(interrupt_doc,
545"interrupt_main()\n\
546\n\
547Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000548A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000549);
550
Guido van Rossumb6775db1994-08-01 11:34:53 +0000551#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000552static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000553thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000554{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000555 int sts;
556 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
557 return NULL;
558 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
559 for (;;) { } /* Should not be reached */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000560}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000561#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000562
Anthony Baxter5576b542006-04-12 04:08:46 +0000563static lockobject *newlockobject(void);
564
Barry Warsawd0c10421996-12-17 00:05:22 +0000565static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000566thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000567{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000568 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000569}
570
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000571PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000572"allocate_lock() -> lock object\n\
573(allocate() is an obsolete synonym)\n\
574\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000575Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000576
Barry Warsawd0c10421996-12-17 00:05:22 +0000577static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000578thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000579{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000580 long ident;
581 ident = PyThread_get_thread_ident();
582 if (ident == -1) {
583 PyErr_SetString(ThreadError, "no current thread ident");
584 return NULL;
585 }
586 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000587}
588
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000589PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000590"get_ident() -> integer\n\
591\n\
592Return a non-zero integer that uniquely identifies the current thread\n\
593amongst other threads that exist simultaneously.\n\
594This may be used to identify per-thread resources.\n\
595Even though on some platforms threads identities may appear to be\n\
596allocated consecutive numbers starting at 1, this behavior should not\n\
597be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000598A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000599
Andrew MacIntyre92913322006-06-13 15:04:24 +0000600static PyObject *
601thread_stack_size(PyObject *self, PyObject *args)
602{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000603 size_t old_size;
604 Py_ssize_t new_size = 0;
605 int rc;
Andrew MacIntyre92913322006-06-13 15:04:24 +0000606
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000607 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
608 return NULL;
Andrew MacIntyre92913322006-06-13 15:04:24 +0000609
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000610 if (new_size < 0) {
611 PyErr_SetString(PyExc_ValueError,
612 "size must be 0 or a positive value");
613 return NULL;
614 }
Andrew MacIntyre92913322006-06-13 15:04:24 +0000615
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000616 old_size = PyThread_get_stacksize();
Andrew MacIntyre92913322006-06-13 15:04:24 +0000617
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000618 rc = PyThread_set_stacksize((size_t) new_size);
619 if (rc == -1) {
620 PyErr_Format(PyExc_ValueError,
621 "size not valid: %zd bytes",
622 new_size);
623 return NULL;
624 }
625 if (rc == -2) {
626 PyErr_SetString(ThreadError,
627 "setting stack size not supported");
628 return NULL;
629 }
Andrew MacIntyre92913322006-06-13 15:04:24 +0000630
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000631 return PyInt_FromSsize_t((Py_ssize_t) old_size);
Andrew MacIntyre92913322006-06-13 15:04:24 +0000632}
633
634PyDoc_STRVAR(stack_size_doc,
635"stack_size([size]) -> size\n\
636\n\
637Return the thread stack size used when creating new threads. The\n\
638optional size argument specifies the stack size (in bytes) to be used\n\
639for subsequently created threads, and must be 0 (use platform or\n\
640configured default) or a positive integer value of at least 32,768 (32k).\n\
641If changing the thread stack size is unsupported, a ThreadError\n\
642exception is raised. If the specified size is invalid, a ValueError\n\
643exception is raised, and the stack size is unmodified. 32k bytes\n\
644 currently the minimum supported stack size value to guarantee\n\
645sufficient stack space for the interpreter itself.\n\
646\n\
647Note that some platforms may have particular restrictions on values for\n\
648the stack size, such as requiring a minimum stack size larger than 32kB or\n\
649requiring allocation in multiples of the system memory page size\n\
650- platform documentation should be referred to for more information\n\
651(4kB pages are common; using multiples of 4096 for the stack size is\n\
652the suggested approach in the absence of more specific information).");
653
Barry Warsawd0c10421996-12-17 00:05:22 +0000654static PyMethodDef thread_methods[] = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000655 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
656 METH_VARARGS,
657 start_new_doc},
658 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
659 METH_VARARGS,
660 start_new_doc},
661 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
662 METH_NOARGS, allocate_doc},
663 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
664 METH_NOARGS, allocate_doc},
665 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
666 METH_NOARGS, exit_doc},
667 {"exit", (PyCFunction)thread_PyThread_exit_thread,
668 METH_NOARGS, exit_doc},
669 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
670 METH_NOARGS, interrupt_doc},
671 {"get_ident", (PyCFunction)thread_get_ident,
672 METH_NOARGS, get_ident_doc},
673 {"stack_size", (PyCFunction)thread_stack_size,
674 METH_VARARGS,
675 stack_size_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000676#ifndef NO_EXIT_PROG
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000677 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
678 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000679#endif
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000680 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000681};
682
683
684/* Initialization function */
685
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000686PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000687"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000688The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000689
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000690PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000691"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000692call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000693\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000694acquire() -- lock the lock, possibly blocking until it can be obtained\n\
695release() -- unlock of the lock\n\
696locked() -- test whether the lock is currently locked\n\
697\n\
698A lock is not owned by the thread that locked it; another thread may\n\
699unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000700will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000701
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000702PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000703initthread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000704{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000705 PyObject *m, *d;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000706
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000707 /* Initialize types: */
708 if (PyType_Ready(&localtype) < 0)
709 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000710
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000711 /* Create the module and add the functions */
712 m = Py_InitModule3("thread", thread_methods, thread_doc);
713 if (m == NULL)
714 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000715
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000716 /* Add a symbolic constant */
717 d = PyModule_GetDict(m);
718 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
719 PyDict_SetItemString(d, "error", ThreadError);
720 Locktype.tp_doc = lock_doc;
721 Py_INCREF(&Locktype);
722 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Jim Fultond15dc062004-07-14 19:11:50 +0000723
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000724 Py_INCREF(&localtype);
725 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
726 return;
727
728 /* Initialize the C thread library */
729 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000730}