blob: b65360e375f895ade24c0c5d9f12270cee6ce2f2 [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"
Gregory P. Smith4e63d542009-08-20 09:39:38 +00006#include "structmember.h" /* offsetof */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00007
Guido van Rossumb6775db1994-08-01 11:34:53 +00008#ifndef WITH_THREAD
Guido van Rossuma027efa1997-05-05 20:56:21 +00009#error "Error! The rest of Python is not compiled with thread support."
Neal Norwitz884baa12002-09-05 21:31:04 +000010#error "Rerun configure, adding a --with-threads option."
Guido van Rossuma027efa1997-05-05 20:56:21 +000011#error "Then run `make clean' followed by `make'."
Guido van Rossumb6775db1994-08-01 11:34:53 +000012#endif
13
Guido van Rossum49b56061998-10-01 20:42:43 +000014#include "pythread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000015
Barry Warsawd0c10421996-12-17 00:05:22 +000016static PyObject *ThreadError;
Antoine Pitrou59c44f32009-10-30 17:07:08 +000017static long nb_threads = 0;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000018
19/* Lock objects */
20
21typedef struct {
Barry Warsawd0c10421996-12-17 00:05:22 +000022 PyObject_HEAD
Guido van Rossum65d5b571998-12-21 19:32:43 +000023 PyThread_type_lock lock_lock;
Gregory P. Smith4e63d542009-08-20 09:39:38 +000024 PyObject *in_weakreflist;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000025} lockobject;
26
Guido van Rossum1984f1e1992-08-04 12:41:02 +000027static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000028lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000029{
Gregory P. Smith4e63d542009-08-20 09:39:38 +000030 if (self->in_weakreflist != NULL)
31 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinnerc951d562010-03-03 00:43:44 +000032 if (self->lock_lock != NULL) {
33 /* Unlock the lock so it's safe to free it */
34 PyThread_acquire_lock(self->lock_lock, 0);
35 PyThread_release_lock(self->lock_lock);
36
37 PyThread_free_lock(self->lock_lock);
38 }
Guido van Rossumb18618d2000-05-03 23:44:39 +000039 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000040}
41
Barry Warsawd0c10421996-12-17 00:05:22 +000042static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000043lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000044{
Neal Norwitzba3a16c2002-03-31 15:27:00 +000045 int i = 1;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000046
Neal Norwitzba3a16c2002-03-31 15:27:00 +000047 if (!PyArg_ParseTuple(args, "|i:acquire", &i))
48 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000049
Barry Warsawd0c10421996-12-17 00:05:22 +000050 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +000051 i = PyThread_acquire_lock(self->lock_lock, i);
Barry Warsawd0c10421996-12-17 00:05:22 +000052 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +000053
Andrew M. Kuchlinga43ece92005-06-02 17:07:11 +000054 return PyBool_FromLong((long)i);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000055}
56
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000057PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000058"acquire([wait]) -> None or bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000059(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000060\n\
61Lock the lock. Without argument, this blocks if the lock is already\n\
62locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000063the lock, and return None once the lock is acquired.\n\
64With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000065and the return value reflects whether the lock is acquired.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000066The blocking operation is not interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000067
Barry Warsawd0c10421996-12-17 00:05:22 +000068static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000069lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000070{
Guido van Rossum1984f1e1992-08-04 12:41:02 +000071 /* Sanity check: the lock must be locked */
Guido van Rossum65d5b571998-12-21 19:32:43 +000072 if (PyThread_acquire_lock(self->lock_lock, 0)) {
73 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000074 PyErr_SetString(ThreadError, "release unlocked lock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +000075 return NULL;
76 }
77
Guido van Rossum65d5b571998-12-21 19:32:43 +000078 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000079 Py_INCREF(Py_None);
80 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000081}
82
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000083PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +000084"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000085(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000086\n\
87Release the lock, allowing another thread that is blocked waiting for\n\
88the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000089but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000090
Barry Warsawd0c10421996-12-17 00:05:22 +000091static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000092lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000093{
Guido van Rossum65d5b571998-12-21 19:32:43 +000094 if (PyThread_acquire_lock(self->lock_lock, 0)) {
95 PyThread_release_lock(self->lock_lock);
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000096 return PyBool_FromLong(0L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000097 }
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000098 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000099}
100
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000101PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000102"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000103(locked_lock() is an obsolete synonym)\n\
104\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000105Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000106
Barry Warsawd0c10421996-12-17 00:05:22 +0000107static PyMethodDef lock_methods[] = {
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000108 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000109 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000110 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000111 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000112 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000113 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000114 {"release", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000115 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000116 {"locked_lock", (PyCFunction)lock_locked_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000117 METH_NOARGS, locked_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000118 {"locked", (PyCFunction)lock_locked_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000119 METH_NOARGS, locked_doc},
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000120 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
121 METH_VARARGS, acquire_doc},
Guido van Rossumf6694362006-03-10 02:28:35 +0000122 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
123 METH_VARARGS, release_doc},
Benjamin Petersona7724e52009-05-24 23:13:32 +0000124 {NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000125};
126
Barry Warsawd0c10421996-12-17 00:05:22 +0000127static PyTypeObject Locktype = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000128 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Guido van Rossum14648392001-12-08 18:02:58 +0000129 "thread.lock", /*tp_name*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000130 sizeof(lockobject), /*tp_size*/
131 0, /*tp_itemsize*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000132 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000133 (destructor)lock_dealloc, /*tp_dealloc*/
134 0, /*tp_print*/
Benjamin Petersona7724e52009-05-24 23:13:32 +0000135 0, /*tp_getattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000136 0, /*tp_setattr*/
137 0, /*tp_compare*/
138 0, /*tp_repr*/
Benjamin Petersona7724e52009-05-24 23:13:32 +0000139 0, /* tp_as_number */
140 0, /* tp_as_sequence */
141 0, /* tp_as_mapping */
142 0, /* tp_hash */
143 0, /* tp_call */
144 0, /* tp_str */
145 0, /* tp_getattro */
146 0, /* tp_setattro */
147 0, /* tp_as_buffer */
Gregory P. Smith4e63d542009-08-20 09:39:38 +0000148 Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Benjamin Petersona7724e52009-05-24 23:13:32 +0000149 0, /* tp_doc */
150 0, /* tp_traverse */
151 0, /* tp_clear */
152 0, /* tp_richcompare */
Gregory P. Smith4e63d542009-08-20 09:39:38 +0000153 offsetof(lockobject, in_weakreflist), /* tp_weaklistoffset */
Benjamin Petersona7724e52009-05-24 23:13:32 +0000154 0, /* tp_iter */
155 0, /* tp_iternext */
156 lock_methods, /* tp_methods */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000157};
158
Anthony Baxter5576b542006-04-12 04:08:46 +0000159static lockobject *
160newlockobject(void)
161{
162 lockobject *self;
163 self = PyObject_New(lockobject, &Locktype);
164 if (self == NULL)
165 return NULL;
166 self->lock_lock = PyThread_allocate_lock();
Gregory P. Smith4e63d542009-08-20 09:39:38 +0000167 self->in_weakreflist = NULL;
Anthony Baxter5576b542006-04-12 04:08:46 +0000168 if (self->lock_lock == NULL) {
Victor Stinnerc951d562010-03-03 00:43:44 +0000169 Py_DECREF(self);
Anthony Baxter5576b542006-04-12 04:08:46 +0000170 PyErr_SetString(ThreadError, "can't allocate lock");
Victor Stinnerc951d562010-03-03 00:43:44 +0000171 return NULL;
Anthony Baxter5576b542006-04-12 04:08:46 +0000172 }
173 return self;
174}
175
Jim Fultond15dc062004-07-14 19:11:50 +0000176/* Thread-local objects */
177
178#include "structmember.h"
179
180typedef struct {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000181 PyObject_HEAD
182 PyObject *key;
183 PyObject *args;
184 PyObject *kw;
185 PyObject *dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000186} localobject;
187
Jim Fultond15dc062004-07-14 19:11:50 +0000188static PyObject *
189local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
190{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000191 localobject *self;
192 PyObject *tdict;
Jim Fultond15dc062004-07-14 19:11:50 +0000193
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000194 if (type->tp_init == PyBaseObject_Type.tp_init
195 && ((args && PyObject_IsTrue(args))
196 || (kw && PyObject_IsTrue(kw)))) {
197 PyErr_SetString(PyExc_TypeError,
198 "Initialization arguments are not supported");
199 return NULL;
200 }
Jim Fultond15dc062004-07-14 19:11:50 +0000201
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000202 self = (localobject *)type->tp_alloc(type, 0);
203 if (self == NULL)
204 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000205
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000206 Py_XINCREF(args);
207 self->args = args;
208 Py_XINCREF(kw);
209 self->kw = kw;
210 self->dict = NULL; /* making sure */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000211 self->key = PyString_FromFormat("thread.local.%p", self);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000212 if (self->key == NULL)
213 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000214
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000215 self->dict = PyDict_New();
216 if (self->dict == NULL)
217 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000218
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000219 tdict = PyThreadState_GetDict();
220 if (tdict == NULL) {
221 PyErr_SetString(PyExc_SystemError,
222 "Couldn't get thread-state dictionary");
223 goto err;
224 }
Jim Fultond15dc062004-07-14 19:11:50 +0000225
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000226 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
227 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000228
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000229 return (PyObject *)self;
230
231 err:
232 Py_DECREF(self);
233 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000234}
235
236static int
237local_traverse(localobject *self, visitproc visit, void *arg)
238{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000239 Py_VISIT(self->args);
240 Py_VISIT(self->kw);
241 Py_VISIT(self->dict);
Jim Fultond15dc062004-07-14 19:11:50 +0000242 return 0;
243}
244
245static int
246local_clear(localobject *self)
247{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000248 Py_CLEAR(self->args);
249 Py_CLEAR(self->kw);
250 Py_CLEAR(self->dict);
251 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000252}
253
254static void
255local_dealloc(localobject *self)
256{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000257 PyThreadState *tstate;
258 if (self->key
259 && (tstate = PyThreadState_Get())
260 && tstate->interp) {
261 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
262 tstate;
263 tstate = PyThreadState_Next(tstate))
264 if (tstate->dict &&
265 PyDict_GetItem(tstate->dict, self->key))
266 PyDict_DelItem(tstate->dict, self->key);
267 }
Jim Fultond15dc062004-07-14 19:11:50 +0000268
Philip Jenveydbf3b252009-09-29 04:32:44 +0000269 Py_XDECREF(self->key);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000270 local_clear(self);
Christian Heimese93237d2007-12-19 02:37:44 +0000271 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000272}
273
274static PyObject *
275_ldict(localobject *self)
276{
277 PyObject *tdict, *ldict;
278
279 tdict = PyThreadState_GetDict();
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000280 if (tdict == NULL) {
281 PyErr_SetString(PyExc_SystemError,
282 "Couldn't get thread-state dictionary");
283 return NULL;
284 }
Jim Fultond15dc062004-07-14 19:11:50 +0000285
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000286 ldict = PyDict_GetItem(tdict, self->key);
287 if (ldict == NULL) {
288 ldict = PyDict_New(); /* we own ldict */
Jim Fultond15dc062004-07-14 19:11:50 +0000289
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000290 if (ldict == NULL)
291 return NULL;
292 else {
293 int i = PyDict_SetItem(tdict, self->key, ldict);
Georg Brandlf3c4ad12006-03-08 12:24:33 +0000294 Py_DECREF(ldict); /* now ldict is borrowed */
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000295 if (i < 0)
296 return NULL;
297 }
Jim Fultond15dc062004-07-14 19:11:50 +0000298
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000299 Py_CLEAR(self->dict);
300 Py_INCREF(ldict);
301 self->dict = ldict; /* still borrowed */
Jim Fultond15dc062004-07-14 19:11:50 +0000302
Christian Heimese93237d2007-12-19 02:37:44 +0000303 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
304 Py_TYPE(self)->tp_init((PyObject*)self,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000305 self->args, self->kw) < 0) {
306 /* we need to get rid of ldict from thread so
307 we create a new one the next time we do an attr
308 acces */
309 PyDict_DelItem(tdict, self->key);
310 return NULL;
311 }
312
313 }
Amaury Forgeot d'Arc1f40c8a2008-06-30 22:42:40 +0000314
315 /* The call to tp_init above may have caused another thread to run.
316 Install our ldict again. */
317 if (self->dict != ldict) {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000318 Py_CLEAR(self->dict);
319 Py_INCREF(ldict);
320 self->dict = ldict;
321 }
Jim Fultond15dc062004-07-14 19:11:50 +0000322
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000323 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000324}
325
Jim Fultond15dc062004-07-14 19:11:50 +0000326static int
327local_setattro(localobject *self, PyObject *name, PyObject *v)
328{
329 PyObject *ldict;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000330
331 ldict = _ldict(self);
332 if (ldict == NULL)
333 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000334
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000335 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000336}
337
338static PyObject *
339local_getdict(localobject *self, void *closure)
340{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000341 if (self->dict == NULL) {
342 PyErr_SetString(PyExc_AttributeError, "__dict__");
343 return NULL;
344 }
Jim Fultond15dc062004-07-14 19:11:50 +0000345
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000346 Py_INCREF(self->dict);
347 return self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000348}
349
350static PyGetSetDef local_getset[] = {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000351 {"__dict__", (getter)local_getdict, (setter)NULL,
352 "Local-data dictionary", NULL},
353 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000354};
355
Anthony Baxter5576b542006-04-12 04:08:46 +0000356static PyObject *local_getattro(localobject *, PyObject *);
357
Jim Fultond15dc062004-07-14 19:11:50 +0000358static PyTypeObject localtype = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000359 PyVarObject_HEAD_INIT(NULL, 0)
Jim Fultond15dc062004-07-14 19:11:50 +0000360 /* tp_name */ "thread._local",
361 /* tp_basicsize */ sizeof(localobject),
362 /* tp_itemsize */ 0,
363 /* tp_dealloc */ (destructor)local_dealloc,
Georg Brandld37ac692006-03-30 11:58:57 +0000364 /* tp_print */ 0,
365 /* tp_getattr */ 0,
366 /* tp_setattr */ 0,
367 /* tp_compare */ 0,
368 /* tp_repr */ 0,
Jim Fultond15dc062004-07-14 19:11:50 +0000369 /* tp_as_number */ 0,
370 /* tp_as_sequence */ 0,
371 /* tp_as_mapping */ 0,
Georg Brandld37ac692006-03-30 11:58:57 +0000372 /* tp_hash */ 0,
373 /* tp_call */ 0,
374 /* tp_str */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000375 /* tp_getattro */ (getattrofunc)local_getattro,
376 /* tp_setattro */ (setattrofunc)local_setattro,
377 /* tp_as_buffer */ 0,
378 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Jim Fultond15dc062004-07-14 19:11:50 +0000379 /* tp_doc */ "Thread-local data",
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000380 /* tp_traverse */ (traverseproc)local_traverse,
381 /* tp_clear */ (inquiry)local_clear,
Georg Brandld37ac692006-03-30 11:58:57 +0000382 /* tp_richcompare */ 0,
383 /* tp_weaklistoffset */ 0,
384 /* tp_iter */ 0,
385 /* tp_iternext */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000386 /* tp_methods */ 0,
387 /* tp_members */ 0,
388 /* tp_getset */ local_getset,
389 /* tp_base */ 0,
390 /* tp_dict */ 0, /* internal use */
Georg Brandld37ac692006-03-30 11:58:57 +0000391 /* tp_descr_get */ 0,
392 /* tp_descr_set */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000393 /* tp_dictoffset */ offsetof(localobject, dict),
Georg Brandld37ac692006-03-30 11:58:57 +0000394 /* tp_init */ 0,
395 /* tp_alloc */ 0,
396 /* tp_new */ local_new,
Jim Fultond15dc062004-07-14 19:11:50 +0000397 /* tp_free */ 0, /* Low-level free-mem routine */
Georg Brandld37ac692006-03-30 11:58:57 +0000398 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000399};
400
Anthony Baxter5576b542006-04-12 04:08:46 +0000401static PyObject *
402local_getattro(localobject *self, PyObject *name)
403{
404 PyObject *ldict, *value;
405
406 ldict = _ldict(self);
407 if (ldict == NULL)
408 return NULL;
409
Christian Heimese93237d2007-12-19 02:37:44 +0000410 if (Py_TYPE(self) != &localtype)
Anthony Baxter5576b542006-04-12 04:08:46 +0000411 /* use generic lookup for subtypes */
412 return PyObject_GenericGetAttr((PyObject *)self, name);
413
414 /* Optimization: just look in dict ourselves */
415 value = PyDict_GetItem(ldict, name);
416 if (value == NULL)
417 /* Fall back on generic to get __class__ and __dict__ */
418 return PyObject_GenericGetAttr((PyObject *)self, name);
419
420 Py_INCREF(value);
421 return value;
422}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000423
424/* Module functions */
425
Guido van Rossuma027efa1997-05-05 20:56:21 +0000426struct bootstate {
427 PyInterpreterState *interp;
428 PyObject *func;
429 PyObject *args;
430 PyObject *keyw;
431};
432
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000433static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000434t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000435{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000436 struct bootstate *boot = (struct bootstate *) boot_raw;
Michael W. Hudson188d4362005-06-20 16:52:57 +0000437 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000438 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000439
Michael W. Hudson188d4362005-06-20 16:52:57 +0000440 tstate = PyThreadState_New(boot->interp);
441
442 PyEval_AcquireThread(tstate);
Antoine Pitrou59c44f32009-10-30 17:07:08 +0000443 nb_threads++;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000444 res = PyEval_CallObjectWithKeywords(
445 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000446 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000447 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000448 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000449 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000450 PyObject *file;
451 PySys_WriteStderr(
452 "Unhandled exception in thread started by ");
453 file = PySys_GetObject("stderr");
454 if (file)
455 PyFile_WriteObject(boot->func, file, 0);
456 else
457 PyObject_Print(boot->func, stderr, 0);
458 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000459 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000460 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000461 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000462 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000463 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000464 Py_DECREF(boot->func);
465 Py_DECREF(boot->args);
466 Py_XDECREF(boot->keyw);
467 PyMem_DEL(boot_raw);
Antoine Pitrou59c44f32009-10-30 17:07:08 +0000468 nb_threads--;
Michael W. Hudson188d4362005-06-20 16:52:57 +0000469 PyThreadState_Clear(tstate);
470 PyThreadState_DeleteCurrent();
Guido van Rossumbcc20741998-08-04 22:53:56 +0000471 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000472}
473
Barry Warsawd0c10421996-12-17 00:05:22 +0000474static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000475thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000476{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000477 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000478 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000479 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000480
Georg Brandl96a8c392006-05-29 21:04:52 +0000481 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
482 &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000483 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000484 if (!PyCallable_Check(func)) {
485 PyErr_SetString(PyExc_TypeError,
486 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000487 return NULL;
488 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000489 if (!PyTuple_Check(args)) {
490 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000491 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000492 return NULL;
493 }
494 if (keyw != NULL && !PyDict_Check(keyw)) {
495 PyErr_SetString(PyExc_TypeError,
496 "optional 3rd arg must be a dictionary");
497 return NULL;
498 }
499 boot = PyMem_NEW(struct bootstate, 1);
500 if (boot == NULL)
501 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000502 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000503 boot->func = func;
504 boot->args = args;
505 boot->keyw = keyw;
506 Py_INCREF(func);
507 Py_INCREF(args);
508 Py_XINCREF(keyw);
509 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000510 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
511 if (ident == -1) {
Guido van Rossum54c273c2005-02-20 03:02:16 +0000512 PyErr_SetString(ThreadError, "can't start new thread");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000513 Py_DECREF(func);
514 Py_DECREF(args);
515 Py_XDECREF(keyw);
516 PyMem_DEL(boot);
517 return NULL;
518 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000519 return PyInt_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000520}
521
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000522PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000523"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000524(start_new() is an obsolete synonym)\n\
525\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000526Start a new thread and return its identifier. The thread will call the\n\
527function with positional arguments from the tuple args and keyword arguments\n\
528taken from the optional dictionary kwargs. The thread exits when the\n\
529function returns; the return value is ignored. The thread will also exit\n\
530when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000531printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000532
Barry Warsawd0c10421996-12-17 00:05:22 +0000533static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000534thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000535{
Barry Warsawd0c10421996-12-17 00:05:22 +0000536 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000537 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000538}
539
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000540PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000541"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000542(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000543\n\
544This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000545thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000546
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000547static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000548thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000549{
550 PyErr_SetInterrupt();
551 Py_INCREF(Py_None);
552 return Py_None;
553}
554
555PyDoc_STRVAR(interrupt_doc,
556"interrupt_main()\n\
557\n\
558Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000559A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000560);
561
Anthony Baxter5576b542006-04-12 04:08:46 +0000562static lockobject *newlockobject(void);
563
Barry Warsawd0c10421996-12-17 00:05:22 +0000564static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000565thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000566{
Barry Warsawd0c10421996-12-17 00:05:22 +0000567 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000568}
569
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000570PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000571"allocate_lock() -> lock object\n\
572(allocate() is an obsolete synonym)\n\
573\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000574Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000575
Barry Warsawd0c10421996-12-17 00:05:22 +0000576static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000577thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000578{
579 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000580 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000581 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000582 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000583 return NULL;
584 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000585 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000586}
587
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000588PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000589"get_ident() -> integer\n\
590\n\
591Return a non-zero integer that uniquely identifies the current thread\n\
592amongst other threads that exist simultaneously.\n\
593This may be used to identify per-thread resources.\n\
594Even though on some platforms threads identities may appear to be\n\
595allocated consecutive numbers starting at 1, this behavior should not\n\
596be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000597A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000598
Andrew MacIntyre92913322006-06-13 15:04:24 +0000599static PyObject *
Antoine Pitrou59c44f32009-10-30 17:07:08 +0000600thread__count(PyObject *self)
601{
602 return PyInt_FromLong(nb_threads);
603}
604
605PyDoc_STRVAR(_count_doc,
606"_count() -> integer\n\
607\n\
Antoine Pitrou2c970a22009-10-30 22:19:09 +0000608\
609Return the number of currently running Python threads, excluding \n\
610the main thread. The returned number comprises all threads created\n\
611through `start_new_thread()` as well as `threading.Thread`, and not\n\
612yet finished.\n\
613\n\
614This function is meant for internal and specialized purposes only.\n\
615In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou59c44f32009-10-30 17:07:08 +0000616
617static PyObject *
Andrew MacIntyre92913322006-06-13 15:04:24 +0000618thread_stack_size(PyObject *self, PyObject *args)
619{
620 size_t old_size;
621 Py_ssize_t new_size = 0;
Andrew MacIntyre92913322006-06-13 15:04:24 +0000622 int rc;
623
624 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
625 return NULL;
626
627 if (new_size < 0) {
628 PyErr_SetString(PyExc_ValueError,
629 "size must be 0 or a positive value");
630 return NULL;
631 }
632
633 old_size = PyThread_get_stacksize();
634
635 rc = PyThread_set_stacksize((size_t) new_size);
636 if (rc == -1) {
637 PyErr_Format(PyExc_ValueError,
638 "size not valid: %zd bytes",
639 new_size);
640 return NULL;
641 }
642 if (rc == -2) {
643 PyErr_SetString(ThreadError,
644 "setting stack size not supported");
645 return NULL;
646 }
647
648 return PyInt_FromSsize_t((Py_ssize_t) old_size);
649}
650
651PyDoc_STRVAR(stack_size_doc,
652"stack_size([size]) -> size\n\
653\n\
654Return the thread stack size used when creating new threads. The\n\
655optional size argument specifies the stack size (in bytes) to be used\n\
656for subsequently created threads, and must be 0 (use platform or\n\
657configured default) or a positive integer value of at least 32,768 (32k).\n\
658If changing the thread stack size is unsupported, a ThreadError\n\
659exception is raised. If the specified size is invalid, a ValueError\n\
660exception is raised, and the stack size is unmodified. 32k bytes\n\
661 currently the minimum supported stack size value to guarantee\n\
662sufficient stack space for the interpreter itself.\n\
663\n\
664Note that some platforms may have particular restrictions on values for\n\
665the stack size, such as requiring a minimum stack size larger than 32kB or\n\
666requiring allocation in multiples of the system memory page size\n\
667- platform documentation should be referred to for more information\n\
668(4kB pages are common; using multiples of 4096 for the stack size is\n\
669the suggested approach in the absence of more specific information).");
670
Barry Warsawd0c10421996-12-17 00:05:22 +0000671static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000672 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
673 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000674 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000675 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
676 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000677 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000678 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000679 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000680 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000681 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000682 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000683 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000684 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000685 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000686 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000687 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000688 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000689 METH_NOARGS, get_ident_doc},
Antoine Pitrou59c44f32009-10-30 17:07:08 +0000690 {"_count", (PyCFunction)thread__count,
691 METH_NOARGS, _count_doc},
Andrew MacIntyre92913322006-06-13 15:04:24 +0000692 {"stack_size", (PyCFunction)thread_stack_size,
693 METH_VARARGS,
694 stack_size_doc},
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000695 {NULL, NULL} /* sentinel */
696};
697
698
699/* Initialization function */
700
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000701PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000702"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000703The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000704
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000705PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000706"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000707call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000708\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000709acquire() -- lock the lock, possibly blocking until it can be obtained\n\
710release() -- unlock of the lock\n\
711locked() -- test whether the lock is currently locked\n\
712\n\
713A lock is not owned by the thread that locked it; another thread may\n\
714unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000715will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000716
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000717PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000718initthread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000719{
Barry Warsawd0c10421996-12-17 00:05:22 +0000720 PyObject *m, *d;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000721
722 /* Initialize types: */
723 if (PyType_Ready(&localtype) < 0)
724 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000725
726 /* Create the module and add the functions */
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000727 m = Py_InitModule3("thread", thread_methods, thread_doc);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000728 if (m == NULL)
729 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000730
731 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000732 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000733 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000734 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000735 Locktype.tp_doc = lock_doc;
Benjamin Petersona7724e52009-05-24 23:13:32 +0000736 if (PyType_Ready(&Locktype) < 0)
737 return;
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000738 Py_INCREF(&Locktype);
739 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000740
Michael W. Hudson64e08142005-06-15 12:25:20 +0000741 Py_INCREF(&localtype);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000742 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
743 return;
Jim Fultond15dc062004-07-14 19:11:50 +0000744
Antoine Pitrou59c44f32009-10-30 17:07:08 +0000745 nb_threads = 0;
746
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000747 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000748 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000749}