blob: 9a6c5d80573576723be483679a49ee8f143ecc82 [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 Rossumf6694362006-03-10 02:28:35 +000071(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 Rossumf6694362006-03-10 02:28:35 +000097(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
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000119static PyObject *
120lock_context(lockobject *self)
121{
122 Py_INCREF(self);
123 return (PyObject *)self;
124}
125
Barry Warsawd0c10421996-12-17 00:05:22 +0000126static PyMethodDef lock_methods[] = {
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000127 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000128 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000129 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000130 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000131 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000132 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000133 {"release", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000134 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000135 {"locked_lock", (PyCFunction)lock_locked_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000136 METH_NOARGS, locked_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000137 {"locked", (PyCFunction)lock_locked_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000138 METH_NOARGS, locked_doc},
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000139 {"__context__", (PyCFunction)lock_context,
140 METH_NOARGS, PyDoc_STR("__context__() -> self.")},
141 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
142 METH_VARARGS, acquire_doc},
Guido van Rossumf6694362006-03-10 02:28:35 +0000143 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
144 METH_VARARGS, release_doc},
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000145 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000146};
147
Barry Warsawd0c10421996-12-17 00:05:22 +0000148static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000149lock_getattr(lockobject *self, char *name)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000150{
Barry Warsawd0c10421996-12-17 00:05:22 +0000151 return Py_FindMethod(lock_methods, (PyObject *)self, name);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000152}
153
Barry Warsawd0c10421996-12-17 00:05:22 +0000154static PyTypeObject Locktype = {
155 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000156 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000157 "thread.lock", /*tp_name*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000158 sizeof(lockobject), /*tp_size*/
159 0, /*tp_itemsize*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000160 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000161 (destructor)lock_dealloc, /*tp_dealloc*/
162 0, /*tp_print*/
163 (getattrfunc)lock_getattr, /*tp_getattr*/
164 0, /*tp_setattr*/
165 0, /*tp_compare*/
166 0, /*tp_repr*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000167};
168
Jim Fultond15dc062004-07-14 19:11:50 +0000169/* Thread-local objects */
170
171#include "structmember.h"
172
173typedef struct {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000174 PyObject_HEAD
175 PyObject *key;
176 PyObject *args;
177 PyObject *kw;
178 PyObject *dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000179} localobject;
180
181static PyTypeObject localtype;
182
183static PyObject *
184local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
185{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000186 localobject *self;
187 PyObject *tdict;
Jim Fultond15dc062004-07-14 19:11:50 +0000188
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000189 if (type->tp_init == PyBaseObject_Type.tp_init
190 && ((args && PyObject_IsTrue(args))
191 || (kw && PyObject_IsTrue(kw)))) {
192 PyErr_SetString(PyExc_TypeError,
193 "Initialization arguments are not supported");
194 return NULL;
195 }
Jim Fultond15dc062004-07-14 19:11:50 +0000196
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000197 self = (localobject *)type->tp_alloc(type, 0);
198 if (self == NULL)
199 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000200
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000201 Py_XINCREF(args);
202 self->args = args;
203 Py_XINCREF(kw);
204 self->kw = kw;
205 self->dict = NULL; /* making sure */
206 self->key = PyString_FromFormat("thread.local.%p", self);
207 if (self->key == NULL)
208 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000209
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000210 self->dict = PyDict_New();
211 if (self->dict == NULL)
212 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000213
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000214 tdict = PyThreadState_GetDict();
215 if (tdict == NULL) {
216 PyErr_SetString(PyExc_SystemError,
217 "Couldn't get thread-state dictionary");
218 goto err;
219 }
Jim Fultond15dc062004-07-14 19:11:50 +0000220
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000221 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
222 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000223
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000224 return (PyObject *)self;
225
226 err:
227 Py_DECREF(self);
228 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000229}
230
231static int
232local_traverse(localobject *self, visitproc visit, void *arg)
233{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000234 Py_VISIT(self->args);
235 Py_VISIT(self->kw);
236 Py_VISIT(self->dict);
Jim Fultond15dc062004-07-14 19:11:50 +0000237 return 0;
238}
239
240static int
241local_clear(localobject *self)
242{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000243 Py_CLEAR(self->key);
244 Py_CLEAR(self->args);
245 Py_CLEAR(self->kw);
246 Py_CLEAR(self->dict);
247 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000248}
249
250static void
251local_dealloc(localobject *self)
252{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000253 PyThreadState *tstate;
254 if (self->key
255 && (tstate = PyThreadState_Get())
256 && tstate->interp) {
257 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
258 tstate;
259 tstate = PyThreadState_Next(tstate))
260 if (tstate->dict &&
261 PyDict_GetItem(tstate->dict, self->key))
262 PyDict_DelItem(tstate->dict, self->key);
263 }
Jim Fultond15dc062004-07-14 19:11:50 +0000264
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000265 local_clear(self);
266 self->ob_type->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000267}
268
269static PyObject *
270_ldict(localobject *self)
271{
272 PyObject *tdict, *ldict;
273
274 tdict = PyThreadState_GetDict();
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000275 if (tdict == NULL) {
276 PyErr_SetString(PyExc_SystemError,
277 "Couldn't get thread-state dictionary");
278 return NULL;
279 }
Jim Fultond15dc062004-07-14 19:11:50 +0000280
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000281 ldict = PyDict_GetItem(tdict, self->key);
282 if (ldict == NULL) {
283 ldict = PyDict_New(); /* we own ldict */
Jim Fultond15dc062004-07-14 19:11:50 +0000284
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000285 if (ldict == NULL)
286 return NULL;
287 else {
288 int i = PyDict_SetItem(tdict, self->key, ldict);
Georg Brandlf3c4ad12006-03-08 12:24:33 +0000289 Py_DECREF(ldict); /* now ldict is borrowed */
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000290 if (i < 0)
291 return NULL;
292 }
Jim Fultond15dc062004-07-14 19:11:50 +0000293
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000294 Py_CLEAR(self->dict);
295 Py_INCREF(ldict);
296 self->dict = ldict; /* still borrowed */
Jim Fultond15dc062004-07-14 19:11:50 +0000297
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000298 if (self->ob_type->tp_init != PyBaseObject_Type.tp_init &&
299 self->ob_type->tp_init((PyObject*)self,
300 self->args, self->kw) < 0) {
301 /* we need to get rid of ldict from thread so
302 we create a new one the next time we do an attr
303 acces */
304 PyDict_DelItem(tdict, self->key);
305 return NULL;
306 }
307
308 }
309 else if (self->dict != ldict) {
310 Py_CLEAR(self->dict);
311 Py_INCREF(ldict);
312 self->dict = ldict;
313 }
Jim Fultond15dc062004-07-14 19:11:50 +0000314
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000315 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000316}
317
318static PyObject *
319local_getattro(localobject *self, PyObject *name)
320{
321 PyObject *ldict, *value;
322
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000323 ldict = _ldict(self);
324 if (ldict == NULL)
325 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000326
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000327 if (self->ob_type != &localtype)
328 /* use generic lookup for subtypes */
329 return PyObject_GenericGetAttr((PyObject *)self, name);
Jim Fultond15dc062004-07-14 19:11:50 +0000330
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000331 /* Optimization: just look in dict ourselves */
332 value = PyDict_GetItem(ldict, name);
333 if (value == NULL)
334 /* Fall back on generic to get __class__ and __dict__ */
335 return PyObject_GenericGetAttr((PyObject *)self, name);
Jim Fultond15dc062004-07-14 19:11:50 +0000336
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000337 Py_INCREF(value);
338 return value;
Jim Fultond15dc062004-07-14 19:11:50 +0000339}
340
341static int
342local_setattro(localobject *self, PyObject *name, PyObject *v)
343{
344 PyObject *ldict;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000345
346 ldict = _ldict(self);
347 if (ldict == NULL)
348 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000349
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000350 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000351}
352
353static PyObject *
354local_getdict(localobject *self, void *closure)
355{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000356 if (self->dict == NULL) {
357 PyErr_SetString(PyExc_AttributeError, "__dict__");
358 return NULL;
359 }
Jim Fultond15dc062004-07-14 19:11:50 +0000360
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000361 Py_INCREF(self->dict);
362 return self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000363}
364
365static PyGetSetDef local_getset[] = {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000366 {"__dict__", (getter)local_getdict, (setter)NULL,
367 "Local-data dictionary", NULL},
368 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000369};
370
371static PyTypeObject localtype = {
372 PyObject_HEAD_INIT(NULL)
373 /* ob_size */ 0,
374 /* tp_name */ "thread._local",
375 /* tp_basicsize */ sizeof(localobject),
376 /* tp_itemsize */ 0,
377 /* tp_dealloc */ (destructor)local_dealloc,
378 /* tp_print */ (printfunc)0,
379 /* tp_getattr */ (getattrfunc)0,
380 /* tp_setattr */ (setattrfunc)0,
381 /* tp_compare */ (cmpfunc)0,
382 /* tp_repr */ (reprfunc)0,
383 /* tp_as_number */ 0,
384 /* tp_as_sequence */ 0,
385 /* tp_as_mapping */ 0,
386 /* tp_hash */ (hashfunc)0,
387 /* tp_call */ (ternaryfunc)0,
388 /* tp_str */ (reprfunc)0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000389 /* tp_getattro */ (getattrofunc)local_getattro,
390 /* tp_setattro */ (setattrofunc)local_setattro,
391 /* tp_as_buffer */ 0,
392 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Jim Fultond15dc062004-07-14 19:11:50 +0000393 /* tp_doc */ "Thread-local data",
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000394 /* tp_traverse */ (traverseproc)local_traverse,
395 /* tp_clear */ (inquiry)local_clear,
396 /* tp_richcompare */ (richcmpfunc)0,
397 /* tp_weaklistoffset */ (long)0,
398 /* tp_iter */ (getiterfunc)0,
399 /* tp_iternext */ (iternextfunc)0,
400 /* tp_methods */ 0,
401 /* tp_members */ 0,
402 /* tp_getset */ local_getset,
403 /* tp_base */ 0,
404 /* tp_dict */ 0, /* internal use */
405 /* tp_descr_get */ (descrgetfunc)0,
406 /* tp_descr_set */ (descrsetfunc)0,
407 /* tp_dictoffset */ offsetof(localobject, dict),
408 /* tp_init */ (initproc)0,
409 /* tp_alloc */ (allocfunc)0,
410 /* tp_new */ (newfunc)local_new,
Jim Fultond15dc062004-07-14 19:11:50 +0000411 /* tp_free */ 0, /* Low-level free-mem routine */
412 /* tp_is_gc */ (inquiry)0, /* For PyObject_IS_GC */
413};
414
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000415
416/* Module functions */
417
Guido van Rossuma027efa1997-05-05 20:56:21 +0000418struct bootstate {
419 PyInterpreterState *interp;
420 PyObject *func;
421 PyObject *args;
422 PyObject *keyw;
423};
424
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000425static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000426t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000427{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000428 struct bootstate *boot = (struct bootstate *) boot_raw;
Michael W. Hudson188d4362005-06-20 16:52:57 +0000429 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000430 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000431
Michael W. Hudson188d4362005-06-20 16:52:57 +0000432 tstate = PyThreadState_New(boot->interp);
433
434 PyEval_AcquireThread(tstate);
Guido van Rossuma027efa1997-05-05 20:56:21 +0000435 res = PyEval_CallObjectWithKeywords(
436 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000437 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000438 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000439 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000440 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000441 PyObject *file;
442 PySys_WriteStderr(
443 "Unhandled exception in thread started by ");
444 file = PySys_GetObject("stderr");
445 if (file)
446 PyFile_WriteObject(boot->func, file, 0);
447 else
448 PyObject_Print(boot->func, stderr, 0);
449 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000450 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000451 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000452 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000453 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000454 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000455 Py_DECREF(boot->func);
456 Py_DECREF(boot->args);
457 Py_XDECREF(boot->keyw);
458 PyMem_DEL(boot_raw);
Michael W. Hudson188d4362005-06-20 16:52:57 +0000459 PyThreadState_Clear(tstate);
460 PyThreadState_DeleteCurrent();
Guido van Rossumbcc20741998-08-04 22:53:56 +0000461 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000462}
463
Barry Warsawd0c10421996-12-17 00:05:22 +0000464static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000465thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000466{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000467 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000468 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000469 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000470
Guido van Rossum43713e52000-02-29 13:59:29 +0000471 if (!PyArg_ParseTuple(fargs, "OO|O:start_new_thread", &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000472 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000473 if (!PyCallable_Check(func)) {
474 PyErr_SetString(PyExc_TypeError,
475 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000476 return NULL;
477 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000478 if (!PyTuple_Check(args)) {
479 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000480 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000481 return NULL;
482 }
483 if (keyw != NULL && !PyDict_Check(keyw)) {
484 PyErr_SetString(PyExc_TypeError,
485 "optional 3rd arg must be a dictionary");
486 return NULL;
487 }
488 boot = PyMem_NEW(struct bootstate, 1);
489 if (boot == NULL)
490 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000491 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000492 boot->func = func;
493 boot->args = args;
494 boot->keyw = keyw;
495 Py_INCREF(func);
496 Py_INCREF(args);
497 Py_XINCREF(keyw);
498 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000499 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
500 if (ident == -1) {
Guido van Rossum54c273c2005-02-20 03:02:16 +0000501 PyErr_SetString(ThreadError, "can't start new thread");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000502 Py_DECREF(func);
503 Py_DECREF(args);
504 Py_XDECREF(keyw);
505 PyMem_DEL(boot);
506 return NULL;
507 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000508 return PyInt_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000509}
510
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000511PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000512"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000513(start_new() is an obsolete synonym)\n\
514\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000515Start a new thread and return its identifier. The thread will call the\n\
516function with positional arguments from the tuple args and keyword arguments\n\
517taken from the optional dictionary kwargs. The thread exits when the\n\
518function returns; the return value is ignored. The thread will also exit\n\
519when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000520printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000521
Barry Warsawd0c10421996-12-17 00:05:22 +0000522static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000523thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000524{
Barry Warsawd0c10421996-12-17 00:05:22 +0000525 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000526 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000527}
528
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000529PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000530"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000531(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000532\n\
533This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000534thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000535
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000536static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000537thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000538{
539 PyErr_SetInterrupt();
540 Py_INCREF(Py_None);
541 return Py_None;
542}
543
544PyDoc_STRVAR(interrupt_doc,
545"interrupt_main()\n\
546\n\
547Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000548A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000549);
550
Guido van Rossumb6775db1994-08-01 11:34:53 +0000551#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000552static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000553thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000554{
555 int sts;
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000556 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000557 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000558 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000559 for (;;) { } /* Should not be reached */
560}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000561#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000562
Barry Warsawd0c10421996-12-17 00:05:22 +0000563static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000564thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000565{
Barry Warsawd0c10421996-12-17 00:05:22 +0000566 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000567}
568
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000569PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000570"allocate_lock() -> lock object\n\
571(allocate() is an obsolete synonym)\n\
572\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000573Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000574
Barry Warsawd0c10421996-12-17 00:05:22 +0000575static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000576thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000577{
578 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000579 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000580 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000581 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000582 return NULL;
583 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000584 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000585}
586
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000587PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000588"get_ident() -> integer\n\
589\n\
590Return a non-zero integer that uniquely identifies the current thread\n\
591amongst other threads that exist simultaneously.\n\
592This may be used to identify per-thread resources.\n\
593Even though on some platforms threads identities may appear to be\n\
594allocated consecutive numbers starting at 1, this behavior should not\n\
595be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000596A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000597
Barry Warsawd0c10421996-12-17 00:05:22 +0000598static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000599 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
600 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000601 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000602 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
603 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000604 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000605 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000606 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000607 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000608 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000609 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000610 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000611 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000612 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000613 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000614 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000615 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000616 METH_NOARGS, get_ident_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000617#ifndef NO_EXIT_PROG
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000618 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
619 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000620#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000621 {NULL, NULL} /* sentinel */
622};
623
624
625/* Initialization function */
626
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000627PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000628"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000629The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000630
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000631PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000632"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000633call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000634\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000635acquire() -- lock the lock, possibly blocking until it can be obtained\n\
636release() -- unlock of the lock\n\
637locked() -- test whether the lock is currently locked\n\
638\n\
639A lock is not owned by the thread that locked it; another thread may\n\
640unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000641will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000642
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000643PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000644initthread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000645{
Barry Warsawd0c10421996-12-17 00:05:22 +0000646 PyObject *m, *d;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000647
648 /* Initialize types: */
649 if (PyType_Ready(&localtype) < 0)
650 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000651
652 /* Create the module and add the functions */
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000653 m = Py_InitModule3("thread", thread_methods, thread_doc);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000654 if (m == NULL)
655 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000656
657 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000658 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000659 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000660 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000661 Locktype.tp_doc = lock_doc;
662 Py_INCREF(&Locktype);
663 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000664
Michael W. Hudson64e08142005-06-15 12:25:20 +0000665 Py_INCREF(&localtype);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000666 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
667 return;
Jim Fultond15dc062004-07-14 19:11:50 +0000668
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000669 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000670 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000671}