blob: 0fe9a763cd058953e77538f5d974a0505b744497 [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{
Thomas Wouters89f507f2006-12-13 04:49: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öwis9f2e3462007-07-21 17:22:18 +0000129 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Georg Brandl0a7ac7d2008-05-26 10:29:35 +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
Thomas Wouters49fd7fa2006-04-21 10:40:58 +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 */
Walter Dörwald4ee631e2007-06-20 14:55:01 +0000193 self->key = PyUnicode_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 Heimes90aa7642007-12-19 02:45:37 +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 Heimes90aa7642007-12-19 02:45:37 +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 }
296 else if (self->dict != ldict) {
297 Py_CLEAR(self->dict);
298 Py_INCREF(ldict);
299 self->dict = ldict;
300 }
Jim Fultond15dc062004-07-14 19:11:50 +0000301
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000302 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000303}
304
Jim Fultond15dc062004-07-14 19:11:50 +0000305static int
306local_setattro(localobject *self, PyObject *name, PyObject *v)
307{
308 PyObject *ldict;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000309
310 ldict = _ldict(self);
311 if (ldict == NULL)
312 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000313
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000314 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000315}
316
317static PyObject *
318local_getdict(localobject *self, void *closure)
319{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000320 if (self->dict == NULL) {
321 PyErr_SetString(PyExc_AttributeError, "__dict__");
322 return NULL;
323 }
Jim Fultond15dc062004-07-14 19:11:50 +0000324
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000325 Py_INCREF(self->dict);
326 return self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000327}
328
329static PyGetSetDef local_getset[] = {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000330 {"__dict__", (getter)local_getdict, (setter)NULL,
331 "Local-data dictionary", NULL},
332 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000333};
334
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000335static PyObject *local_getattro(localobject *, PyObject *);
336
Jim Fultond15dc062004-07-14 19:11:50 +0000337static PyTypeObject localtype = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000338 PyVarObject_HEAD_INIT(NULL, 0)
Georg Brandl0a7ac7d2008-05-26 10:29:35 +0000339 /* tp_name */ "_thread._local",
Jim Fultond15dc062004-07-14 19:11:50 +0000340 /* tp_basicsize */ sizeof(localobject),
341 /* tp_itemsize */ 0,
342 /* tp_dealloc */ (destructor)local_dealloc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000343 /* tp_print */ 0,
344 /* tp_getattr */ 0,
345 /* tp_setattr */ 0,
346 /* tp_compare */ 0,
347 /* tp_repr */ 0,
Jim Fultond15dc062004-07-14 19:11:50 +0000348 /* tp_as_number */ 0,
349 /* tp_as_sequence */ 0,
350 /* tp_as_mapping */ 0,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000351 /* tp_hash */ 0,
352 /* tp_call */ 0,
353 /* tp_str */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000354 /* tp_getattro */ (getattrofunc)local_getattro,
355 /* tp_setattro */ (setattrofunc)local_setattro,
356 /* tp_as_buffer */ 0,
357 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Jim Fultond15dc062004-07-14 19:11:50 +0000358 /* tp_doc */ "Thread-local data",
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000359 /* tp_traverse */ (traverseproc)local_traverse,
360 /* tp_clear */ (inquiry)local_clear,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000361 /* tp_richcompare */ 0,
362 /* tp_weaklistoffset */ 0,
363 /* tp_iter */ 0,
364 /* tp_iternext */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000365 /* tp_methods */ 0,
366 /* tp_members */ 0,
367 /* tp_getset */ local_getset,
368 /* tp_base */ 0,
369 /* tp_dict */ 0, /* internal use */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000370 /* tp_descr_get */ 0,
371 /* tp_descr_set */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000372 /* tp_dictoffset */ offsetof(localobject, dict),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000373 /* tp_init */ 0,
374 /* tp_alloc */ 0,
375 /* tp_new */ local_new,
Jim Fultond15dc062004-07-14 19:11:50 +0000376 /* tp_free */ 0, /* Low-level free-mem routine */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000377 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000378};
379
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000380static PyObject *
381local_getattro(localobject *self, PyObject *name)
382{
383 PyObject *ldict, *value;
384
385 ldict = _ldict(self);
386 if (ldict == NULL)
387 return NULL;
388
Christian Heimes90aa7642007-12-19 02:45:37 +0000389 if (Py_TYPE(self) != &localtype)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000390 /* use generic lookup for subtypes */
391 return PyObject_GenericGetAttr((PyObject *)self, name);
392
393 /* Optimization: just look in dict ourselves */
394 value = PyDict_GetItem(ldict, name);
395 if (value == NULL)
396 /* Fall back on generic to get __class__ and __dict__ */
397 return PyObject_GenericGetAttr((PyObject *)self, name);
398
399 Py_INCREF(value);
400 return value;
401}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000402
403/* Module functions */
404
Guido van Rossuma027efa1997-05-05 20:56:21 +0000405struct bootstate {
406 PyInterpreterState *interp;
407 PyObject *func;
408 PyObject *args;
409 PyObject *keyw;
410};
411
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000412static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000413t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000414{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000415 struct bootstate *boot = (struct bootstate *) boot_raw;
Michael W. Hudson188d4362005-06-20 16:52:57 +0000416 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000417 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000418
Michael W. Hudson188d4362005-06-20 16:52:57 +0000419 tstate = PyThreadState_New(boot->interp);
420
421 PyEval_AcquireThread(tstate);
Guido van Rossuma027efa1997-05-05 20:56:21 +0000422 res = PyEval_CallObjectWithKeywords(
423 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000424 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000425 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000426 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000427 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000428 PyObject *file;
429 PySys_WriteStderr(
430 "Unhandled exception in thread started by ");
431 file = PySys_GetObject("stderr");
Christian Heimes2be03732007-11-15 02:26:46 +0000432 if (file != NULL && file != Py_None)
Guido van Rossum24ccca12003-04-29 19:44:05 +0000433 PyFile_WriteObject(boot->func, file, 0);
434 else
435 PyObject_Print(boot->func, stderr, 0);
436 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000437 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000438 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000439 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000440 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000441 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000442 Py_DECREF(boot->func);
443 Py_DECREF(boot->args);
444 Py_XDECREF(boot->keyw);
445 PyMem_DEL(boot_raw);
Michael W. Hudson188d4362005-06-20 16:52:57 +0000446 PyThreadState_Clear(tstate);
447 PyThreadState_DeleteCurrent();
Guido van Rossumbcc20741998-08-04 22:53:56 +0000448 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000449}
450
Barry Warsawd0c10421996-12-17 00:05:22 +0000451static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000452thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000453{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000454 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000455 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000456 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000457
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000458 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
459 &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000460 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000461 if (!PyCallable_Check(func)) {
462 PyErr_SetString(PyExc_TypeError,
463 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000464 return NULL;
465 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000466 if (!PyTuple_Check(args)) {
467 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000468 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000469 return NULL;
470 }
471 if (keyw != NULL && !PyDict_Check(keyw)) {
472 PyErr_SetString(PyExc_TypeError,
473 "optional 3rd arg must be a dictionary");
474 return NULL;
475 }
476 boot = PyMem_NEW(struct bootstate, 1);
477 if (boot == NULL)
478 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000479 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000480 boot->func = func;
481 boot->args = args;
482 boot->keyw = keyw;
483 Py_INCREF(func);
484 Py_INCREF(args);
485 Py_XINCREF(keyw);
486 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000487 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
488 if (ident == -1) {
Guido van Rossum54c273c2005-02-20 03:02:16 +0000489 PyErr_SetString(ThreadError, "can't start new thread");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000490 Py_DECREF(func);
491 Py_DECREF(args);
492 Py_XDECREF(keyw);
493 PyMem_DEL(boot);
494 return NULL;
495 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000496 return PyLong_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000497}
498
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000499PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000500"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000501(start_new() is an obsolete synonym)\n\
502\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000503Start a new thread and return its identifier. The thread will call the\n\
504function with positional arguments from the tuple args and keyword arguments\n\
505taken from the optional dictionary kwargs. The thread exits when the\n\
506function returns; the return value is ignored. The thread will also exit\n\
507when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000508printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000509
Barry Warsawd0c10421996-12-17 00:05:22 +0000510static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000511thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000512{
Barry Warsawd0c10421996-12-17 00:05:22 +0000513 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000514 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000515}
516
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000517PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000518"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000519(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000520\n\
521This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000522thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000523
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000524static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000525thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000526{
527 PyErr_SetInterrupt();
528 Py_INCREF(Py_None);
529 return Py_None;
530}
531
532PyDoc_STRVAR(interrupt_doc,
533"interrupt_main()\n\
534\n\
535Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000536A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000537);
538
Guido van Rossumb6775db1994-08-01 11:34:53 +0000539#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000540static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000541thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000542{
543 int sts;
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000544 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000545 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000546 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000547 for (;;) { } /* Should not be reached */
548}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000549#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000550
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000551static lockobject *newlockobject(void);
552
Barry Warsawd0c10421996-12-17 00:05:22 +0000553static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000554thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000555{
Barry Warsawd0c10421996-12-17 00:05:22 +0000556 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000557}
558
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000559PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000560"allocate_lock() -> lock object\n\
561(allocate() is an obsolete synonym)\n\
562\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000563Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000564
Barry Warsawd0c10421996-12-17 00:05:22 +0000565static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000566thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000567{
568 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000569 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000570 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000571 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000572 return NULL;
573 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000574 return PyLong_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000575}
576
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000577PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000578"get_ident() -> integer\n\
579\n\
580Return a non-zero integer that uniquely identifies the current thread\n\
581amongst other threads that exist simultaneously.\n\
582This may be used to identify per-thread resources.\n\
583Even though on some platforms threads identities may appear to be\n\
584allocated consecutive numbers starting at 1, this behavior should not\n\
585be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000586A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000587
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000588static PyObject *
589thread_stack_size(PyObject *self, PyObject *args)
590{
591 size_t old_size;
592 Py_ssize_t new_size = 0;
593 int rc;
594
595 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
596 return NULL;
597
598 if (new_size < 0) {
599 PyErr_SetString(PyExc_ValueError,
600 "size must be 0 or a positive value");
601 return NULL;
602 }
603
604 old_size = PyThread_get_stacksize();
605
606 rc = PyThread_set_stacksize((size_t) new_size);
607 if (rc == -1) {
608 PyErr_Format(PyExc_ValueError,
609 "size not valid: %zd bytes",
610 new_size);
611 return NULL;
612 }
613 if (rc == -2) {
614 PyErr_SetString(ThreadError,
615 "setting stack size not supported");
616 return NULL;
617 }
618
Christian Heimes217cfd12007-12-02 14:31:20 +0000619 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000620}
621
622PyDoc_STRVAR(stack_size_doc,
623"stack_size([size]) -> size\n\
624\n\
625Return the thread stack size used when creating new threads. The\n\
626optional size argument specifies the stack size (in bytes) to be used\n\
627for subsequently created threads, and must be 0 (use platform or\n\
628configured default) or a positive integer value of at least 32,768 (32k).\n\
629If changing the thread stack size is unsupported, a ThreadError\n\
630exception is raised. If the specified size is invalid, a ValueError\n\
631exception is raised, and the stack size is unmodified. 32k bytes\n\
632 currently the minimum supported stack size value to guarantee\n\
633sufficient stack space for the interpreter itself.\n\
634\n\
635Note that some platforms may have particular restrictions on values for\n\
636the stack size, such as requiring a minimum stack size larger than 32kB or\n\
637requiring allocation in multiples of the system memory page size\n\
638- platform documentation should be referred to for more information\n\
639(4kB pages are common; using multiples of 4096 for the stack size is\n\
640the suggested approach in the absence of more specific information).");
641
Barry Warsawd0c10421996-12-17 00:05:22 +0000642static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000643 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
644 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000645 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000646 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
647 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000648 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000649 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000650 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000651 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000652 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000653 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000654 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000655 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000656 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000657 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000658 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000659 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000660 METH_NOARGS, get_ident_doc},
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000661 {"stack_size", (PyCFunction)thread_stack_size,
662 METH_VARARGS,
663 stack_size_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000664#ifndef NO_EXIT_PROG
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000665 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
666 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000667#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000668 {NULL, NULL} /* sentinel */
669};
670
671
672/* Initialization function */
673
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000674PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000675"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000676The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000677
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000678PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000679"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000680call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000681\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000682acquire() -- lock the lock, possibly blocking until it can be obtained\n\
683release() -- unlock of the lock\n\
684locked() -- test whether the lock is currently locked\n\
685\n\
686A lock is not owned by the thread that locked it; another thread may\n\
687unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000688will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000689
Martin v. Löwis1a214512008-06-11 05:26:20 +0000690static struct PyModuleDef threadmodule = {
691 PyModuleDef_HEAD_INIT,
692 "_thread",
693 thread_doc,
694 -1,
695 thread_methods,
696 NULL,
697 NULL,
698 NULL,
699 NULL
700};
701
702
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000703PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000704PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000705{
Barry Warsawd0c10421996-12-17 00:05:22 +0000706 PyObject *m, *d;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000707
708 /* Initialize types: */
709 if (PyType_Ready(&localtype) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000710 return NULL;
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000711 if (PyType_Ready(&Locktype) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000712 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000713
714 /* Create the module and add the functions */
Martin v. Löwis1a214512008-06-11 05:26:20 +0000715 m = PyModule_Create(&threadmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000716 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000717 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000718
719 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000720 d = PyModule_GetDict(m);
Georg Brandl2067bfd2008-05-25 13:05:15 +0000721 ThreadError = PyErr_NewException("_thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000722 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000723 Locktype.tp_doc = lock_doc;
724 Py_INCREF(&Locktype);
725 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000726
Michael W. Hudson64e08142005-06-15 12:25:20 +0000727 Py_INCREF(&localtype);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000728 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000729 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000730
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000731 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000732 PyThread_init_thread();
Martin v. Löwis1a214512008-06-11 05:26:20 +0000733 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000734}