blob: 245c51dfdf236de2a8d429d501c987602a0dcdc8 [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
Andrew M. Kuchlinga43ece92005-06-02 17:07:11 +000066 return PyBool_FromLong((long)i);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000067}
68
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000069PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000070"acquire([wait]) -> None or bool\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +000071(PyThread_acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000072\n\
73Lock the lock. Without argument, this blocks if the lock is already\n\
74locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000075the lock, and return None once the lock is acquired.\n\
76With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000077and the return value reflects whether the lock is acquired.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000078The blocking operation is not interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000079
Barry Warsawd0c10421996-12-17 00:05:22 +000080static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000081lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000082{
Guido van Rossum1984f1e1992-08-04 12:41:02 +000083 /* Sanity check: the lock must be locked */
Guido van Rossum65d5b571998-12-21 19:32:43 +000084 if (PyThread_acquire_lock(self->lock_lock, 0)) {
85 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000086 PyErr_SetString(ThreadError, "release unlocked lock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +000087 return NULL;
88 }
89
Guido van Rossum65d5b571998-12-21 19:32:43 +000090 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000091 Py_INCREF(Py_None);
92 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000093}
94
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000095PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +000096"release()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +000097(PyThread_release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000098\n\
99Release the lock, allowing another thread that is blocked waiting for\n\
100the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000101but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000102
Barry Warsawd0c10421996-12-17 00:05:22 +0000103static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000104lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000105{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000106 if (PyThread_acquire_lock(self->lock_lock, 0)) {
107 PyThread_release_lock(self->lock_lock);
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000108 return PyBool_FromLong(0L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000109 }
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000110 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000111}
112
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000113PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000114"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000115(locked_lock() is an obsolete synonym)\n\
116\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000117Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000118
Barry Warsawd0c10421996-12-17 00:05:22 +0000119static PyMethodDef lock_methods[] = {
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000120 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000121 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000122 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000123 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000124 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000125 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000126 {"release", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000127 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000128 {"locked_lock", (PyCFunction)lock_locked_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000129 METH_NOARGS, locked_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000130 {"locked", (PyCFunction)lock_locked_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000131 METH_NOARGS, locked_doc},
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000132 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000133};
134
Barry Warsawd0c10421996-12-17 00:05:22 +0000135static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000136lock_getattr(lockobject *self, char *name)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000137{
Barry Warsawd0c10421996-12-17 00:05:22 +0000138 return Py_FindMethod(lock_methods, (PyObject *)self, name);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000139}
140
Barry Warsawd0c10421996-12-17 00:05:22 +0000141static PyTypeObject Locktype = {
142 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000143 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000144 "thread.lock", /*tp_name*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000145 sizeof(lockobject), /*tp_size*/
146 0, /*tp_itemsize*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000147 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000148 (destructor)lock_dealloc, /*tp_dealloc*/
149 0, /*tp_print*/
150 (getattrfunc)lock_getattr, /*tp_getattr*/
151 0, /*tp_setattr*/
152 0, /*tp_compare*/
153 0, /*tp_repr*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000154};
155
Jim Fultond15dc062004-07-14 19:11:50 +0000156/* Thread-local objects */
157
158#include "structmember.h"
159
160typedef struct {
161 PyObject_HEAD
162 PyObject *key;
163 PyObject *args;
164 PyObject *kw;
165 PyObject *dict;
166} localobject;
167
168static PyTypeObject localtype;
169
170static PyObject *
171local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
172{
173 localobject *self;
174 PyObject *tdict;
175
176 if (type->tp_init == PyBaseObject_Type.tp_init
177 && ((args && PyObject_IsTrue(args))
178 ||
179 (kw && PyObject_IsTrue(kw))
180 )
181 ) {
182 PyErr_SetString(PyExc_TypeError,
183 "Initialization arguments are not supported");
184 return NULL;
185 }
186
187 self = (localobject *)type->tp_alloc(type, 0);
188 if (self == NULL)
189 return NULL;
190
191 Py_XINCREF(args);
192 self->args = args;
193 Py_XINCREF(kw);
194 self->kw = kw;
195 self->dict = NULL; /* making sure */
196 self->key = PyString_FromFormat("thread.local.%p", self);
197 if (self->key == NULL)
198 goto err;
199
200 self->dict = PyDict_New();
201 if (self->dict == NULL)
202 goto err;
203
204 tdict = PyThreadState_GetDict();
205 if (tdict == NULL) {
206 PyErr_SetString(PyExc_SystemError,
207 "Couldn't get thread-state dictionary");
208 goto err;
209 }
210
211 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
212 goto err;
213
214 return (PyObject *)self;
215
216 err:
217 Py_DECREF(self);
218 return NULL;
219}
220
221static int
222local_traverse(localobject *self, visitproc visit, void *arg)
223{
224 Py_VISIT(self->args);
225 Py_VISIT(self->kw);
226 Py_VISIT(self->dict);
227 return 0;
228}
229
230static int
231local_clear(localobject *self)
232{
233 Py_CLEAR(self->key);
234 Py_CLEAR(self->args);
235 Py_CLEAR(self->kw);
236 Py_CLEAR(self->dict);
237 return 0;
238}
239
240static void
241local_dealloc(localobject *self)
242{
243 PyThreadState *tstate;
244 if (self->key
245 && (tstate = PyThreadState_Get())
246 && tstate->interp) {
247 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
248 tstate;
249 tstate = PyThreadState_Next(tstate)
250 )
251 if (tstate->dict &&
252 PyDict_GetItem(tstate->dict, self->key))
253 PyDict_DelItem(tstate->dict, self->key);
254 }
255
256 local_clear(self);
257 self->ob_type->tp_free((PyObject*)self);
258}
259
260static PyObject *
261_ldict(localobject *self)
262{
263 PyObject *tdict, *ldict;
264
265 tdict = PyThreadState_GetDict();
266 if (tdict == NULL) {
267 PyErr_SetString(PyExc_SystemError,
268 "Couldn't get thread-state dictionary");
269 return NULL;
270 }
271
272 ldict = PyDict_GetItem(tdict, self->key);
273 if (ldict == NULL) {
274 ldict = PyDict_New(); /* we own ldict */
275
276 if (ldict == NULL)
277 return NULL;
278 else {
279 int i = PyDict_SetItem(tdict, self->key, ldict);
280 Py_DECREF(ldict); /* now ldict is borowed */
281 if (i < 0)
282 return NULL;
283 }
284
285 Py_CLEAR(self->dict);
286 Py_INCREF(ldict);
287 self->dict = ldict; /* still borrowed */
288
289 if (self->ob_type->tp_init != PyBaseObject_Type.tp_init &&
290 self->ob_type->tp_init((PyObject*)self,
291 self->args, self->kw) < 0
292 ) {
293 /* we need to get rid of ldict from thread so
294 we create a new one the next time we do an attr
295 acces */
296 PyDict_DelItem(tdict, self->key);
297 return NULL;
298 }
299
300 }
301 else if (self->dict != ldict) {
302 Py_CLEAR(self->dict);
303 Py_INCREF(ldict);
304 self->dict = ldict;
305 }
306
307 return ldict;
308}
309
310static PyObject *
311local_getattro(localobject *self, PyObject *name)
312{
313 PyObject *ldict, *value;
314
315 ldict = _ldict(self);
316 if (ldict == NULL)
317 return NULL;
318
319 if (self->ob_type != &localtype)
320 /* use generic lookup for subtypes */
321 return PyObject_GenericGetAttr((PyObject *)self, name);
322
323 /* Optimization: just look in dict ourselves */
324 value = PyDict_GetItem(ldict, name);
325 if (value == NULL)
326 /* Fall back on generic to get __class__ and __dict__ */
327 return PyObject_GenericGetAttr((PyObject *)self, name);
328
329 Py_INCREF(value);
330 return value;
331}
332
333static int
334local_setattro(localobject *self, PyObject *name, PyObject *v)
335{
336 PyObject *ldict;
337
338 ldict = _ldict(self);
339 if (ldict == NULL)
340 return -1;
341
342 return PyObject_GenericSetAttr((PyObject *)self, name, v);
343}
344
345static PyObject *
346local_getdict(localobject *self, void *closure)
347{
348 if (self->dict == NULL) {
349 PyErr_SetString(PyExc_AttributeError, "__dict__");
350 return NULL;
351 }
352
353 Py_INCREF(self->dict);
354 return self->dict;
355}
356
357static PyGetSetDef local_getset[] = {
358 {"__dict__",
359 (getter)local_getdict, (setter)0,
360 "Local-data dictionary",
361 NULL},
362 {NULL} /* Sentinel */
363};
364
365static PyTypeObject localtype = {
366 PyObject_HEAD_INIT(NULL)
367 /* ob_size */ 0,
368 /* tp_name */ "thread._local",
369 /* tp_basicsize */ sizeof(localobject),
370 /* tp_itemsize */ 0,
371 /* tp_dealloc */ (destructor)local_dealloc,
372 /* tp_print */ (printfunc)0,
373 /* tp_getattr */ (getattrfunc)0,
374 /* tp_setattr */ (setattrfunc)0,
375 /* tp_compare */ (cmpfunc)0,
376 /* tp_repr */ (reprfunc)0,
377 /* tp_as_number */ 0,
378 /* tp_as_sequence */ 0,
379 /* tp_as_mapping */ 0,
380 /* tp_hash */ (hashfunc)0,
381 /* tp_call */ (ternaryfunc)0,
382 /* tp_str */ (reprfunc)0,
383 /* tp_getattro */ (getattrofunc)local_getattro,
384 /* tp_setattro */ (setattrofunc)local_setattro,
385 /* tp_as_buffer */ 0,
386 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
387 /* tp_doc */ "Thread-local data",
388 /* tp_traverse */ (traverseproc)local_traverse,
389 /* tp_clear */ (inquiry)local_clear,
390 /* tp_richcompare */ (richcmpfunc)0,
391 /* tp_weaklistoffset */ (long)0,
392 /* tp_iter */ (getiterfunc)0,
393 /* tp_iternext */ (iternextfunc)0,
394 /* tp_methods */ 0,
395 /* tp_members */ 0,
396 /* tp_getset */ local_getset,
397 /* tp_base */ 0,
398 /* tp_dict */ 0, /* internal use */
399 /* tp_descr_get */ (descrgetfunc)0,
400 /* tp_descr_set */ (descrsetfunc)0,
401 /* tp_dictoffset */ offsetof(localobject, dict),
402 /* tp_init */ (initproc)0,
403 /* tp_alloc */ (allocfunc)0,
404 /* tp_new */ (newfunc)local_new,
405 /* tp_free */ 0, /* Low-level free-mem routine */
406 /* tp_is_gc */ (inquiry)0, /* For PyObject_IS_GC */
407};
408
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000409
410/* Module functions */
411
Guido van Rossuma027efa1997-05-05 20:56:21 +0000412struct bootstate {
413 PyInterpreterState *interp;
414 PyObject *func;
415 PyObject *args;
416 PyObject *keyw;
417};
418
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000419static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000420t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000421{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000422 struct bootstate *boot = (struct bootstate *) boot_raw;
Mark Hammondeb619bb2004-08-24 22:24:08 +0000423 PyGILState_STATE gstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000424 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000425
Mark Hammondeb619bb2004-08-24 22:24:08 +0000426 gstate = PyGILState_Ensure();
Guido van Rossuma027efa1997-05-05 20:56:21 +0000427 res = PyEval_CallObjectWithKeywords(
428 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000429 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000430 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000431 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000432 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000433 PyObject *file;
434 PySys_WriteStderr(
435 "Unhandled exception in thread started by ");
436 file = PySys_GetObject("stderr");
437 if (file)
438 PyFile_WriteObject(boot->func, file, 0);
439 else
440 PyObject_Print(boot->func, stderr, 0);
441 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000442 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000443 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000444 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000445 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000446 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000447 Py_DECREF(boot->func);
448 Py_DECREF(boot->args);
449 Py_XDECREF(boot->keyw);
450 PyMem_DEL(boot_raw);
Mark Hammondeb619bb2004-08-24 22:24:08 +0000451 PyGILState_Release(gstate);
Guido van Rossumbcc20741998-08-04 22:53:56 +0000452 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000453}
454
Barry Warsawd0c10421996-12-17 00:05:22 +0000455static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000456thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000457{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000458 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000459 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000460 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000461
Guido van Rossum43713e52000-02-29 13:59:29 +0000462 if (!PyArg_ParseTuple(fargs, "OO|O:start_new_thread", &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000463 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000464 if (!PyCallable_Check(func)) {
465 PyErr_SetString(PyExc_TypeError,
466 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000467 return NULL;
468 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000469 if (!PyTuple_Check(args)) {
470 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000471 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000472 return NULL;
473 }
474 if (keyw != NULL && !PyDict_Check(keyw)) {
475 PyErr_SetString(PyExc_TypeError,
476 "optional 3rd arg must be a dictionary");
477 return NULL;
478 }
479 boot = PyMem_NEW(struct bootstate, 1);
480 if (boot == NULL)
481 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000482 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000483 boot->func = func;
484 boot->args = args;
485 boot->keyw = keyw;
486 Py_INCREF(func);
487 Py_INCREF(args);
488 Py_XINCREF(keyw);
489 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000490 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
491 if (ident == -1) {
Guido van Rossum54c273c2005-02-20 03:02:16 +0000492 PyErr_SetString(ThreadError, "can't start new thread");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000493 Py_DECREF(func);
494 Py_DECREF(args);
495 Py_XDECREF(keyw);
496 PyMem_DEL(boot);
497 return NULL;
498 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000499 return PyInt_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000500}
501
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000502PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000503"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000504(start_new() is an obsolete synonym)\n\
505\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000506Start a new thread and return its identifier. The thread will call the\n\
507function with positional arguments from the tuple args and keyword arguments\n\
508taken from the optional dictionary kwargs. The thread exits when the\n\
509function returns; the return value is ignored. The thread will also exit\n\
510when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000511printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000512
Barry Warsawd0c10421996-12-17 00:05:22 +0000513static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000514thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000515{
Barry Warsawd0c10421996-12-17 00:05:22 +0000516 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000517 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000518}
519
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000520PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000521"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000522(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000523\n\
524This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000525thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000526
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000527static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000528thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000529{
530 PyErr_SetInterrupt();
531 Py_INCREF(Py_None);
532 return Py_None;
533}
534
535PyDoc_STRVAR(interrupt_doc,
536"interrupt_main()\n\
537\n\
538Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000539A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000540);
541
Guido van Rossumb6775db1994-08-01 11:34:53 +0000542#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000543static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000544thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000545{
546 int sts;
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000547 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000548 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000549 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000550 for (;;) { } /* Should not be reached */
551}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000552#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000553
Barry Warsawd0c10421996-12-17 00:05:22 +0000554static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000555thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000556{
Barry Warsawd0c10421996-12-17 00:05:22 +0000557 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000558}
559
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000560PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000561"allocate_lock() -> lock object\n\
562(allocate() is an obsolete synonym)\n\
563\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000564Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000565
Barry Warsawd0c10421996-12-17 00:05:22 +0000566static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000567thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000568{
569 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000570 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000571 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000572 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000573 return NULL;
574 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000575 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000576}
577
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000578PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000579"get_ident() -> integer\n\
580\n\
581Return a non-zero integer that uniquely identifies the current thread\n\
582amongst other threads that exist simultaneously.\n\
583This may be used to identify per-thread resources.\n\
584Even though on some platforms threads identities may appear to be\n\
585allocated consecutive numbers starting at 1, this behavior should not\n\
586be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000587A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000588
Barry Warsawd0c10421996-12-17 00:05:22 +0000589static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000590 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
591 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000592 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000593 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
594 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000595 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000596 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000597 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000598 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000599 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000600 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000601 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000602 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000603 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000604 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000605 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000606 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000607 METH_NOARGS, get_ident_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000608#ifndef NO_EXIT_PROG
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000609 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
610 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000611#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000612 {NULL, NULL} /* sentinel */
613};
614
615
616/* Initialization function */
617
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000618PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000619"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000620The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000621
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000622PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000623"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000624call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000625\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000626acquire() -- lock the lock, possibly blocking until it can be obtained\n\
627release() -- unlock of the lock\n\
628locked() -- test whether the lock is currently locked\n\
629\n\
630A lock is not owned by the thread that locked it; another thread may\n\
631unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000632will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000633
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000634PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000635initthread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000636{
Barry Warsawd0c10421996-12-17 00:05:22 +0000637 PyObject *m, *d;
Jim Fultond15dc062004-07-14 19:11:50 +0000638
639 /* Initialize types: */
640 if (PyType_Ready(&localtype) < 0)
641 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000642
643 /* Create the module and add the functions */
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000644 m = Py_InitModule3("thread", thread_methods, thread_doc);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000645
646 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000647 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000648 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000649 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000650 Locktype.tp_doc = lock_doc;
651 Py_INCREF(&Locktype);
652 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000653
Jim Fultond15dc062004-07-14 19:11:50 +0000654 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
655 return;
656
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000657 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000658 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000659}