blob: 098a78490d1fc8daf2741651c42a657a02601e0a [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;
Mark Hammondeb619bb2004-08-24 22:24:08 +0000416 PyGILState_STATE gstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000417 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000418
Mark Hammondeb619bb2004-08-24 22:24:08 +0000419 gstate = PyGILState_Ensure();
Guido van Rossuma027efa1997-05-05 20:56:21 +0000420 res = PyEval_CallObjectWithKeywords(
421 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000422 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000423 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000424 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000425 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000426 PyObject *file;
427 PySys_WriteStderr(
428 "Unhandled exception in thread started by ");
429 file = PySys_GetObject("stderr");
430 if (file)
431 PyFile_WriteObject(boot->func, file, 0);
432 else
433 PyObject_Print(boot->func, stderr, 0);
434 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000435 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000436 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000437 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000438 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000439 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000440 Py_DECREF(boot->func);
441 Py_DECREF(boot->args);
442 Py_XDECREF(boot->keyw);
443 PyMem_DEL(boot_raw);
Mark Hammondeb619bb2004-08-24 22:24:08 +0000444 PyGILState_Release(gstate);
Guido van Rossumbcc20741998-08-04 22:53:56 +0000445 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000446}
447
Barry Warsawd0c10421996-12-17 00:05:22 +0000448static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000449thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000450{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000451 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000452 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000453 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000454
Guido van Rossum43713e52000-02-29 13:59:29 +0000455 if (!PyArg_ParseTuple(fargs, "OO|O:start_new_thread", &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000456 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000457 if (!PyCallable_Check(func)) {
458 PyErr_SetString(PyExc_TypeError,
459 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000460 return NULL;
461 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000462 if (!PyTuple_Check(args)) {
463 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000464 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000465 return NULL;
466 }
467 if (keyw != NULL && !PyDict_Check(keyw)) {
468 PyErr_SetString(PyExc_TypeError,
469 "optional 3rd arg must be a dictionary");
470 return NULL;
471 }
472 boot = PyMem_NEW(struct bootstate, 1);
473 if (boot == NULL)
474 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000475 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000476 boot->func = func;
477 boot->args = args;
478 boot->keyw = keyw;
479 Py_INCREF(func);
480 Py_INCREF(args);
481 Py_XINCREF(keyw);
482 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000483 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
484 if (ident == -1) {
Guido van Rossum54c273c2005-02-20 03:02:16 +0000485 PyErr_SetString(ThreadError, "can't start new thread");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000486 Py_DECREF(func);
487 Py_DECREF(args);
488 Py_XDECREF(keyw);
489 PyMem_DEL(boot);
490 return NULL;
491 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000492 return PyInt_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000493}
494
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000495PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000496"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000497(start_new() is an obsolete synonym)\n\
498\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000499Start a new thread and return its identifier. The thread will call the\n\
500function with positional arguments from the tuple args and keyword arguments\n\
501taken from the optional dictionary kwargs. The thread exits when the\n\
502function returns; the return value is ignored. The thread will also exit\n\
503when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000504printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000505
Barry Warsawd0c10421996-12-17 00:05:22 +0000506static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000507thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000508{
Barry Warsawd0c10421996-12-17 00:05:22 +0000509 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000510 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000511}
512
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000513PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000514"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000515(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000516\n\
517This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000518thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000519
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000520static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000521thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000522{
523 PyErr_SetInterrupt();
524 Py_INCREF(Py_None);
525 return Py_None;
526}
527
528PyDoc_STRVAR(interrupt_doc,
529"interrupt_main()\n\
530\n\
531Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000532A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000533);
534
Guido van Rossumb6775db1994-08-01 11:34:53 +0000535#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000536static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000537thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000538{
539 int sts;
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000540 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000541 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000542 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000543 for (;;) { } /* Should not be reached */
544}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000545#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000546
Barry Warsawd0c10421996-12-17 00:05:22 +0000547static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000548thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000549{
Barry Warsawd0c10421996-12-17 00:05:22 +0000550 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000551}
552
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000553PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000554"allocate_lock() -> lock object\n\
555(allocate() is an obsolete synonym)\n\
556\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000557Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000558
Barry Warsawd0c10421996-12-17 00:05:22 +0000559static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000560thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000561{
562 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000563 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000564 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000565 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000566 return NULL;
567 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000568 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000569}
570
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000571PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000572"get_ident() -> integer\n\
573\n\
574Return a non-zero integer that uniquely identifies the current thread\n\
575amongst other threads that exist simultaneously.\n\
576This may be used to identify per-thread resources.\n\
577Even though on some platforms threads identities may appear to be\n\
578allocated consecutive numbers starting at 1, this behavior should not\n\
579be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000580A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000581
Barry Warsawd0c10421996-12-17 00:05:22 +0000582static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000583 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
584 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000585 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000586 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
587 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000588 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000589 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000590 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000591 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000592 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000593 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000594 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000595 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000596 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000597 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000598 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000599 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000600 METH_NOARGS, get_ident_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000601#ifndef NO_EXIT_PROG
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000602 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
603 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000604#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000605 {NULL, NULL} /* sentinel */
606};
607
608
609/* Initialization function */
610
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000611PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000612"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000613The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000614
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000615PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000616"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000617call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000618\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000619acquire() -- lock the lock, possibly blocking until it can be obtained\n\
620release() -- unlock of the lock\n\
621locked() -- test whether the lock is currently locked\n\
622\n\
623A lock is not owned by the thread that locked it; another thread may\n\
624unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000625will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000626
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000627PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000628initthread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000629{
Barry Warsawd0c10421996-12-17 00:05:22 +0000630 PyObject *m, *d;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000631
632 /* Initialize types: */
633 if (PyType_Ready(&localtype) < 0)
634 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000635
636 /* Create the module and add the functions */
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000637 m = Py_InitModule3("thread", thread_methods, thread_doc);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000638
639 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000640 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000641 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000642 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000643 Locktype.tp_doc = lock_doc;
644 Py_INCREF(&Locktype);
645 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000646
Michael W. Hudson64e08142005-06-15 12:25:20 +0000647 Py_INCREF(&localtype);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000648 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
649 return;
Jim Fultond15dc062004-07-14 19:11:50 +0000650
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000651 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000652 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000653}