blob: b398a25d8941291562759d47a8d6579cc92c01dc [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;
Guido van Rossum75aa0d61997-07-18 23:57:50 +0000428 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000429 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000430
Guido van Rossuma027efa1997-05-05 20:56:21 +0000431 tstate = PyThreadState_New(boot->interp);
Guido van Rossum75aa0d61997-07-18 23:57:50 +0000432 PyEval_AcquireThread(tstate);
Guido van Rossuma027efa1997-05-05 20:56:21 +0000433 res = PyEval_CallObjectWithKeywords(
434 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000435 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000436 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000437 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000438 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000439 PyObject *file;
440 PySys_WriteStderr(
441 "Unhandled exception in thread started by ");
442 file = PySys_GetObject("stderr");
443 if (file)
444 PyFile_WriteObject(boot->func, file, 0);
445 else
446 PyObject_Print(boot->func, stderr, 0);
447 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000448 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000449 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000450 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000451 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000452 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000453 Py_DECREF(boot->func);
454 Py_DECREF(boot->args);
455 Py_XDECREF(boot->keyw);
456 PyMem_DEL(boot_raw);
Guido van Rossumb02158e1997-08-02 03:13:11 +0000457 PyThreadState_Clear(tstate);
Guido van Rossum2528b192001-01-23 01:47:18 +0000458 PyThreadState_DeleteCurrent();
Guido van Rossumbcc20741998-08-04 22:53:56 +0000459 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000460}
461
Barry Warsawd0c10421996-12-17 00:05:22 +0000462static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000463thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000464{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000465 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000466 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000467 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000468
Guido van Rossum43713e52000-02-29 13:59:29 +0000469 if (!PyArg_ParseTuple(fargs, "OO|O:start_new_thread", &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000470 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000471 if (!PyCallable_Check(func)) {
472 PyErr_SetString(PyExc_TypeError,
473 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000474 return NULL;
475 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000476 if (!PyTuple_Check(args)) {
477 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000478 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000479 return NULL;
480 }
481 if (keyw != NULL && !PyDict_Check(keyw)) {
482 PyErr_SetString(PyExc_TypeError,
483 "optional 3rd arg must be a dictionary");
484 return NULL;
485 }
486 boot = PyMem_NEW(struct bootstate, 1);
487 if (boot == NULL)
488 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000489 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000490 boot->func = func;
491 boot->args = args;
492 boot->keyw = keyw;
493 Py_INCREF(func);
494 Py_INCREF(args);
495 Py_XINCREF(keyw);
496 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000497 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
498 if (ident == -1) {
Guido van Rossuma027efa1997-05-05 20:56:21 +0000499 PyErr_SetString(ThreadError, "can't start new thread\n");
500 Py_DECREF(func);
501 Py_DECREF(args);
502 Py_XDECREF(keyw);
503 PyMem_DEL(boot);
504 return NULL;
505 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000506 return PyInt_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000507}
508
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000509PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000510"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000511(start_new() is an obsolete synonym)\n\
512\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000513Start a new thread and return its identifier. The thread will call the\n\
514function with positional arguments from the tuple args and keyword arguments\n\
515taken from the optional dictionary kwargs. The thread exits when the\n\
516function returns; the return value is ignored. The thread will also exit\n\
517when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000518printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000519
Barry Warsawd0c10421996-12-17 00:05:22 +0000520static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000521thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000522{
Barry Warsawd0c10421996-12-17 00:05:22 +0000523 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000524 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000525}
526
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000527PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000528"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000529(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000530\n\
531This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000532thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000533
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000534static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000535thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000536{
537 PyErr_SetInterrupt();
538 Py_INCREF(Py_None);
539 return Py_None;
540}
541
542PyDoc_STRVAR(interrupt_doc,
543"interrupt_main()\n\
544\n\
545Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000546A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000547);
548
Guido van Rossumb6775db1994-08-01 11:34:53 +0000549#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000550static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000551thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000552{
553 int sts;
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000554 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000555 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000556 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000557 for (;;) { } /* Should not be reached */
558}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000559#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000560
Barry Warsawd0c10421996-12-17 00:05:22 +0000561static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000562thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000563{
Barry Warsawd0c10421996-12-17 00:05:22 +0000564 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000565}
566
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000567PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000568"allocate_lock() -> lock object\n\
569(allocate() is an obsolete synonym)\n\
570\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000571Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000572
Barry Warsawd0c10421996-12-17 00:05:22 +0000573static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000574thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000575{
576 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000577 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000578 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000579 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000580 return NULL;
581 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000582 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000583}
584
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000585PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000586"get_ident() -> integer\n\
587\n\
588Return a non-zero integer that uniquely identifies the current thread\n\
589amongst other threads that exist simultaneously.\n\
590This may be used to identify per-thread resources.\n\
591Even though on some platforms threads identities may appear to be\n\
592allocated consecutive numbers starting at 1, this behavior should not\n\
593be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000594A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000595
Barry Warsawd0c10421996-12-17 00:05:22 +0000596static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000597 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
598 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000599 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000600 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
601 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000602 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000603 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000604 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000605 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000606 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000607 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000608 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000609 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000610 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000611 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000612 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000613 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000614 METH_NOARGS, get_ident_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000615#ifndef NO_EXIT_PROG
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000616 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
617 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000618#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000619 {NULL, NULL} /* sentinel */
620};
621
622
623/* Initialization function */
624
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000625PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000626"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000627The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000628
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000629PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000630"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000631call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000632\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000633acquire() -- lock the lock, possibly blocking until it can be obtained\n\
634release() -- unlock of the lock\n\
635locked() -- test whether the lock is currently locked\n\
636\n\
637A lock is not owned by the thread that locked it; another thread may\n\
638unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000639will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000640
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000641PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000642initthread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000643{
Barry Warsawd0c10421996-12-17 00:05:22 +0000644 PyObject *m, *d;
Jim Fultond15dc062004-07-14 19:11:50 +0000645
646 /* Initialize types: */
647 if (PyType_Ready(&localtype) < 0)
648 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000649
650 /* Create the module and add the functions */
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000651 m = Py_InitModule3("thread", thread_methods, thread_doc);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000652
653 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000654 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000655 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000656 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000657 Locktype.tp_doc = lock_doc;
658 Py_INCREF(&Locktype);
659 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000660
Jim Fultond15dc062004-07-14 19:11:50 +0000661 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
662 return;
663
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000664 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000665 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000666}