blob: 3025595df1b2a8f91afaec6abe15bab100e80086 [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 {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000161 PyObject_HEAD
162 PyObject *key;
163 PyObject *args;
164 PyObject *kw;
165 PyObject *dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000166} localobject;
167
168static PyTypeObject localtype;
169
170static PyObject *
171local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
172{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000173 localobject *self;
174 PyObject *tdict;
Jim Fultond15dc062004-07-14 19:11:50 +0000175
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000176 if (type->tp_init == PyBaseObject_Type.tp_init
177 && ((args && PyObject_IsTrue(args))
178 || (kw && PyObject_IsTrue(kw)))) {
179 PyErr_SetString(PyExc_TypeError,
180 "Initialization arguments are not supported");
181 return NULL;
182 }
Jim Fultond15dc062004-07-14 19:11:50 +0000183
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000184 self = (localobject *)type->tp_alloc(type, 0);
185 if (self == NULL)
186 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000187
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000188 Py_XINCREF(args);
189 self->args = args;
190 Py_XINCREF(kw);
191 self->kw = kw;
192 self->dict = NULL; /* making sure */
193 self->key = PyString_FromFormat("thread.local.%p", self);
194 if (self->key == NULL)
195 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000196
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000197 self->dict = PyDict_New();
198 if (self->dict == NULL)
199 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000200
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000201 tdict = PyThreadState_GetDict();
202 if (tdict == NULL) {
203 PyErr_SetString(PyExc_SystemError,
204 "Couldn't get thread-state dictionary");
205 goto err;
206 }
Jim Fultond15dc062004-07-14 19:11:50 +0000207
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000208 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
209 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000210
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000211 return (PyObject *)self;
212
213 err:
214 Py_DECREF(self);
215 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000216}
217
218static int
219local_traverse(localobject *self, visitproc visit, void *arg)
220{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000221 Py_VISIT(self->args);
222 Py_VISIT(self->kw);
223 Py_VISIT(self->dict);
Jim Fultond15dc062004-07-14 19:11:50 +0000224 return 0;
225}
226
227static int
228local_clear(localobject *self)
229{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000230 Py_CLEAR(self->key);
231 Py_CLEAR(self->args);
232 Py_CLEAR(self->kw);
233 Py_CLEAR(self->dict);
234 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000235}
236
237static void
238local_dealloc(localobject *self)
239{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000240 PyThreadState *tstate;
241 if (self->key
242 && (tstate = PyThreadState_Get())
243 && tstate->interp) {
244 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
245 tstate;
246 tstate = PyThreadState_Next(tstate))
247 if (tstate->dict &&
248 PyDict_GetItem(tstate->dict, self->key))
249 PyDict_DelItem(tstate->dict, self->key);
250 }
Jim Fultond15dc062004-07-14 19:11:50 +0000251
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000252 local_clear(self);
253 self->ob_type->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000254}
255
256static PyObject *
257_ldict(localobject *self)
258{
259 PyObject *tdict, *ldict;
260
261 tdict = PyThreadState_GetDict();
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000262 if (tdict == NULL) {
263 PyErr_SetString(PyExc_SystemError,
264 "Couldn't get thread-state dictionary");
265 return NULL;
266 }
Jim Fultond15dc062004-07-14 19:11:50 +0000267
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000268 ldict = PyDict_GetItem(tdict, self->key);
269 if (ldict == NULL) {
270 ldict = PyDict_New(); /* we own ldict */
Jim Fultond15dc062004-07-14 19:11:50 +0000271
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000272 if (ldict == NULL)
273 return NULL;
274 else {
275 int i = PyDict_SetItem(tdict, self->key, ldict);
276 Py_DECREF(ldict); /* now ldict is borowed */
277 if (i < 0)
278 return NULL;
279 }
Jim Fultond15dc062004-07-14 19:11:50 +0000280
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000281 Py_CLEAR(self->dict);
282 Py_INCREF(ldict);
283 self->dict = ldict; /* still borrowed */
Jim Fultond15dc062004-07-14 19:11:50 +0000284
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000285 if (self->ob_type->tp_init != PyBaseObject_Type.tp_init &&
286 self->ob_type->tp_init((PyObject*)self,
287 self->args, self->kw) < 0) {
288 /* we need to get rid of ldict from thread so
289 we create a new one the next time we do an attr
290 acces */
291 PyDict_DelItem(tdict, self->key);
292 return NULL;
293 }
294
295 }
296 else if (self->dict != ldict) {
297 Py_CLEAR(self->dict);
298 Py_INCREF(ldict);
299 self->dict = ldict;
300 }
Jim Fultond15dc062004-07-14 19:11:50 +0000301
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000302 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000303}
304
305static PyObject *
306local_getattro(localobject *self, PyObject *name)
307{
308 PyObject *ldict, *value;
309
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000310 ldict = _ldict(self);
311 if (ldict == NULL)
312 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000313
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000314 if (self->ob_type != &localtype)
315 /* use generic lookup for subtypes */
316 return PyObject_GenericGetAttr((PyObject *)self, name);
Jim Fultond15dc062004-07-14 19:11:50 +0000317
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000318 /* Optimization: just look in dict ourselves */
319 value = PyDict_GetItem(ldict, name);
320 if (value == NULL)
321 /* Fall back on generic to get __class__ and __dict__ */
322 return PyObject_GenericGetAttr((PyObject *)self, name);
Jim Fultond15dc062004-07-14 19:11:50 +0000323
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000324 Py_INCREF(value);
325 return value;
Jim Fultond15dc062004-07-14 19:11:50 +0000326}
327
328static int
329local_setattro(localobject *self, PyObject *name, PyObject *v)
330{
331 PyObject *ldict;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000332
333 ldict = _ldict(self);
334 if (ldict == NULL)
335 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000336
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000337 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000338}
339
340static PyObject *
341local_getdict(localobject *self, void *closure)
342{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000343 if (self->dict == NULL) {
344 PyErr_SetString(PyExc_AttributeError, "__dict__");
345 return NULL;
346 }
Jim Fultond15dc062004-07-14 19:11:50 +0000347
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000348 Py_INCREF(self->dict);
349 return self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000350}
351
352static PyGetSetDef local_getset[] = {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000353 {"__dict__", (getter)local_getdict, (setter)NULL,
354 "Local-data dictionary", NULL},
355 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000356};
357
358static PyTypeObject localtype = {
359 PyObject_HEAD_INIT(NULL)
360 /* ob_size */ 0,
361 /* tp_name */ "thread._local",
362 /* tp_basicsize */ sizeof(localobject),
363 /* tp_itemsize */ 0,
364 /* tp_dealloc */ (destructor)local_dealloc,
365 /* tp_print */ (printfunc)0,
366 /* tp_getattr */ (getattrfunc)0,
367 /* tp_setattr */ (setattrfunc)0,
368 /* tp_compare */ (cmpfunc)0,
369 /* tp_repr */ (reprfunc)0,
370 /* tp_as_number */ 0,
371 /* tp_as_sequence */ 0,
372 /* tp_as_mapping */ 0,
373 /* tp_hash */ (hashfunc)0,
374 /* tp_call */ (ternaryfunc)0,
375 /* tp_str */ (reprfunc)0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000376 /* tp_getattro */ (getattrofunc)local_getattro,
377 /* tp_setattro */ (setattrofunc)local_setattro,
378 /* tp_as_buffer */ 0,
379 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Jim Fultond15dc062004-07-14 19:11:50 +0000380 /* tp_doc */ "Thread-local data",
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000381 /* tp_traverse */ (traverseproc)local_traverse,
382 /* tp_clear */ (inquiry)local_clear,
383 /* tp_richcompare */ (richcmpfunc)0,
384 /* tp_weaklistoffset */ (long)0,
385 /* tp_iter */ (getiterfunc)0,
386 /* tp_iternext */ (iternextfunc)0,
387 /* tp_methods */ 0,
388 /* tp_members */ 0,
389 /* tp_getset */ local_getset,
390 /* tp_base */ 0,
391 /* tp_dict */ 0, /* internal use */
392 /* tp_descr_get */ (descrgetfunc)0,
393 /* tp_descr_set */ (descrsetfunc)0,
394 /* tp_dictoffset */ offsetof(localobject, dict),
395 /* tp_init */ (initproc)0,
396 /* tp_alloc */ (allocfunc)0,
397 /* tp_new */ (newfunc)local_new,
Jim Fultond15dc062004-07-14 19:11:50 +0000398 /* tp_free */ 0, /* Low-level free-mem routine */
399 /* tp_is_gc */ (inquiry)0, /* For PyObject_IS_GC */
400};
401
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000402
403/* Module functions */
404
Guido van Rossuma027efa1997-05-05 20:56:21 +0000405struct bootstate {
406 PyInterpreterState *interp;
407 PyObject *func;
408 PyObject *args;
409 PyObject *keyw;
410};
411
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000412static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000413t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000414{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000415 struct bootstate *boot = (struct bootstate *) boot_raw;
Michael W. Hudson188d4362005-06-20 16:52:57 +0000416 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000417 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000418
Michael W. Hudson188d4362005-06-20 16:52:57 +0000419 tstate = PyThreadState_New(boot->interp);
420
421 PyEval_AcquireThread(tstate);
Guido van Rossuma027efa1997-05-05 20:56:21 +0000422 res = PyEval_CallObjectWithKeywords(
423 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000424 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000425 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000426 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000427 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000428 PyObject *file;
429 PySys_WriteStderr(
430 "Unhandled exception in thread started by ");
431 file = PySys_GetObject("stderr");
432 if (file)
433 PyFile_WriteObject(boot->func, file, 0);
434 else
435 PyObject_Print(boot->func, stderr, 0);
436 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000437 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000438 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000439 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000440 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000441 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000442 Py_DECREF(boot->func);
443 Py_DECREF(boot->args);
444 Py_XDECREF(boot->keyw);
445 PyMem_DEL(boot_raw);
Michael W. Hudson188d4362005-06-20 16:52:57 +0000446 PyThreadState_Clear(tstate);
447 PyThreadState_DeleteCurrent();
Guido van Rossumbcc20741998-08-04 22:53:56 +0000448 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000449}
450
Barry Warsawd0c10421996-12-17 00:05:22 +0000451static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000452thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000453{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000454 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000455 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000456 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000457
Guido van Rossum43713e52000-02-29 13:59:29 +0000458 if (!PyArg_ParseTuple(fargs, "OO|O:start_new_thread", &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000459 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000460 if (!PyCallable_Check(func)) {
461 PyErr_SetString(PyExc_TypeError,
462 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000463 return NULL;
464 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000465 if (!PyTuple_Check(args)) {
466 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000467 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000468 return NULL;
469 }
470 if (keyw != NULL && !PyDict_Check(keyw)) {
471 PyErr_SetString(PyExc_TypeError,
472 "optional 3rd arg must be a dictionary");
473 return NULL;
474 }
475 boot = PyMem_NEW(struct bootstate, 1);
476 if (boot == NULL)
477 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000478 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000479 boot->func = func;
480 boot->args = args;
481 boot->keyw = keyw;
482 Py_INCREF(func);
483 Py_INCREF(args);
484 Py_XINCREF(keyw);
485 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000486 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
487 if (ident == -1) {
Guido van Rossum54c273c2005-02-20 03:02:16 +0000488 PyErr_SetString(ThreadError, "can't start new thread");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000489 Py_DECREF(func);
490 Py_DECREF(args);
491 Py_XDECREF(keyw);
492 PyMem_DEL(boot);
493 return NULL;
494 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000495 return PyInt_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000496}
497
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000498PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000499"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000500(start_new() is an obsolete synonym)\n\
501\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000502Start a new thread and return its identifier. The thread will call the\n\
503function with positional arguments from the tuple args and keyword arguments\n\
504taken from the optional dictionary kwargs. The thread exits when the\n\
505function returns; the return value is ignored. The thread will also exit\n\
506when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000507printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000508
Barry Warsawd0c10421996-12-17 00:05:22 +0000509static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000510thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000511{
Barry Warsawd0c10421996-12-17 00:05:22 +0000512 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000513 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000514}
515
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000516PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000517"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000518(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000519\n\
520This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000521thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000522
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000523static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000524thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000525{
526 PyErr_SetInterrupt();
527 Py_INCREF(Py_None);
528 return Py_None;
529}
530
531PyDoc_STRVAR(interrupt_doc,
532"interrupt_main()\n\
533\n\
534Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000535A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000536);
537
Guido van Rossumb6775db1994-08-01 11:34:53 +0000538#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000539static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000540thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000541{
542 int sts;
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000543 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000544 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000545 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000546 for (;;) { } /* Should not be reached */
547}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000548#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000549
Barry Warsawd0c10421996-12-17 00:05:22 +0000550static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000551thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000552{
Barry Warsawd0c10421996-12-17 00:05:22 +0000553 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000554}
555
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000556PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000557"allocate_lock() -> lock object\n\
558(allocate() is an obsolete synonym)\n\
559\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000560Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000561
Barry Warsawd0c10421996-12-17 00:05:22 +0000562static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000563thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000564{
565 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000566 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000567 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000568 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000569 return NULL;
570 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000571 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000572}
573
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000574PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000575"get_ident() -> integer\n\
576\n\
577Return a non-zero integer that uniquely identifies the current thread\n\
578amongst other threads that exist simultaneously.\n\
579This may be used to identify per-thread resources.\n\
580Even though on some platforms threads identities may appear to be\n\
581allocated consecutive numbers starting at 1, this behavior should not\n\
582be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000583A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000584
Barry Warsawd0c10421996-12-17 00:05:22 +0000585static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000586 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
587 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000588 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000589 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
590 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000591 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000592 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000593 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000594 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000595 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000596 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000597 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000598 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000599 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000600 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000601 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000602 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000603 METH_NOARGS, get_ident_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000604#ifndef NO_EXIT_PROG
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000605 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
606 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000607#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000608 {NULL, NULL} /* sentinel */
609};
610
611
612/* Initialization function */
613
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000614PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000615"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000616The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000617
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000618PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000619"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000620call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000621\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000622acquire() -- lock the lock, possibly blocking until it can be obtained\n\
623release() -- unlock of the lock\n\
624locked() -- test whether the lock is currently locked\n\
625\n\
626A lock is not owned by the thread that locked it; another thread may\n\
627unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000628will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000629
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000630PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000631initthread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000632{
Barry Warsawd0c10421996-12-17 00:05:22 +0000633 PyObject *m, *d;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000634
635 /* Initialize types: */
636 if (PyType_Ready(&localtype) < 0)
637 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000638
639 /* Create the module and add the functions */
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000640 m = Py_InitModule3("thread", thread_methods, thread_doc);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000641
642 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000643 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000644 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000645 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000646 Locktype.tp_doc = lock_doc;
647 Py_INCREF(&Locktype);
648 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000649
Michael W. Hudson64e08142005-06-15 12:25:20 +0000650 Py_INCREF(&localtype);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000651 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
652 return;
Jim Fultond15dc062004-07-14 19:11:50 +0000653
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000654 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000655 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000656}