blob: cba01faf06d67ce748e42aa5ff45eb36206d6884 [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 {
Barry Warsawd0c10421996-12-17 00:05:22 +000021 PyObject_HEAD
Guido van Rossum65d5b571998-12-21 19:32:43 +000022 PyThread_type_lock lock_lock;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000023} lockobject;
24
Jeremy Hylton938ace62002-07-17 16:30:39 +000025static PyTypeObject Locktype;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000026
Guido van Rossum1984f1e1992-08-04 12:41:02 +000027static lockobject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000028newlockobject(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000029{
30 lockobject *self;
Guido van Rossumb18618d2000-05-03 23:44:39 +000031 self = PyObject_New(lockobject, &Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000032 if (self == NULL)
33 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +000034 self->lock_lock = PyThread_allocate_lock();
Guido van Rossum1984f1e1992-08-04 12:41:02 +000035 if (self->lock_lock == NULL) {
Guido van Rossumb18618d2000-05-03 23:44:39 +000036 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000037 self = NULL;
Barry Warsawd0c10421996-12-17 00:05:22 +000038 PyErr_SetString(ThreadError, "can't allocate lock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +000039 }
40 return self;
41}
42
43static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000044lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000045{
46 /* Unlock the lock so it's safe to free it */
Guido van Rossum65d5b571998-12-21 19:32:43 +000047 PyThread_acquire_lock(self->lock_lock, 0);
48 PyThread_release_lock(self->lock_lock);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000049
Guido van Rossum65d5b571998-12-21 19:32:43 +000050 PyThread_free_lock(self->lock_lock);
Guido van Rossumb18618d2000-05-03 23:44:39 +000051 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000052}
53
Barry Warsawd0c10421996-12-17 00:05:22 +000054static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000055lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000056{
Neal Norwitzba3a16c2002-03-31 15:27:00 +000057 int i = 1;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000058
Neal Norwitzba3a16c2002-03-31 15:27:00 +000059 if (!PyArg_ParseTuple(args, "|i:acquire", &i))
60 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000061
Barry Warsawd0c10421996-12-17 00:05:22 +000062 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +000063 i = PyThread_acquire_lock(self->lock_lock, i);
Barry Warsawd0c10421996-12-17 00:05:22 +000064 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +000065
66 if (args == NULL) {
Barry Warsawd0c10421996-12-17 00:05:22 +000067 Py_INCREF(Py_None);
68 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000069 }
70 else
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000071 return PyBool_FromLong((long)i);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000072}
73
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000074PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000075"acquire([wait]) -> None or bool\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +000076(PyThread_acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000077\n\
78Lock the lock. Without argument, this blocks if the lock is already\n\
79locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000080the lock, and return None once the lock is acquired.\n\
81With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000082and the return value reflects whether the lock is acquired.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000083The blocking operation is not interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000084
Barry Warsawd0c10421996-12-17 00:05:22 +000085static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000086lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000087{
Guido van Rossum1984f1e1992-08-04 12:41:02 +000088 /* Sanity check: the lock must be locked */
Guido van Rossum65d5b571998-12-21 19:32:43 +000089 if (PyThread_acquire_lock(self->lock_lock, 0)) {
90 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000091 PyErr_SetString(ThreadError, "release unlocked lock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +000092 return NULL;
93 }
94
Guido van Rossum65d5b571998-12-21 19:32:43 +000095 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000096 Py_INCREF(Py_None);
97 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000098}
99
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000100PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000101"release()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000102(PyThread_release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000103\n\
104Release the lock, allowing another thread that is blocked waiting for\n\
105the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000106but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000107
Barry Warsawd0c10421996-12-17 00:05:22 +0000108static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000109lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000110{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000111 if (PyThread_acquire_lock(self->lock_lock, 0)) {
112 PyThread_release_lock(self->lock_lock);
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000113 return PyBool_FromLong(0L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000114 }
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000115 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000116}
117
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000118PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000119"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000120(locked_lock() is an obsolete synonym)\n\
121\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000122Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000123
Barry Warsawd0c10421996-12-17 00:05:22 +0000124static PyMethodDef lock_methods[] = {
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000125 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000126 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000127 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000128 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000129 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000130 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000131 {"release", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000132 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000133 {"locked_lock", (PyCFunction)lock_locked_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000134 METH_NOARGS, locked_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000135 {"locked", (PyCFunction)lock_locked_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000136 METH_NOARGS, locked_doc},
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000137 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000138};
139
Barry Warsawd0c10421996-12-17 00:05:22 +0000140static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000141lock_getattr(lockobject *self, char *name)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000142{
Barry Warsawd0c10421996-12-17 00:05:22 +0000143 return Py_FindMethod(lock_methods, (PyObject *)self, name);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000144}
145
Barry Warsawd0c10421996-12-17 00:05:22 +0000146static PyTypeObject Locktype = {
147 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000148 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000149 "thread.lock", /*tp_name*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000150 sizeof(lockobject), /*tp_size*/
151 0, /*tp_itemsize*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000152 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000153 (destructor)lock_dealloc, /*tp_dealloc*/
154 0, /*tp_print*/
155 (getattrfunc)lock_getattr, /*tp_getattr*/
156 0, /*tp_setattr*/
157 0, /*tp_compare*/
158 0, /*tp_repr*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000159};
160
Jim Fultond15dc062004-07-14 19:11:50 +0000161/* Thread-local objects */
162
163#include "structmember.h"
164
165typedef struct {
166 PyObject_HEAD
167 PyObject *key;
168 PyObject *args;
169 PyObject *kw;
170 PyObject *dict;
171} localobject;
172
173static PyTypeObject localtype;
174
175static PyObject *
176local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
177{
178 localobject *self;
179 PyObject *tdict;
180
181 if (type->tp_init == PyBaseObject_Type.tp_init
182 && ((args && PyObject_IsTrue(args))
183 ||
184 (kw && PyObject_IsTrue(kw))
185 )
186 ) {
187 PyErr_SetString(PyExc_TypeError,
188 "Initialization arguments are not supported");
189 return NULL;
190 }
191
192 self = (localobject *)type->tp_alloc(type, 0);
193 if (self == NULL)
194 return NULL;
195
196 Py_XINCREF(args);
197 self->args = args;
198 Py_XINCREF(kw);
199 self->kw = kw;
200 self->dict = NULL; /* making sure */
201 self->key = PyString_FromFormat("thread.local.%p", self);
202 if (self->key == NULL)
203 goto err;
204
205 self->dict = PyDict_New();
206 if (self->dict == NULL)
207 goto err;
208
209 tdict = PyThreadState_GetDict();
210 if (tdict == NULL) {
211 PyErr_SetString(PyExc_SystemError,
212 "Couldn't get thread-state dictionary");
213 goto err;
214 }
215
216 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
217 goto err;
218
219 return (PyObject *)self;
220
221 err:
222 Py_DECREF(self);
223 return NULL;
224}
225
226static int
227local_traverse(localobject *self, visitproc visit, void *arg)
228{
229 Py_VISIT(self->args);
230 Py_VISIT(self->kw);
231 Py_VISIT(self->dict);
232 return 0;
233}
234
235static int
236local_clear(localobject *self)
237{
238 Py_CLEAR(self->key);
239 Py_CLEAR(self->args);
240 Py_CLEAR(self->kw);
241 Py_CLEAR(self->dict);
242 return 0;
243}
244
245static void
246local_dealloc(localobject *self)
247{
248 PyThreadState *tstate;
249 if (self->key
250 && (tstate = PyThreadState_Get())
251 && tstate->interp) {
252 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
253 tstate;
254 tstate = PyThreadState_Next(tstate)
255 )
256 if (tstate->dict &&
257 PyDict_GetItem(tstate->dict, self->key))
258 PyDict_DelItem(tstate->dict, self->key);
259 }
260
261 local_clear(self);
262 self->ob_type->tp_free((PyObject*)self);
263}
264
265static PyObject *
266_ldict(localobject *self)
267{
268 PyObject *tdict, *ldict;
269
270 tdict = PyThreadState_GetDict();
271 if (tdict == NULL) {
272 PyErr_SetString(PyExc_SystemError,
273 "Couldn't get thread-state dictionary");
274 return NULL;
275 }
276
277 ldict = PyDict_GetItem(tdict, self->key);
278 if (ldict == NULL) {
279 ldict = PyDict_New(); /* we own ldict */
280
281 if (ldict == NULL)
282 return NULL;
283 else {
284 int i = PyDict_SetItem(tdict, self->key, ldict);
285 Py_DECREF(ldict); /* now ldict is borowed */
286 if (i < 0)
287 return NULL;
288 }
289
290 Py_CLEAR(self->dict);
291 Py_INCREF(ldict);
292 self->dict = ldict; /* still borrowed */
293
294 if (self->ob_type->tp_init != PyBaseObject_Type.tp_init &&
295 self->ob_type->tp_init((PyObject*)self,
296 self->args, self->kw) < 0
297 ) {
298 /* we need to get rid of ldict from thread so
299 we create a new one the next time we do an attr
300 acces */
301 PyDict_DelItem(tdict, self->key);
302 return NULL;
303 }
304
305 }
306 else if (self->dict != ldict) {
307 Py_CLEAR(self->dict);
308 Py_INCREF(ldict);
309 self->dict = ldict;
310 }
311
312 return ldict;
313}
314
315static PyObject *
316local_getattro(localobject *self, PyObject *name)
317{
318 PyObject *ldict, *value;
319
320 ldict = _ldict(self);
321 if (ldict == NULL)
322 return NULL;
323
324 if (self->ob_type != &localtype)
325 /* use generic lookup for subtypes */
326 return PyObject_GenericGetAttr((PyObject *)self, name);
327
328 /* Optimization: just look in dict ourselves */
329 value = PyDict_GetItem(ldict, name);
330 if (value == NULL)
331 /* Fall back on generic to get __class__ and __dict__ */
332 return PyObject_GenericGetAttr((PyObject *)self, name);
333
334 Py_INCREF(value);
335 return value;
336}
337
338static int
339local_setattro(localobject *self, PyObject *name, PyObject *v)
340{
341 PyObject *ldict;
342
343 ldict = _ldict(self);
344 if (ldict == NULL)
345 return -1;
346
347 return PyObject_GenericSetAttr((PyObject *)self, name, v);
348}
349
350static PyObject *
351local_getdict(localobject *self, void *closure)
352{
353 if (self->dict == NULL) {
354 PyErr_SetString(PyExc_AttributeError, "__dict__");
355 return NULL;
356 }
357
358 Py_INCREF(self->dict);
359 return self->dict;
360}
361
362static PyGetSetDef local_getset[] = {
363 {"__dict__",
364 (getter)local_getdict, (setter)0,
365 "Local-data dictionary",
366 NULL},
367 {NULL} /* Sentinel */
368};
369
370static PyTypeObject localtype = {
371 PyObject_HEAD_INIT(NULL)
372 /* ob_size */ 0,
373 /* tp_name */ "thread._local",
374 /* tp_basicsize */ sizeof(localobject),
375 /* tp_itemsize */ 0,
376 /* tp_dealloc */ (destructor)local_dealloc,
377 /* tp_print */ (printfunc)0,
378 /* tp_getattr */ (getattrfunc)0,
379 /* tp_setattr */ (setattrfunc)0,
380 /* tp_compare */ (cmpfunc)0,
381 /* tp_repr */ (reprfunc)0,
382 /* tp_as_number */ 0,
383 /* tp_as_sequence */ 0,
384 /* tp_as_mapping */ 0,
385 /* tp_hash */ (hashfunc)0,
386 /* tp_call */ (ternaryfunc)0,
387 /* tp_str */ (reprfunc)0,
388 /* tp_getattro */ (getattrofunc)local_getattro,
389 /* tp_setattro */ (setattrofunc)local_setattro,
390 /* tp_as_buffer */ 0,
391 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
392 /* tp_doc */ "Thread-local data",
393 /* tp_traverse */ (traverseproc)local_traverse,
394 /* tp_clear */ (inquiry)local_clear,
395 /* tp_richcompare */ (richcmpfunc)0,
396 /* tp_weaklistoffset */ (long)0,
397 /* tp_iter */ (getiterfunc)0,
398 /* tp_iternext */ (iternextfunc)0,
399 /* tp_methods */ 0,
400 /* tp_members */ 0,
401 /* tp_getset */ local_getset,
402 /* tp_base */ 0,
403 /* tp_dict */ 0, /* internal use */
404 /* tp_descr_get */ (descrgetfunc)0,
405 /* tp_descr_set */ (descrsetfunc)0,
406 /* tp_dictoffset */ offsetof(localobject, dict),
407 /* tp_init */ (initproc)0,
408 /* tp_alloc */ (allocfunc)0,
409 /* tp_new */ (newfunc)local_new,
410 /* tp_free */ 0, /* Low-level free-mem routine */
411 /* tp_is_gc */ (inquiry)0, /* For PyObject_IS_GC */
412};
413
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000414
415/* Module functions */
416
Guido van Rossuma027efa1997-05-05 20:56:21 +0000417struct bootstate {
418 PyInterpreterState *interp;
419 PyObject *func;
420 PyObject *args;
421 PyObject *keyw;
422};
423
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000424static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000425t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000426{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000427 struct bootstate *boot = (struct bootstate *) boot_raw;
Mark Hammondeb619bb2004-08-24 22:24:08 +0000428 PyGILState_STATE gstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000429 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000430
Mark Hammondeb619bb2004-08-24 22:24:08 +0000431 gstate = PyGILState_Ensure();
Guido van Rossuma027efa1997-05-05 20:56:21 +0000432 res = PyEval_CallObjectWithKeywords(
433 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000434 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000435 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000436 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000437 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000438 PyObject *file;
439 PySys_WriteStderr(
440 "Unhandled exception in thread started by ");
441 file = PySys_GetObject("stderr");
442 if (file)
443 PyFile_WriteObject(boot->func, file, 0);
444 else
445 PyObject_Print(boot->func, stderr, 0);
446 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000447 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000448 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000449 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000450 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000451 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000452 Py_DECREF(boot->func);
453 Py_DECREF(boot->args);
454 Py_XDECREF(boot->keyw);
455 PyMem_DEL(boot_raw);
Mark Hammondeb619bb2004-08-24 22:24:08 +0000456 PyGILState_Release(gstate);
Guido van Rossumbcc20741998-08-04 22:53:56 +0000457 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000458}
459
Barry Warsawd0c10421996-12-17 00:05:22 +0000460static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000461thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000462{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000463 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000464 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000465 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000466
Guido van Rossum43713e52000-02-29 13:59:29 +0000467 if (!PyArg_ParseTuple(fargs, "OO|O:start_new_thread", &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000468 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000469 if (!PyCallable_Check(func)) {
470 PyErr_SetString(PyExc_TypeError,
471 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000472 return NULL;
473 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000474 if (!PyTuple_Check(args)) {
475 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000476 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000477 return NULL;
478 }
479 if (keyw != NULL && !PyDict_Check(keyw)) {
480 PyErr_SetString(PyExc_TypeError,
481 "optional 3rd arg must be a dictionary");
482 return NULL;
483 }
484 boot = PyMem_NEW(struct bootstate, 1);
485 if (boot == NULL)
486 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000487 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000488 boot->func = func;
489 boot->args = args;
490 boot->keyw = keyw;
491 Py_INCREF(func);
492 Py_INCREF(args);
493 Py_XINCREF(keyw);
494 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000495 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
496 if (ident == -1) {
Guido van Rossuma027efa1997-05-05 20:56:21 +0000497 PyErr_SetString(ThreadError, "can't start new thread\n");
498 Py_DECREF(func);
499 Py_DECREF(args);
500 Py_XDECREF(keyw);
501 PyMem_DEL(boot);
502 return NULL;
503 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000504 return PyInt_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000505}
506
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000507PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000508"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000509(start_new() is an obsolete synonym)\n\
510\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000511Start a new thread and return its identifier. The thread will call the\n\
512function with positional arguments from the tuple args and keyword arguments\n\
513taken from the optional dictionary kwargs. The thread exits when the\n\
514function returns; the return value is ignored. The thread will also exit\n\
515when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000516printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000517
Barry Warsawd0c10421996-12-17 00:05:22 +0000518static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000519thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000520{
Barry Warsawd0c10421996-12-17 00:05:22 +0000521 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000522 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000523}
524
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000525PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000526"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000527(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000528\n\
529This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000530thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000531
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000532static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000533thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000534{
535 PyErr_SetInterrupt();
536 Py_INCREF(Py_None);
537 return Py_None;
538}
539
540PyDoc_STRVAR(interrupt_doc,
541"interrupt_main()\n\
542\n\
543Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000544A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000545);
546
Guido van Rossumb6775db1994-08-01 11:34:53 +0000547#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000548static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000549thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000550{
551 int sts;
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000552 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000553 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000554 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000555 for (;;) { } /* Should not be reached */
556}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000557#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000558
Barry Warsawd0c10421996-12-17 00:05:22 +0000559static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000560thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000561{
Barry Warsawd0c10421996-12-17 00:05:22 +0000562 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000563}
564
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000565PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000566"allocate_lock() -> lock object\n\
567(allocate() is an obsolete synonym)\n\
568\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000569Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000570
Barry Warsawd0c10421996-12-17 00:05:22 +0000571static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000572thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000573{
574 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000575 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000576 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000577 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000578 return NULL;
579 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000580 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000581}
582
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000583PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000584"get_ident() -> integer\n\
585\n\
586Return a non-zero integer that uniquely identifies the current thread\n\
587amongst other threads that exist simultaneously.\n\
588This may be used to identify per-thread resources.\n\
589Even though on some platforms threads identities may appear to be\n\
590allocated consecutive numbers starting at 1, this behavior should not\n\
591be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000592A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000593
Barry Warsawd0c10421996-12-17 00:05:22 +0000594static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000595 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
596 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000597 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000598 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
599 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000600 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000601 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000602 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000603 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000604 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000605 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000606 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000607 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000608 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000609 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000610 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000611 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000612 METH_NOARGS, get_ident_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000613#ifndef NO_EXIT_PROG
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000614 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
615 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000616#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000617 {NULL, NULL} /* sentinel */
618};
619
620
621/* Initialization function */
622
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000623PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000624"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000625The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000626
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000627PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000628"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000629call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000630\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000631acquire() -- lock the lock, possibly blocking until it can be obtained\n\
632release() -- unlock of the lock\n\
633locked() -- test whether the lock is currently locked\n\
634\n\
635A lock is not owned by the thread that locked it; another thread may\n\
636unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000637will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000638
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000639PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000640initthread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000641{
Barry Warsawd0c10421996-12-17 00:05:22 +0000642 PyObject *m, *d;
Jim Fultond15dc062004-07-14 19:11:50 +0000643
644 /* Initialize types: */
645 if (PyType_Ready(&localtype) < 0)
646 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000647
648 /* Create the module and add the functions */
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000649 m = Py_InitModule3("thread", thread_methods, thread_doc);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000650
651 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000652 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000653 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000654 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000655 Locktype.tp_doc = lock_doc;
656 Py_INCREF(&Locktype);
657 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000658
Jim Fultond15dc062004-07-14 19:11:50 +0000659 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
660 return;
661
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000662 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000663 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000664}