blob: 1f91197e4bafb1c6f4638b006363c4eb696a352b [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{
Victor Stinner27bf15e2010-03-21 13:13:07 +000028 if (self->lock_lock != NULL) {
29 /* Unlock the lock so it's safe to free it */
30 PyThread_acquire_lock(self->lock_lock, 0);
31 PyThread_release_lock(self->lock_lock);
32
33 PyThread_free_lock(self->lock_lock);
34 }
Guido van Rossumb18618d2000-05-03 23:44:39 +000035 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000036}
37
Barry Warsawd0c10421996-12-17 00:05:22 +000038static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000039lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000040{
Neal Norwitzba3a16c2002-03-31 15:27:00 +000041 int i = 1;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000042
Neal Norwitzba3a16c2002-03-31 15:27:00 +000043 if (!PyArg_ParseTuple(args, "|i:acquire", &i))
44 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000045
Barry Warsawd0c10421996-12-17 00:05:22 +000046 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +000047 i = PyThread_acquire_lock(self->lock_lock, i);
Barry Warsawd0c10421996-12-17 00:05:22 +000048 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +000049
Andrew M. Kuchlinga43ece92005-06-02 17:07:11 +000050 return PyBool_FromLong((long)i);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000051}
52
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000053PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000054"acquire([wait]) -> None or bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000055(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000056\n\
57Lock the lock. Without argument, this blocks if the lock is already\n\
58locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000059the lock, and return None once the lock is acquired.\n\
60With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000061and the return value reflects whether the lock is acquired.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000062The blocking operation is not interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000063
Barry Warsawd0c10421996-12-17 00:05:22 +000064static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000065lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000066{
Guido van Rossum1984f1e1992-08-04 12:41:02 +000067 /* Sanity check: the lock must be locked */
Guido van Rossum65d5b571998-12-21 19:32:43 +000068 if (PyThread_acquire_lock(self->lock_lock, 0)) {
69 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000070 PyErr_SetString(ThreadError, "release unlocked lock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +000071 return NULL;
72 }
73
Guido van Rossum65d5b571998-12-21 19:32:43 +000074 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000075 Py_INCREF(Py_None);
76 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000077}
78
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000079PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +000080"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000081(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000082\n\
83Release the lock, allowing another thread that is blocked waiting for\n\
84the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000085but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000086
Barry Warsawd0c10421996-12-17 00:05:22 +000087static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000088lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000089{
Guido van Rossum65d5b571998-12-21 19:32:43 +000090 if (PyThread_acquire_lock(self->lock_lock, 0)) {
91 PyThread_release_lock(self->lock_lock);
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000092 return PyBool_FromLong(0L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000093 }
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000094 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000095}
96
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000097PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000098"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000099(locked_lock() is an obsolete synonym)\n\
100\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000101Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000102
Barry Warsawd0c10421996-12-17 00:05:22 +0000103static PyMethodDef lock_methods[] = {
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000104 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000105 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000106 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000107 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000108 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000109 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000110 {"release", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000111 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000112 {"locked_lock", (PyCFunction)lock_locked_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000113 METH_NOARGS, locked_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000114 {"locked", (PyCFunction)lock_locked_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000115 METH_NOARGS, locked_doc},
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000116 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
117 METH_VARARGS, acquire_doc},
Guido van Rossumf6694362006-03-10 02:28:35 +0000118 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
119 METH_VARARGS, release_doc},
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000120 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000121};
122
Barry Warsawd0c10421996-12-17 00:05:22 +0000123static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000124lock_getattr(lockobject *self, char *name)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000125{
Barry Warsawd0c10421996-12-17 00:05:22 +0000126 return Py_FindMethod(lock_methods, (PyObject *)self, name);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000127}
128
Barry Warsawd0c10421996-12-17 00:05:22 +0000129static PyTypeObject Locktype = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000130 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Guido van Rossum14648392001-12-08 18:02:58 +0000131 "thread.lock", /*tp_name*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000132 sizeof(lockobject), /*tp_size*/
133 0, /*tp_itemsize*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000134 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000135 (destructor)lock_dealloc, /*tp_dealloc*/
136 0, /*tp_print*/
137 (getattrfunc)lock_getattr, /*tp_getattr*/
138 0, /*tp_setattr*/
139 0, /*tp_compare*/
140 0, /*tp_repr*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000141};
142
Anthony Baxter5576b542006-04-12 04:08:46 +0000143static lockobject *
144newlockobject(void)
145{
146 lockobject *self;
147 self = PyObject_New(lockobject, &Locktype);
148 if (self == NULL)
149 return NULL;
150 self->lock_lock = PyThread_allocate_lock();
151 if (self->lock_lock == NULL) {
Victor Stinner27bf15e2010-03-21 13:13:07 +0000152 Py_DECREF(self);
Anthony Baxter5576b542006-04-12 04:08:46 +0000153 PyErr_SetString(ThreadError, "can't allocate lock");
Victor Stinner27bf15e2010-03-21 13:13:07 +0000154 return NULL;
Anthony Baxter5576b542006-04-12 04:08:46 +0000155 }
156 return self;
157}
158
Jim Fultond15dc062004-07-14 19:11:50 +0000159/* Thread-local objects */
160
161#include "structmember.h"
162
163typedef struct {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000164 PyObject_HEAD
165 PyObject *key;
166 PyObject *args;
167 PyObject *kw;
168 PyObject *dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000169} localobject;
170
Jim Fultond15dc062004-07-14 19:11:50 +0000171static PyObject *
172local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
173{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000174 localobject *self;
175 PyObject *tdict;
Jim Fultond15dc062004-07-14 19:11:50 +0000176
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000177 if (type->tp_init == PyBaseObject_Type.tp_init
178 && ((args && PyObject_IsTrue(args))
179 || (kw && PyObject_IsTrue(kw)))) {
180 PyErr_SetString(PyExc_TypeError,
181 "Initialization arguments are not supported");
182 return NULL;
183 }
Jim Fultond15dc062004-07-14 19:11:50 +0000184
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000185 self = (localobject *)type->tp_alloc(type, 0);
186 if (self == NULL)
187 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000188
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000189 Py_XINCREF(args);
190 self->args = args;
191 Py_XINCREF(kw);
192 self->kw = kw;
193 self->dict = NULL; /* making sure */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000194 self->key = PyString_FromFormat("thread.local.%p", self);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000195 if (self->key == NULL)
196 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000197
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000198 self->dict = PyDict_New();
199 if (self->dict == NULL)
200 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000201
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000202 tdict = PyThreadState_GetDict();
203 if (tdict == NULL) {
204 PyErr_SetString(PyExc_SystemError,
205 "Couldn't get thread-state dictionary");
206 goto err;
207 }
Jim Fultond15dc062004-07-14 19:11:50 +0000208
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000209 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
210 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000211
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000212 return (PyObject *)self;
213
214 err:
215 Py_DECREF(self);
216 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000217}
218
219static int
220local_traverse(localobject *self, visitproc visit, void *arg)
221{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000222 Py_VISIT(self->args);
223 Py_VISIT(self->kw);
224 Py_VISIT(self->dict);
Jim Fultond15dc062004-07-14 19:11:50 +0000225 return 0;
226}
227
228static int
229local_clear(localobject *self)
230{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000231 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
Philip Jenvey87b4e722009-09-29 04:41:54 +0000252 Py_XDECREF(self->key);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000253 local_clear(self);
Christian Heimese93237d2007-12-19 02:37:44 +0000254 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000255}
256
257static PyObject *
258_ldict(localobject *self)
259{
260 PyObject *tdict, *ldict;
261
262 tdict = PyThreadState_GetDict();
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000263 if (tdict == NULL) {
264 PyErr_SetString(PyExc_SystemError,
265 "Couldn't get thread-state dictionary");
266 return NULL;
267 }
Jim Fultond15dc062004-07-14 19:11:50 +0000268
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000269 ldict = PyDict_GetItem(tdict, self->key);
270 if (ldict == NULL) {
271 ldict = PyDict_New(); /* we own ldict */
Jim Fultond15dc062004-07-14 19:11:50 +0000272
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000273 if (ldict == NULL)
274 return NULL;
275 else {
276 int i = PyDict_SetItem(tdict, self->key, ldict);
Georg Brandlf3c4ad12006-03-08 12:24:33 +0000277 Py_DECREF(ldict); /* now ldict is borrowed */
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000278 if (i < 0)
279 return NULL;
280 }
Jim Fultond15dc062004-07-14 19:11:50 +0000281
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000282 Py_CLEAR(self->dict);
283 Py_INCREF(ldict);
284 self->dict = ldict; /* still borrowed */
Jim Fultond15dc062004-07-14 19:11:50 +0000285
Christian Heimese93237d2007-12-19 02:37:44 +0000286 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
287 Py_TYPE(self)->tp_init((PyObject*)self,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000288 self->args, self->kw) < 0) {
289 /* we need to get rid of ldict from thread so
290 we create a new one the next time we do an attr
291 acces */
292 PyDict_DelItem(tdict, self->key);
293 return NULL;
294 }
295
296 }
Amaury Forgeot d'Arc1f40c8a2008-06-30 22:42:40 +0000297
298 /* The call to tp_init above may have caused another thread to run.
299 Install our ldict again. */
300 if (self->dict != ldict) {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000301 Py_CLEAR(self->dict);
302 Py_INCREF(ldict);
303 self->dict = ldict;
304 }
Jim Fultond15dc062004-07-14 19:11:50 +0000305
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000306 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000307}
308
Jim Fultond15dc062004-07-14 19:11:50 +0000309static int
310local_setattro(localobject *self, PyObject *name, PyObject *v)
311{
312 PyObject *ldict;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000313
314 ldict = _ldict(self);
315 if (ldict == NULL)
316 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000317
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000318 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000319}
320
321static PyObject *
322local_getdict(localobject *self, void *closure)
323{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000324 if (self->dict == NULL) {
325 PyErr_SetString(PyExc_AttributeError, "__dict__");
326 return NULL;
327 }
Jim Fultond15dc062004-07-14 19:11:50 +0000328
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000329 Py_INCREF(self->dict);
330 return self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000331}
332
333static PyGetSetDef local_getset[] = {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000334 {"__dict__", (getter)local_getdict, (setter)NULL,
335 "Local-data dictionary", NULL},
336 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000337};
338
Anthony Baxter5576b542006-04-12 04:08:46 +0000339static PyObject *local_getattro(localobject *, PyObject *);
340
Jim Fultond15dc062004-07-14 19:11:50 +0000341static PyTypeObject localtype = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000342 PyVarObject_HEAD_INIT(NULL, 0)
Jim Fultond15dc062004-07-14 19:11:50 +0000343 /* tp_name */ "thread._local",
344 /* tp_basicsize */ sizeof(localobject),
345 /* tp_itemsize */ 0,
346 /* tp_dealloc */ (destructor)local_dealloc,
Georg Brandld37ac692006-03-30 11:58:57 +0000347 /* tp_print */ 0,
348 /* tp_getattr */ 0,
349 /* tp_setattr */ 0,
350 /* tp_compare */ 0,
351 /* tp_repr */ 0,
Jim Fultond15dc062004-07-14 19:11:50 +0000352 /* tp_as_number */ 0,
353 /* tp_as_sequence */ 0,
354 /* tp_as_mapping */ 0,
Georg Brandld37ac692006-03-30 11:58:57 +0000355 /* tp_hash */ 0,
356 /* tp_call */ 0,
357 /* tp_str */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000358 /* tp_getattro */ (getattrofunc)local_getattro,
359 /* tp_setattro */ (setattrofunc)local_setattro,
360 /* tp_as_buffer */ 0,
361 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Jim Fultond15dc062004-07-14 19:11:50 +0000362 /* tp_doc */ "Thread-local data",
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000363 /* tp_traverse */ (traverseproc)local_traverse,
364 /* tp_clear */ (inquiry)local_clear,
Georg Brandld37ac692006-03-30 11:58:57 +0000365 /* tp_richcompare */ 0,
366 /* tp_weaklistoffset */ 0,
367 /* tp_iter */ 0,
368 /* tp_iternext */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000369 /* tp_methods */ 0,
370 /* tp_members */ 0,
371 /* tp_getset */ local_getset,
372 /* tp_base */ 0,
373 /* tp_dict */ 0, /* internal use */
Georg Brandld37ac692006-03-30 11:58:57 +0000374 /* tp_descr_get */ 0,
375 /* tp_descr_set */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000376 /* tp_dictoffset */ offsetof(localobject, dict),
Georg Brandld37ac692006-03-30 11:58:57 +0000377 /* tp_init */ 0,
378 /* tp_alloc */ 0,
379 /* tp_new */ local_new,
Jim Fultond15dc062004-07-14 19:11:50 +0000380 /* tp_free */ 0, /* Low-level free-mem routine */
Georg Brandld37ac692006-03-30 11:58:57 +0000381 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000382};
383
Anthony Baxter5576b542006-04-12 04:08:46 +0000384static PyObject *
385local_getattro(localobject *self, PyObject *name)
386{
387 PyObject *ldict, *value;
388
389 ldict = _ldict(self);
390 if (ldict == NULL)
391 return NULL;
392
Christian Heimese93237d2007-12-19 02:37:44 +0000393 if (Py_TYPE(self) != &localtype)
Anthony Baxter5576b542006-04-12 04:08:46 +0000394 /* use generic lookup for subtypes */
395 return PyObject_GenericGetAttr((PyObject *)self, name);
396
397 /* Optimization: just look in dict ourselves */
398 value = PyDict_GetItem(ldict, name);
399 if (value == NULL)
400 /* Fall back on generic to get __class__ and __dict__ */
401 return PyObject_GenericGetAttr((PyObject *)self, name);
402
403 Py_INCREF(value);
404 return value;
405}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000406
407/* Module functions */
408
Guido van Rossuma027efa1997-05-05 20:56:21 +0000409struct bootstate {
410 PyInterpreterState *interp;
411 PyObject *func;
412 PyObject *args;
413 PyObject *keyw;
414};
415
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000416static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000417t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000418{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000419 struct bootstate *boot = (struct bootstate *) boot_raw;
Michael W. Hudson188d4362005-06-20 16:52:57 +0000420 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000421 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000422
Michael W. Hudson188d4362005-06-20 16:52:57 +0000423 tstate = PyThreadState_New(boot->interp);
424
425 PyEval_AcquireThread(tstate);
Guido van Rossuma027efa1997-05-05 20:56:21 +0000426 res = PyEval_CallObjectWithKeywords(
427 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000428 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000429 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000430 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000431 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000432 PyObject *file;
433 PySys_WriteStderr(
434 "Unhandled exception in thread started by ");
435 file = PySys_GetObject("stderr");
436 if (file)
437 PyFile_WriteObject(boot->func, file, 0);
438 else
439 PyObject_Print(boot->func, stderr, 0);
440 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000441 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000442 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000443 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000444 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000445 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000446 Py_DECREF(boot->func);
447 Py_DECREF(boot->args);
448 Py_XDECREF(boot->keyw);
449 PyMem_DEL(boot_raw);
Michael W. Hudson188d4362005-06-20 16:52:57 +0000450 PyThreadState_Clear(tstate);
451 PyThreadState_DeleteCurrent();
Guido van Rossumbcc20741998-08-04 22:53:56 +0000452 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000453}
454
Barry Warsawd0c10421996-12-17 00:05:22 +0000455static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000456thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000457{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000458 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000459 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000460 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000461
Georg Brandl96a8c392006-05-29 21:04:52 +0000462 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
463 &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000464 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000465 if (!PyCallable_Check(func)) {
466 PyErr_SetString(PyExc_TypeError,
467 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000468 return NULL;
469 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000470 if (!PyTuple_Check(args)) {
471 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000472 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000473 return NULL;
474 }
475 if (keyw != NULL && !PyDict_Check(keyw)) {
476 PyErr_SetString(PyExc_TypeError,
477 "optional 3rd arg must be a dictionary");
478 return NULL;
479 }
480 boot = PyMem_NEW(struct bootstate, 1);
481 if (boot == NULL)
482 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000483 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000484 boot->func = func;
485 boot->args = args;
486 boot->keyw = keyw;
487 Py_INCREF(func);
488 Py_INCREF(args);
489 Py_XINCREF(keyw);
490 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000491 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
492 if (ident == -1) {
Guido van Rossum54c273c2005-02-20 03:02:16 +0000493 PyErr_SetString(ThreadError, "can't start new thread");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000494 Py_DECREF(func);
495 Py_DECREF(args);
496 Py_XDECREF(keyw);
497 PyMem_DEL(boot);
498 return NULL;
499 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000500 return PyInt_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000501}
502
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000503PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000504"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000505(start_new() is an obsolete synonym)\n\
506\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000507Start a new thread and return its identifier. The thread will call the\n\
508function with positional arguments from the tuple args and keyword arguments\n\
509taken from the optional dictionary kwargs. The thread exits when the\n\
510function returns; the return value is ignored. The thread will also exit\n\
511when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000512printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000513
Barry Warsawd0c10421996-12-17 00:05:22 +0000514static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000515thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000516{
Barry Warsawd0c10421996-12-17 00:05:22 +0000517 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000518 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000519}
520
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000521PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000522"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000523(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000524\n\
525This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000526thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000527
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000528static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000529thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000530{
531 PyErr_SetInterrupt();
532 Py_INCREF(Py_None);
533 return Py_None;
534}
535
536PyDoc_STRVAR(interrupt_doc,
537"interrupt_main()\n\
538\n\
539Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000540A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000541);
542
Guido van Rossumb6775db1994-08-01 11:34:53 +0000543#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000544static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000545thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000546{
547 int sts;
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000548 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000549 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000550 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000551 for (;;) { } /* Should not be reached */
552}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000553#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000554
Anthony Baxter5576b542006-04-12 04:08:46 +0000555static lockobject *newlockobject(void);
556
Barry Warsawd0c10421996-12-17 00:05:22 +0000557static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000558thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000559{
Barry Warsawd0c10421996-12-17 00:05:22 +0000560 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000561}
562
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000563PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000564"allocate_lock() -> lock object\n\
565(allocate() is an obsolete synonym)\n\
566\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000567Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000568
Barry Warsawd0c10421996-12-17 00:05:22 +0000569static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000570thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000571{
572 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000573 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000574 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000575 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000576 return NULL;
577 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000578 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000579}
580
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000581PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000582"get_ident() -> integer\n\
583\n\
584Return a non-zero integer that uniquely identifies the current thread\n\
585amongst other threads that exist simultaneously.\n\
586This may be used to identify per-thread resources.\n\
587Even though on some platforms threads identities may appear to be\n\
588allocated consecutive numbers starting at 1, this behavior should not\n\
589be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000590A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000591
Andrew MacIntyre92913322006-06-13 15:04:24 +0000592static PyObject *
593thread_stack_size(PyObject *self, PyObject *args)
594{
595 size_t old_size;
596 Py_ssize_t new_size = 0;
Andrew MacIntyre92913322006-06-13 15:04:24 +0000597 int rc;
598
599 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
600 return NULL;
601
602 if (new_size < 0) {
603 PyErr_SetString(PyExc_ValueError,
604 "size must be 0 or a positive value");
605 return NULL;
606 }
607
608 old_size = PyThread_get_stacksize();
609
610 rc = PyThread_set_stacksize((size_t) new_size);
611 if (rc == -1) {
612 PyErr_Format(PyExc_ValueError,
613 "size not valid: %zd bytes",
614 new_size);
615 return NULL;
616 }
617 if (rc == -2) {
618 PyErr_SetString(ThreadError,
619 "setting stack size not supported");
620 return NULL;
621 }
622
623 return PyInt_FromSsize_t((Py_ssize_t) old_size);
624}
625
626PyDoc_STRVAR(stack_size_doc,
627"stack_size([size]) -> size\n\
628\n\
629Return the thread stack size used when creating new threads. The\n\
630optional size argument specifies the stack size (in bytes) to be used\n\
631for subsequently created threads, and must be 0 (use platform or\n\
632configured default) or a positive integer value of at least 32,768 (32k).\n\
633If changing the thread stack size is unsupported, a ThreadError\n\
634exception is raised. If the specified size is invalid, a ValueError\n\
635exception is raised, and the stack size is unmodified. 32k bytes\n\
636 currently the minimum supported stack size value to guarantee\n\
637sufficient stack space for the interpreter itself.\n\
638\n\
639Note that some platforms may have particular restrictions on values for\n\
640the stack size, such as requiring a minimum stack size larger than 32kB or\n\
641requiring allocation in multiples of the system memory page size\n\
642- platform documentation should be referred to for more information\n\
643(4kB pages are common; using multiples of 4096 for the stack size is\n\
644the suggested approach in the absence of more specific information).");
645
Barry Warsawd0c10421996-12-17 00:05:22 +0000646static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000647 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
648 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000649 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000650 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
651 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000652 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000653 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000654 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000655 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000656 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000657 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000658 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000659 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000660 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000661 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000662 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000663 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000664 METH_NOARGS, get_ident_doc},
Andrew MacIntyre92913322006-06-13 15:04:24 +0000665 {"stack_size", (PyCFunction)thread_stack_size,
666 METH_VARARGS,
667 stack_size_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000668#ifndef NO_EXIT_PROG
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000669 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
670 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000671#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000672 {NULL, NULL} /* sentinel */
673};
674
675
676/* Initialization function */
677
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000678PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000679"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000680The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000681
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000682PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000683"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000684call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000685\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000686acquire() -- lock the lock, possibly blocking until it can be obtained\n\
687release() -- unlock of the lock\n\
688locked() -- test whether the lock is currently locked\n\
689\n\
690A lock is not owned by the thread that locked it; another thread may\n\
691unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000692will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000693
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000694PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000695initthread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000696{
Barry Warsawd0c10421996-12-17 00:05:22 +0000697 PyObject *m, *d;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000698
699 /* Initialize types: */
700 if (PyType_Ready(&localtype) < 0)
701 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000702
703 /* Create the module and add the functions */
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000704 m = Py_InitModule3("thread", thread_methods, thread_doc);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000705 if (m == NULL)
706 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000707
708 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000709 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000710 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000711 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000712 Locktype.tp_doc = lock_doc;
713 Py_INCREF(&Locktype);
714 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000715
Michael W. Hudson64e08142005-06-15 12:25:20 +0000716 Py_INCREF(&localtype);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000717 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
718 return;
Jim Fultond15dc062004-07-14 19:11:50 +0000719
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000720 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000721 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000722}