blob: a87ddb344d9bf6ad3eabac6105613b403c3d038e [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
Guido van Rossum1984f1e1992-08-04 12:41:02 +000025static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000026lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000027{
Neal Norwitz837ce932006-10-28 21:15:30 +000028 assert(self->lock_lock);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000029 /* Unlock the lock so it's safe to free it */
Guido van Rossum65d5b571998-12-21 19:32:43 +000030 PyThread_acquire_lock(self->lock_lock, 0);
31 PyThread_release_lock(self->lock_lock);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000032
Guido van Rossum65d5b571998-12-21 19:32:43 +000033 PyThread_free_lock(self->lock_lock);
Guido van Rossumb18618d2000-05-03 23:44:39 +000034 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000035}
36
Barry Warsawd0c10421996-12-17 00:05:22 +000037static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000038lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000039{
Neal Norwitzba3a16c2002-03-31 15:27:00 +000040 int i = 1;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000041
Neal Norwitzba3a16c2002-03-31 15:27:00 +000042 if (!PyArg_ParseTuple(args, "|i:acquire", &i))
43 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000044
Barry Warsawd0c10421996-12-17 00:05:22 +000045 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +000046 i = PyThread_acquire_lock(self->lock_lock, i);
Barry Warsawd0c10421996-12-17 00:05:22 +000047 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +000048
Andrew M. Kuchlinga43ece92005-06-02 17:07:11 +000049 return PyBool_FromLong((long)i);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000050}
51
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000052PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000053"acquire([wait]) -> None or bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000054(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000055\n\
56Lock the lock. Without argument, this blocks if the lock is already\n\
57locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000058the lock, and return None once the lock is acquired.\n\
59With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000060and the return value reflects whether the lock is acquired.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000061The blocking operation is not interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000062
Barry Warsawd0c10421996-12-17 00:05:22 +000063static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000064lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000065{
Guido van Rossum1984f1e1992-08-04 12:41:02 +000066 /* Sanity check: the lock must be locked */
Guido van Rossum65d5b571998-12-21 19:32:43 +000067 if (PyThread_acquire_lock(self->lock_lock, 0)) {
68 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000069 PyErr_SetString(ThreadError, "release unlocked lock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +000070 return NULL;
71 }
72
Guido van Rossum65d5b571998-12-21 19:32:43 +000073 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000074 Py_INCREF(Py_None);
75 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000076}
77
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000078PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +000079"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000080(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000081\n\
82Release the lock, allowing another thread that is blocked waiting for\n\
83the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000084but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000085
Barry Warsawd0c10421996-12-17 00:05:22 +000086static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000087lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000088{
Guido van Rossum65d5b571998-12-21 19:32:43 +000089 if (PyThread_acquire_lock(self->lock_lock, 0)) {
90 PyThread_release_lock(self->lock_lock);
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000091 return PyBool_FromLong(0L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000092 }
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000093 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000094}
95
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000096PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000097"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000098(locked_lock() is an obsolete synonym)\n\
99\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000100Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000101
Barry Warsawd0c10421996-12-17 00:05:22 +0000102static PyMethodDef lock_methods[] = {
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000103 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000104 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000105 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000106 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000107 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000108 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000109 {"release", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000110 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000111 {"locked_lock", (PyCFunction)lock_locked_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000112 METH_NOARGS, locked_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000113 {"locked", (PyCFunction)lock_locked_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000114 METH_NOARGS, locked_doc},
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000115 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
116 METH_VARARGS, acquire_doc},
Guido van Rossumf6694362006-03-10 02:28:35 +0000117 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
118 METH_VARARGS, release_doc},
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000119 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000120};
121
Barry Warsawd0c10421996-12-17 00:05:22 +0000122static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000123lock_getattr(lockobject *self, char *name)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000124{
Barry Warsawd0c10421996-12-17 00:05:22 +0000125 return Py_FindMethod(lock_methods, (PyObject *)self, name);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000126}
127
Barry Warsawd0c10421996-12-17 00:05:22 +0000128static PyTypeObject Locktype = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000129 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Guido van Rossum14648392001-12-08 18:02:58 +0000130 "thread.lock", /*tp_name*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000131 sizeof(lockobject), /*tp_size*/
132 0, /*tp_itemsize*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000133 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000134 (destructor)lock_dealloc, /*tp_dealloc*/
135 0, /*tp_print*/
136 (getattrfunc)lock_getattr, /*tp_getattr*/
137 0, /*tp_setattr*/
138 0, /*tp_compare*/
139 0, /*tp_repr*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000140};
141
Anthony Baxter5576b542006-04-12 04:08:46 +0000142static lockobject *
143newlockobject(void)
144{
145 lockobject *self;
146 self = PyObject_New(lockobject, &Locktype);
147 if (self == NULL)
148 return NULL;
149 self->lock_lock = PyThread_allocate_lock();
150 if (self->lock_lock == NULL) {
151 PyObject_Del(self);
152 self = NULL;
153 PyErr_SetString(ThreadError, "can't allocate lock");
154 }
155 return self;
156}
157
Jim Fultond15dc062004-07-14 19:11:50 +0000158/* Thread-local objects */
159
160#include "structmember.h"
161
162typedef struct {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000163 PyObject_HEAD
164 PyObject *key;
165 PyObject *args;
166 PyObject *kw;
167 PyObject *dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000168} localobject;
169
Jim Fultond15dc062004-07-14 19:11:50 +0000170static 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 */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000193 self->key = PyString_FromFormat("thread.local.%p", self);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000194 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);
Christian Heimese93237d2007-12-19 02:37:44 +0000253 Py_TYPE(self)->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);
Georg Brandlf3c4ad12006-03-08 12:24:33 +0000276 Py_DECREF(ldict); /* now ldict is borrowed */
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000277 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
Christian Heimese93237d2007-12-19 02:37:44 +0000285 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
286 Py_TYPE(self)->tp_init((PyObject*)self,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000287 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 }
Amaury Forgeot d'Arc1f40c8a2008-06-30 22:42:40 +0000296
297 /* The call to tp_init above may have caused another thread to run.
298 Install our ldict again. */
299 if (self->dict != ldict) {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000300 Py_CLEAR(self->dict);
301 Py_INCREF(ldict);
302 self->dict = ldict;
303 }
Jim Fultond15dc062004-07-14 19:11:50 +0000304
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000305 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000306}
307
Jim Fultond15dc062004-07-14 19:11:50 +0000308static int
309local_setattro(localobject *self, PyObject *name, PyObject *v)
310{
311 PyObject *ldict;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000312
313 ldict = _ldict(self);
314 if (ldict == NULL)
315 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000316
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000317 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000318}
319
320static PyObject *
321local_getdict(localobject *self, void *closure)
322{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000323 if (self->dict == NULL) {
324 PyErr_SetString(PyExc_AttributeError, "__dict__");
325 return NULL;
326 }
Jim Fultond15dc062004-07-14 19:11:50 +0000327
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000328 Py_INCREF(self->dict);
329 return self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000330}
331
332static PyGetSetDef local_getset[] = {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000333 {"__dict__", (getter)local_getdict, (setter)NULL,
334 "Local-data dictionary", NULL},
335 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000336};
337
Anthony Baxter5576b542006-04-12 04:08:46 +0000338static PyObject *local_getattro(localobject *, PyObject *);
339
Jim Fultond15dc062004-07-14 19:11:50 +0000340static PyTypeObject localtype = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000341 PyVarObject_HEAD_INIT(NULL, 0)
Jim Fultond15dc062004-07-14 19:11:50 +0000342 /* tp_name */ "thread._local",
343 /* tp_basicsize */ sizeof(localobject),
344 /* tp_itemsize */ 0,
345 /* tp_dealloc */ (destructor)local_dealloc,
Georg Brandld37ac692006-03-30 11:58:57 +0000346 /* tp_print */ 0,
347 /* tp_getattr */ 0,
348 /* tp_setattr */ 0,
349 /* tp_compare */ 0,
350 /* tp_repr */ 0,
Jim Fultond15dc062004-07-14 19:11:50 +0000351 /* tp_as_number */ 0,
352 /* tp_as_sequence */ 0,
353 /* tp_as_mapping */ 0,
Georg Brandld37ac692006-03-30 11:58:57 +0000354 /* tp_hash */ 0,
355 /* tp_call */ 0,
356 /* tp_str */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000357 /* tp_getattro */ (getattrofunc)local_getattro,
358 /* tp_setattro */ (setattrofunc)local_setattro,
359 /* tp_as_buffer */ 0,
360 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Jim Fultond15dc062004-07-14 19:11:50 +0000361 /* tp_doc */ "Thread-local data",
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000362 /* tp_traverse */ (traverseproc)local_traverse,
363 /* tp_clear */ (inquiry)local_clear,
Georg Brandld37ac692006-03-30 11:58:57 +0000364 /* tp_richcompare */ 0,
365 /* tp_weaklistoffset */ 0,
366 /* tp_iter */ 0,
367 /* tp_iternext */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000368 /* tp_methods */ 0,
369 /* tp_members */ 0,
370 /* tp_getset */ local_getset,
371 /* tp_base */ 0,
372 /* tp_dict */ 0, /* internal use */
Georg Brandld37ac692006-03-30 11:58:57 +0000373 /* tp_descr_get */ 0,
374 /* tp_descr_set */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000375 /* tp_dictoffset */ offsetof(localobject, dict),
Georg Brandld37ac692006-03-30 11:58:57 +0000376 /* tp_init */ 0,
377 /* tp_alloc */ 0,
378 /* tp_new */ local_new,
Jim Fultond15dc062004-07-14 19:11:50 +0000379 /* tp_free */ 0, /* Low-level free-mem routine */
Georg Brandld37ac692006-03-30 11:58:57 +0000380 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000381};
382
Anthony Baxter5576b542006-04-12 04:08:46 +0000383static PyObject *
384local_getattro(localobject *self, PyObject *name)
385{
386 PyObject *ldict, *value;
387
388 ldict = _ldict(self);
389 if (ldict == NULL)
390 return NULL;
391
Christian Heimese93237d2007-12-19 02:37:44 +0000392 if (Py_TYPE(self) != &localtype)
Anthony Baxter5576b542006-04-12 04:08:46 +0000393 /* use generic lookup for subtypes */
394 return PyObject_GenericGetAttr((PyObject *)self, name);
395
396 /* Optimization: just look in dict ourselves */
397 value = PyDict_GetItem(ldict, name);
398 if (value == NULL)
399 /* Fall back on generic to get __class__ and __dict__ */
400 return PyObject_GenericGetAttr((PyObject *)self, name);
401
402 Py_INCREF(value);
403 return value;
404}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000405
406/* Module functions */
407
Guido van Rossuma027efa1997-05-05 20:56:21 +0000408struct bootstate {
409 PyInterpreterState *interp;
410 PyObject *func;
411 PyObject *args;
412 PyObject *keyw;
413};
414
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000415static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000416t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000417{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000418 struct bootstate *boot = (struct bootstate *) boot_raw;
Michael W. Hudson188d4362005-06-20 16:52:57 +0000419 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000420 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000421
Michael W. Hudson188d4362005-06-20 16:52:57 +0000422 tstate = PyThreadState_New(boot->interp);
423
424 PyEval_AcquireThread(tstate);
Guido van Rossuma027efa1997-05-05 20:56:21 +0000425 res = PyEval_CallObjectWithKeywords(
426 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000427 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000428 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000429 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000430 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000431 PyObject *file;
432 PySys_WriteStderr(
433 "Unhandled exception in thread started by ");
434 file = PySys_GetObject("stderr");
435 if (file)
436 PyFile_WriteObject(boot->func, file, 0);
437 else
438 PyObject_Print(boot->func, stderr, 0);
439 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000440 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000441 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000442 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000443 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000444 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000445 Py_DECREF(boot->func);
446 Py_DECREF(boot->args);
447 Py_XDECREF(boot->keyw);
448 PyMem_DEL(boot_raw);
Michael W. Hudson188d4362005-06-20 16:52:57 +0000449 PyThreadState_Clear(tstate);
450 PyThreadState_DeleteCurrent();
Guido van Rossumbcc20741998-08-04 22:53:56 +0000451 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000452}
453
Barry Warsawd0c10421996-12-17 00:05:22 +0000454static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000455thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000456{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000457 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000458 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000459 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000460
Georg Brandl96a8c392006-05-29 21:04:52 +0000461 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
462 &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000463 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000464 if (!PyCallable_Check(func)) {
465 PyErr_SetString(PyExc_TypeError,
466 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000467 return NULL;
468 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000469 if (!PyTuple_Check(args)) {
470 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000471 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000472 return NULL;
473 }
474 if (keyw != NULL && !PyDict_Check(keyw)) {
475 PyErr_SetString(PyExc_TypeError,
476 "optional 3rd arg must be a dictionary");
477 return NULL;
478 }
479 boot = PyMem_NEW(struct bootstate, 1);
480 if (boot == NULL)
481 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000482 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000483 boot->func = func;
484 boot->args = args;
485 boot->keyw = keyw;
486 Py_INCREF(func);
487 Py_INCREF(args);
488 Py_XINCREF(keyw);
489 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000490 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
491 if (ident == -1) {
Guido van Rossum54c273c2005-02-20 03:02:16 +0000492 PyErr_SetString(ThreadError, "can't start new thread");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000493 Py_DECREF(func);
494 Py_DECREF(args);
495 Py_XDECREF(keyw);
496 PyMem_DEL(boot);
497 return NULL;
498 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000499 return PyInt_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000500}
501
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000502PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000503"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000504(start_new() is an obsolete synonym)\n\
505\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000506Start a new thread and return its identifier. The thread will call the\n\
507function with positional arguments from the tuple args and keyword arguments\n\
508taken from the optional dictionary kwargs. The thread exits when the\n\
509function returns; the return value is ignored. The thread will also exit\n\
510when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000511printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000512
Barry Warsawd0c10421996-12-17 00:05:22 +0000513static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000514thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000515{
Barry Warsawd0c10421996-12-17 00:05:22 +0000516 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000517 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000518}
519
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000520PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000521"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000522(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000523\n\
524This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000525thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000526
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000527static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000528thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000529{
530 PyErr_SetInterrupt();
531 Py_INCREF(Py_None);
532 return Py_None;
533}
534
535PyDoc_STRVAR(interrupt_doc,
536"interrupt_main()\n\
537\n\
538Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000539A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000540);
541
Guido van Rossumb6775db1994-08-01 11:34:53 +0000542#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000543static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000544thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000545{
546 int sts;
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000547 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000548 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000549 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000550 for (;;) { } /* Should not be reached */
551}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000552#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000553
Anthony Baxter5576b542006-04-12 04:08:46 +0000554static lockobject *newlockobject(void);
555
Barry Warsawd0c10421996-12-17 00:05:22 +0000556static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000557thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000558{
Barry Warsawd0c10421996-12-17 00:05:22 +0000559 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000560}
561
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000562PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000563"allocate_lock() -> lock object\n\
564(allocate() is an obsolete synonym)\n\
565\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000566Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000567
Barry Warsawd0c10421996-12-17 00:05:22 +0000568static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000569thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000570{
571 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000572 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000573 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000574 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000575 return NULL;
576 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000577 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000578}
579
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000580PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000581"get_ident() -> integer\n\
582\n\
583Return a non-zero integer that uniquely identifies the current thread\n\
584amongst other threads that exist simultaneously.\n\
585This may be used to identify per-thread resources.\n\
586Even though on some platforms threads identities may appear to be\n\
587allocated consecutive numbers starting at 1, this behavior should not\n\
588be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000589A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000590
Andrew MacIntyre92913322006-06-13 15:04:24 +0000591static PyObject *
592thread_stack_size(PyObject *self, PyObject *args)
593{
594 size_t old_size;
595 Py_ssize_t new_size = 0;
Andrew MacIntyre92913322006-06-13 15:04:24 +0000596 int rc;
597
598 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
599 return NULL;
600
601 if (new_size < 0) {
602 PyErr_SetString(PyExc_ValueError,
603 "size must be 0 or a positive value");
604 return NULL;
605 }
606
607 old_size = PyThread_get_stacksize();
608
609 rc = PyThread_set_stacksize((size_t) new_size);
610 if (rc == -1) {
611 PyErr_Format(PyExc_ValueError,
612 "size not valid: %zd bytes",
613 new_size);
614 return NULL;
615 }
616 if (rc == -2) {
617 PyErr_SetString(ThreadError,
618 "setting stack size not supported");
619 return NULL;
620 }
621
622 return PyInt_FromSsize_t((Py_ssize_t) old_size);
623}
624
625PyDoc_STRVAR(stack_size_doc,
626"stack_size([size]) -> size\n\
627\n\
628Return the thread stack size used when creating new threads. The\n\
629optional size argument specifies the stack size (in bytes) to be used\n\
630for subsequently created threads, and must be 0 (use platform or\n\
631configured default) or a positive integer value of at least 32,768 (32k).\n\
632If changing the thread stack size is unsupported, a ThreadError\n\
633exception is raised. If the specified size is invalid, a ValueError\n\
634exception is raised, and the stack size is unmodified. 32k bytes\n\
635 currently the minimum supported stack size value to guarantee\n\
636sufficient stack space for the interpreter itself.\n\
637\n\
638Note that some platforms may have particular restrictions on values for\n\
639the stack size, such as requiring a minimum stack size larger than 32kB or\n\
640requiring allocation in multiples of the system memory page size\n\
641- platform documentation should be referred to for more information\n\
642(4kB pages are common; using multiples of 4096 for the stack size is\n\
643the suggested approach in the absence of more specific information).");
644
Barry Warsawd0c10421996-12-17 00:05:22 +0000645static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000646 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
647 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000648 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000649 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
650 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000651 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000652 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000653 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000654 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000655 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000656 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000657 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000658 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000659 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000660 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000661 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000662 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000663 METH_NOARGS, get_ident_doc},
Andrew MacIntyre92913322006-06-13 15:04:24 +0000664 {"stack_size", (PyCFunction)thread_stack_size,
665 METH_VARARGS,
666 stack_size_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000667#ifndef NO_EXIT_PROG
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000668 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
669 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000670#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000671 {NULL, NULL} /* sentinel */
672};
673
674
675/* Initialization function */
676
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000677PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000678"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000679The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000680
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000681PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000682"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000683call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000684\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000685acquire() -- lock the lock, possibly blocking until it can be obtained\n\
686release() -- unlock of the lock\n\
687locked() -- test whether the lock is currently locked\n\
688\n\
689A lock is not owned by the thread that locked it; another thread may\n\
690unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000691will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000692
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000693PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000694initthread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000695{
Barry Warsawd0c10421996-12-17 00:05:22 +0000696 PyObject *m, *d;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000697
698 /* Initialize types: */
699 if (PyType_Ready(&localtype) < 0)
700 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000701
702 /* Create the module and add the functions */
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000703 m = Py_InitModule3("thread", thread_methods, thread_doc);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000704 if (m == NULL)
705 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000706
707 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000708 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000709 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000710 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000711 Locktype.tp_doc = lock_doc;
712 Py_INCREF(&Locktype);
713 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000714
Michael W. Hudson64e08142005-06-15 12:25:20 +0000715 Py_INCREF(&localtype);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000716 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
717 return;
Jim Fultond15dc062004-07-14 19:11:50 +0000718
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000719 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000720 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000721}