blob: f15cacb50eb66c8a08834f3613e9fa9d3d18e512 [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
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
126PyDoc_STRVAR(lock_exit_doc,
127"__exit__(type, value, tb)\n\
128\n\
129Releases the lock; then re-raises the exception if type is not None.");
130
131static PyObject *
132lock_exit(lockobject *self, PyObject *args)
133{
134 PyObject *type, *value, *tb, *result;
135 if (!PyArg_ParseTuple(args, "OOO:__exit__", &type, &value, &tb))
136 return NULL;
137 result = lock_PyThread_release_lock(self);
138 if (result != NULL && type != Py_None) {
139 Py_DECREF(result);
140 result = NULL;
141 Py_INCREF(type);
142 Py_INCREF(value);
143 Py_INCREF(tb);
144 PyErr_Restore(type, value, tb);
145 }
146 return result;
147}
148
Barry Warsawd0c10421996-12-17 00:05:22 +0000149static PyMethodDef lock_methods[] = {
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000150 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000151 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000152 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000153 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000154 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000155 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000156 {"release", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000157 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000158 {"locked_lock", (PyCFunction)lock_locked_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000159 METH_NOARGS, locked_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000160 {"locked", (PyCFunction)lock_locked_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000161 METH_NOARGS, locked_doc},
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000162 {"__context__", (PyCFunction)lock_context,
163 METH_NOARGS, PyDoc_STR("__context__() -> self.")},
164 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
165 METH_VARARGS, acquire_doc},
166 {"__exit__", (PyCFunction)lock_exit,
167 METH_VARARGS, lock_exit_doc},
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000168 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000169};
170
Barry Warsawd0c10421996-12-17 00:05:22 +0000171static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000172lock_getattr(lockobject *self, char *name)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000173{
Barry Warsawd0c10421996-12-17 00:05:22 +0000174 return Py_FindMethod(lock_methods, (PyObject *)self, name);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000175}
176
Barry Warsawd0c10421996-12-17 00:05:22 +0000177static PyTypeObject Locktype = {
178 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000179 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000180 "thread.lock", /*tp_name*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181 sizeof(lockobject), /*tp_size*/
182 0, /*tp_itemsize*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000183 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000184 (destructor)lock_dealloc, /*tp_dealloc*/
185 0, /*tp_print*/
186 (getattrfunc)lock_getattr, /*tp_getattr*/
187 0, /*tp_setattr*/
188 0, /*tp_compare*/
189 0, /*tp_repr*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000190};
191
Jim Fultond15dc062004-07-14 19:11:50 +0000192/* Thread-local objects */
193
194#include "structmember.h"
195
196typedef struct {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000197 PyObject_HEAD
198 PyObject *key;
199 PyObject *args;
200 PyObject *kw;
201 PyObject *dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000202} localobject;
203
204static PyTypeObject localtype;
205
206static PyObject *
207local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
208{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000209 localobject *self;
210 PyObject *tdict;
Jim Fultond15dc062004-07-14 19:11:50 +0000211
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000212 if (type->tp_init == PyBaseObject_Type.tp_init
213 && ((args && PyObject_IsTrue(args))
214 || (kw && PyObject_IsTrue(kw)))) {
215 PyErr_SetString(PyExc_TypeError,
216 "Initialization arguments are not supported");
217 return NULL;
218 }
Jim Fultond15dc062004-07-14 19:11:50 +0000219
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000220 self = (localobject *)type->tp_alloc(type, 0);
221 if (self == NULL)
222 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000223
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000224 Py_XINCREF(args);
225 self->args = args;
226 Py_XINCREF(kw);
227 self->kw = kw;
228 self->dict = NULL; /* making sure */
229 self->key = PyString_FromFormat("thread.local.%p", self);
230 if (self->key == NULL)
231 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000232
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000233 self->dict = PyDict_New();
234 if (self->dict == NULL)
235 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000236
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000237 tdict = PyThreadState_GetDict();
238 if (tdict == NULL) {
239 PyErr_SetString(PyExc_SystemError,
240 "Couldn't get thread-state dictionary");
241 goto err;
242 }
Jim Fultond15dc062004-07-14 19:11:50 +0000243
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000244 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
245 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000246
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000247 return (PyObject *)self;
248
249 err:
250 Py_DECREF(self);
251 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000252}
253
254static int
255local_traverse(localobject *self, visitproc visit, void *arg)
256{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000257 Py_VISIT(self->args);
258 Py_VISIT(self->kw);
259 Py_VISIT(self->dict);
Jim Fultond15dc062004-07-14 19:11:50 +0000260 return 0;
261}
262
263static int
264local_clear(localobject *self)
265{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000266 Py_CLEAR(self->key);
267 Py_CLEAR(self->args);
268 Py_CLEAR(self->kw);
269 Py_CLEAR(self->dict);
270 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000271}
272
273static void
274local_dealloc(localobject *self)
275{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000276 PyThreadState *tstate;
277 if (self->key
278 && (tstate = PyThreadState_Get())
279 && tstate->interp) {
280 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
281 tstate;
282 tstate = PyThreadState_Next(tstate))
283 if (tstate->dict &&
284 PyDict_GetItem(tstate->dict, self->key))
285 PyDict_DelItem(tstate->dict, self->key);
286 }
Jim Fultond15dc062004-07-14 19:11:50 +0000287
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000288 local_clear(self);
289 self->ob_type->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000290}
291
292static PyObject *
293_ldict(localobject *self)
294{
295 PyObject *tdict, *ldict;
296
297 tdict = PyThreadState_GetDict();
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000298 if (tdict == NULL) {
299 PyErr_SetString(PyExc_SystemError,
300 "Couldn't get thread-state dictionary");
301 return NULL;
302 }
Jim Fultond15dc062004-07-14 19:11:50 +0000303
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000304 ldict = PyDict_GetItem(tdict, self->key);
305 if (ldict == NULL) {
306 ldict = PyDict_New(); /* we own ldict */
Jim Fultond15dc062004-07-14 19:11:50 +0000307
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000308 if (ldict == NULL)
309 return NULL;
310 else {
311 int i = PyDict_SetItem(tdict, self->key, ldict);
Georg Brandlf3c4ad12006-03-08 12:24:33 +0000312 Py_DECREF(ldict); /* now ldict is borrowed */
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000313 if (i < 0)
314 return NULL;
315 }
Jim Fultond15dc062004-07-14 19:11:50 +0000316
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000317 Py_CLEAR(self->dict);
318 Py_INCREF(ldict);
319 self->dict = ldict; /* still borrowed */
Jim Fultond15dc062004-07-14 19:11:50 +0000320
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000321 if (self->ob_type->tp_init != PyBaseObject_Type.tp_init &&
322 self->ob_type->tp_init((PyObject*)self,
323 self->args, self->kw) < 0) {
324 /* we need to get rid of ldict from thread so
325 we create a new one the next time we do an attr
326 acces */
327 PyDict_DelItem(tdict, self->key);
328 return NULL;
329 }
330
331 }
332 else if (self->dict != ldict) {
333 Py_CLEAR(self->dict);
334 Py_INCREF(ldict);
335 self->dict = ldict;
336 }
Jim Fultond15dc062004-07-14 19:11:50 +0000337
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000338 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000339}
340
341static PyObject *
342local_getattro(localobject *self, PyObject *name)
343{
344 PyObject *ldict, *value;
345
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000346 ldict = _ldict(self);
347 if (ldict == NULL)
348 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000349
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000350 if (self->ob_type != &localtype)
351 /* use generic lookup for subtypes */
352 return PyObject_GenericGetAttr((PyObject *)self, name);
Jim Fultond15dc062004-07-14 19:11:50 +0000353
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000354 /* Optimization: just look in dict ourselves */
355 value = PyDict_GetItem(ldict, name);
356 if (value == NULL)
357 /* Fall back on generic to get __class__ and __dict__ */
358 return PyObject_GenericGetAttr((PyObject *)self, name);
Jim Fultond15dc062004-07-14 19:11:50 +0000359
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000360 Py_INCREF(value);
361 return value;
Jim Fultond15dc062004-07-14 19:11:50 +0000362}
363
364static int
365local_setattro(localobject *self, PyObject *name, PyObject *v)
366{
367 PyObject *ldict;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000368
369 ldict = _ldict(self);
370 if (ldict == NULL)
371 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000372
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000373 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000374}
375
376static PyObject *
377local_getdict(localobject *self, void *closure)
378{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000379 if (self->dict == NULL) {
380 PyErr_SetString(PyExc_AttributeError, "__dict__");
381 return NULL;
382 }
Jim Fultond15dc062004-07-14 19:11:50 +0000383
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000384 Py_INCREF(self->dict);
385 return self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000386}
387
388static PyGetSetDef local_getset[] = {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000389 {"__dict__", (getter)local_getdict, (setter)NULL,
390 "Local-data dictionary", NULL},
391 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000392};
393
394static PyTypeObject localtype = {
395 PyObject_HEAD_INIT(NULL)
396 /* ob_size */ 0,
397 /* tp_name */ "thread._local",
398 /* tp_basicsize */ sizeof(localobject),
399 /* tp_itemsize */ 0,
400 /* tp_dealloc */ (destructor)local_dealloc,
401 /* tp_print */ (printfunc)0,
402 /* tp_getattr */ (getattrfunc)0,
403 /* tp_setattr */ (setattrfunc)0,
404 /* tp_compare */ (cmpfunc)0,
405 /* tp_repr */ (reprfunc)0,
406 /* tp_as_number */ 0,
407 /* tp_as_sequence */ 0,
408 /* tp_as_mapping */ 0,
409 /* tp_hash */ (hashfunc)0,
410 /* tp_call */ (ternaryfunc)0,
411 /* tp_str */ (reprfunc)0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000412 /* tp_getattro */ (getattrofunc)local_getattro,
413 /* tp_setattro */ (setattrofunc)local_setattro,
414 /* tp_as_buffer */ 0,
415 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Jim Fultond15dc062004-07-14 19:11:50 +0000416 /* tp_doc */ "Thread-local data",
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000417 /* tp_traverse */ (traverseproc)local_traverse,
418 /* tp_clear */ (inquiry)local_clear,
419 /* tp_richcompare */ (richcmpfunc)0,
420 /* tp_weaklistoffset */ (long)0,
421 /* tp_iter */ (getiterfunc)0,
422 /* tp_iternext */ (iternextfunc)0,
423 /* tp_methods */ 0,
424 /* tp_members */ 0,
425 /* tp_getset */ local_getset,
426 /* tp_base */ 0,
427 /* tp_dict */ 0, /* internal use */
428 /* tp_descr_get */ (descrgetfunc)0,
429 /* tp_descr_set */ (descrsetfunc)0,
430 /* tp_dictoffset */ offsetof(localobject, dict),
431 /* tp_init */ (initproc)0,
432 /* tp_alloc */ (allocfunc)0,
433 /* tp_new */ (newfunc)local_new,
Jim Fultond15dc062004-07-14 19:11:50 +0000434 /* tp_free */ 0, /* Low-level free-mem routine */
435 /* tp_is_gc */ (inquiry)0, /* For PyObject_IS_GC */
436};
437
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000438
439/* Module functions */
440
Guido van Rossuma027efa1997-05-05 20:56:21 +0000441struct bootstate {
442 PyInterpreterState *interp;
443 PyObject *func;
444 PyObject *args;
445 PyObject *keyw;
446};
447
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000448static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000449t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000450{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000451 struct bootstate *boot = (struct bootstate *) boot_raw;
Michael W. Hudson188d4362005-06-20 16:52:57 +0000452 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000453 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000454
Michael W. Hudson188d4362005-06-20 16:52:57 +0000455 tstate = PyThreadState_New(boot->interp);
456
457 PyEval_AcquireThread(tstate);
Guido van Rossuma027efa1997-05-05 20:56:21 +0000458 res = PyEval_CallObjectWithKeywords(
459 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000460 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000461 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000462 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000463 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000464 PyObject *file;
465 PySys_WriteStderr(
466 "Unhandled exception in thread started by ");
467 file = PySys_GetObject("stderr");
468 if (file)
469 PyFile_WriteObject(boot->func, file, 0);
470 else
471 PyObject_Print(boot->func, stderr, 0);
472 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000473 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000474 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000475 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000476 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000477 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000478 Py_DECREF(boot->func);
479 Py_DECREF(boot->args);
480 Py_XDECREF(boot->keyw);
481 PyMem_DEL(boot_raw);
Michael W. Hudson188d4362005-06-20 16:52:57 +0000482 PyThreadState_Clear(tstate);
483 PyThreadState_DeleteCurrent();
Guido van Rossumbcc20741998-08-04 22:53:56 +0000484 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000485}
486
Barry Warsawd0c10421996-12-17 00:05:22 +0000487static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000488thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000489{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000490 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000491 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000492 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000493
Guido van Rossum43713e52000-02-29 13:59:29 +0000494 if (!PyArg_ParseTuple(fargs, "OO|O:start_new_thread", &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000495 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000496 if (!PyCallable_Check(func)) {
497 PyErr_SetString(PyExc_TypeError,
498 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000499 return NULL;
500 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000501 if (!PyTuple_Check(args)) {
502 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000503 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000504 return NULL;
505 }
506 if (keyw != NULL && !PyDict_Check(keyw)) {
507 PyErr_SetString(PyExc_TypeError,
508 "optional 3rd arg must be a dictionary");
509 return NULL;
510 }
511 boot = PyMem_NEW(struct bootstate, 1);
512 if (boot == NULL)
513 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000514 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000515 boot->func = func;
516 boot->args = args;
517 boot->keyw = keyw;
518 Py_INCREF(func);
519 Py_INCREF(args);
520 Py_XINCREF(keyw);
521 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000522 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
523 if (ident == -1) {
Guido van Rossum54c273c2005-02-20 03:02:16 +0000524 PyErr_SetString(ThreadError, "can't start new thread");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000525 Py_DECREF(func);
526 Py_DECREF(args);
527 Py_XDECREF(keyw);
528 PyMem_DEL(boot);
529 return NULL;
530 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000531 return PyInt_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000532}
533
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000534PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000535"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000536(start_new() is an obsolete synonym)\n\
537\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000538Start a new thread and return its identifier. The thread will call the\n\
539function with positional arguments from the tuple args and keyword arguments\n\
540taken from the optional dictionary kwargs. The thread exits when the\n\
541function returns; the return value is ignored. The thread will also exit\n\
542when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000543printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000544
Barry Warsawd0c10421996-12-17 00:05:22 +0000545static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000546thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000547{
Barry Warsawd0c10421996-12-17 00:05:22 +0000548 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000549 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000550}
551
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000552PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000553"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000554(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000555\n\
556This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000557thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000558
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000559static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000560thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000561{
562 PyErr_SetInterrupt();
563 Py_INCREF(Py_None);
564 return Py_None;
565}
566
567PyDoc_STRVAR(interrupt_doc,
568"interrupt_main()\n\
569\n\
570Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000571A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000572);
573
Guido van Rossumb6775db1994-08-01 11:34:53 +0000574#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000575static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000576thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000577{
578 int sts;
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000579 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000580 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000581 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000582 for (;;) { } /* Should not be reached */
583}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000584#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000585
Barry Warsawd0c10421996-12-17 00:05:22 +0000586static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000587thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000588{
Barry Warsawd0c10421996-12-17 00:05:22 +0000589 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000590}
591
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000592PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000593"allocate_lock() -> lock object\n\
594(allocate() is an obsolete synonym)\n\
595\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000596Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000597
Barry Warsawd0c10421996-12-17 00:05:22 +0000598static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000599thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000600{
601 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000602 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000603 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000604 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000605 return NULL;
606 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000607 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000608}
609
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000610PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000611"get_ident() -> integer\n\
612\n\
613Return a non-zero integer that uniquely identifies the current thread\n\
614amongst other threads that exist simultaneously.\n\
615This may be used to identify per-thread resources.\n\
616Even though on some platforms threads identities may appear to be\n\
617allocated consecutive numbers starting at 1, this behavior should not\n\
618be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000619A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000620
Barry Warsawd0c10421996-12-17 00:05:22 +0000621static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000622 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
623 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000624 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000625 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
626 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000627 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000628 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000629 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000630 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000631 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000632 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000633 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000634 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000635 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000636 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000637 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000638 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000639 METH_NOARGS, get_ident_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000640#ifndef NO_EXIT_PROG
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000641 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
642 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000643#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000644 {NULL, NULL} /* sentinel */
645};
646
647
648/* Initialization function */
649
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000650PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000651"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000652The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000653
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000654PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000655"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000656call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000657\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000658acquire() -- lock the lock, possibly blocking until it can be obtained\n\
659release() -- unlock of the lock\n\
660locked() -- test whether the lock is currently locked\n\
661\n\
662A lock is not owned by the thread that locked it; another thread may\n\
663unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000664will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000665
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000666PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000667initthread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000668{
Barry Warsawd0c10421996-12-17 00:05:22 +0000669 PyObject *m, *d;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000670
671 /* Initialize types: */
672 if (PyType_Ready(&localtype) < 0)
673 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000674
675 /* Create the module and add the functions */
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000676 m = Py_InitModule3("thread", thread_methods, thread_doc);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000677 if (m == NULL)
678 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000679
680 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000681 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000682 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000683 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000684 Locktype.tp_doc = lock_doc;
685 Py_INCREF(&Locktype);
686 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000687
Michael W. Hudson64e08142005-06-15 12:25:20 +0000688 Py_INCREF(&localtype);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000689 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
690 return;
Jim Fultond15dc062004-07-14 19:11:50 +0000691
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000692 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000693 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000694}