blob: f0d03d74362c4ea6568ace9890adb48af04e0212 [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 PyTypeObject Locktype = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000123 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Georg Brandl0a7ac7d2008-05-26 10:29:35 +0000124 "_thread.lock", /*tp_name*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000125 sizeof(lockobject), /*tp_size*/
126 0, /*tp_itemsize*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000127 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000128 (destructor)lock_dealloc, /*tp_dealloc*/
129 0, /*tp_print*/
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000130 0, /*tp_getattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000131 0, /*tp_setattr*/
132 0, /*tp_compare*/
133 0, /*tp_repr*/
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000134 0, /*tp_as_number*/
135 0, /*tp_as_sequence*/
136 0, /*tp_as_mapping*/
137 0, /*tp_hash*/
138 0, /*tp_call*/
139 0, /*tp_str*/
140 0, /*tp_getattro*/
141 0, /*tp_setattro*/
142 0, /*tp_as_buffer*/
143 Py_TPFLAGS_DEFAULT, /*tp_flags*/
144 0, /*tp_doc*/
145 0, /*tp_traverse*/
146 0, /*tp_clear*/
147 0, /*tp_richcompare*/
148 0, /*tp_weaklistoffset*/
149 0, /*tp_iter*/
150 0, /*tp_iternext*/
151 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000152};
153
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000154static lockobject *
155newlockobject(void)
156{
157 lockobject *self;
158 self = PyObject_New(lockobject, &Locktype);
159 if (self == NULL)
160 return NULL;
161 self->lock_lock = PyThread_allocate_lock();
162 if (self->lock_lock == NULL) {
163 PyObject_Del(self);
164 self = NULL;
165 PyErr_SetString(ThreadError, "can't allocate lock");
166 }
167 return self;
168}
169
Jim Fultond15dc062004-07-14 19:11:50 +0000170/* Thread-local objects */
171
172#include "structmember.h"
173
174typedef struct {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000175 PyObject_HEAD
176 PyObject *key;
177 PyObject *args;
178 PyObject *kw;
179 PyObject *dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000180} localobject;
181
Jim Fultond15dc062004-07-14 19:11:50 +0000182static PyObject *
183local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
184{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000185 localobject *self;
186 PyObject *tdict;
Jim Fultond15dc062004-07-14 19:11:50 +0000187
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000188 if (type->tp_init == PyBaseObject_Type.tp_init
189 && ((args && PyObject_IsTrue(args))
190 || (kw && PyObject_IsTrue(kw)))) {
191 PyErr_SetString(PyExc_TypeError,
192 "Initialization arguments are not supported");
193 return NULL;
194 }
Jim Fultond15dc062004-07-14 19:11:50 +0000195
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000196 self = (localobject *)type->tp_alloc(type, 0);
197 if (self == NULL)
198 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000199
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000200 Py_XINCREF(args);
201 self->args = args;
202 Py_XINCREF(kw);
203 self->kw = kw;
204 self->dict = NULL; /* making sure */
Walter Dörwald4ee631e2007-06-20 14:55:01 +0000205 self->key = PyUnicode_FromFormat("thread.local.%p", self);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000206 if (self->key == NULL)
207 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000208
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000209 self->dict = PyDict_New();
210 if (self->dict == NULL)
211 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000212
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000213 tdict = PyThreadState_GetDict();
214 if (tdict == NULL) {
215 PyErr_SetString(PyExc_SystemError,
216 "Couldn't get thread-state dictionary");
217 goto err;
218 }
Jim Fultond15dc062004-07-14 19:11:50 +0000219
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000220 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
221 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000222
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000223 return (PyObject *)self;
224
225 err:
226 Py_DECREF(self);
227 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000228}
229
230static int
231local_traverse(localobject *self, visitproc visit, void *arg)
232{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000233 Py_VISIT(self->args);
234 Py_VISIT(self->kw);
235 Py_VISIT(self->dict);
Jim Fultond15dc062004-07-14 19:11:50 +0000236 return 0;
237}
238
239static int
240local_clear(localobject *self)
241{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000242 Py_CLEAR(self->key);
243 Py_CLEAR(self->args);
244 Py_CLEAR(self->kw);
245 Py_CLEAR(self->dict);
246 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000247}
248
249static void
250local_dealloc(localobject *self)
251{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000252 PyThreadState *tstate;
253 if (self->key
254 && (tstate = PyThreadState_Get())
255 && tstate->interp) {
256 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
257 tstate;
258 tstate = PyThreadState_Next(tstate))
259 if (tstate->dict &&
260 PyDict_GetItem(tstate->dict, self->key))
261 PyDict_DelItem(tstate->dict, self->key);
262 }
Jim Fultond15dc062004-07-14 19:11:50 +0000263
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000264 local_clear(self);
Christian Heimes90aa7642007-12-19 02:45:37 +0000265 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000266}
267
268static PyObject *
269_ldict(localobject *self)
270{
271 PyObject *tdict, *ldict;
272
273 tdict = PyThreadState_GetDict();
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000274 if (tdict == NULL) {
275 PyErr_SetString(PyExc_SystemError,
276 "Couldn't get thread-state dictionary");
277 return NULL;
278 }
Jim Fultond15dc062004-07-14 19:11:50 +0000279
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000280 ldict = PyDict_GetItem(tdict, self->key);
281 if (ldict == NULL) {
282 ldict = PyDict_New(); /* we own ldict */
Jim Fultond15dc062004-07-14 19:11:50 +0000283
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000284 if (ldict == NULL)
285 return NULL;
286 else {
287 int i = PyDict_SetItem(tdict, self->key, ldict);
Georg Brandlf3c4ad12006-03-08 12:24:33 +0000288 Py_DECREF(ldict); /* now ldict is borrowed */
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000289 if (i < 0)
290 return NULL;
291 }
Jim Fultond15dc062004-07-14 19:11:50 +0000292
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000293 Py_CLEAR(self->dict);
294 Py_INCREF(ldict);
295 self->dict = ldict; /* still borrowed */
Jim Fultond15dc062004-07-14 19:11:50 +0000296
Christian Heimes90aa7642007-12-19 02:45:37 +0000297 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
298 Py_TYPE(self)->tp_init((PyObject*)self,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000299 self->args, self->kw) < 0) {
300 /* we need to get rid of ldict from thread so
301 we create a new one the next time we do an attr
302 acces */
303 PyDict_DelItem(tdict, self->key);
304 return NULL;
305 }
306
307 }
Benjamin Peterson8a250ae2008-06-30 23:30:24 +0000308
309 /* The call to tp_init above may have caused another thread to run.
310 Install our ldict again. */
311 if (self->dict != ldict) {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000312 Py_CLEAR(self->dict);
313 Py_INCREF(ldict);
314 self->dict = ldict;
315 }
Jim Fultond15dc062004-07-14 19:11:50 +0000316
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000317 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000318}
319
Jim Fultond15dc062004-07-14 19:11:50 +0000320static int
321local_setattro(localobject *self, PyObject *name, PyObject *v)
322{
323 PyObject *ldict;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000324
325 ldict = _ldict(self);
326 if (ldict == NULL)
327 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000328
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000329 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000330}
331
332static PyObject *
333local_getdict(localobject *self, void *closure)
334{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000335 if (self->dict == NULL) {
336 PyErr_SetString(PyExc_AttributeError, "__dict__");
337 return NULL;
338 }
Jim Fultond15dc062004-07-14 19:11:50 +0000339
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000340 Py_INCREF(self->dict);
341 return self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000342}
343
344static PyGetSetDef local_getset[] = {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000345 {"__dict__", (getter)local_getdict, (setter)NULL,
346 "Local-data dictionary", NULL},
347 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000348};
349
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000350static PyObject *local_getattro(localobject *, PyObject *);
351
Jim Fultond15dc062004-07-14 19:11:50 +0000352static PyTypeObject localtype = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000353 PyVarObject_HEAD_INIT(NULL, 0)
Georg Brandl0a7ac7d2008-05-26 10:29:35 +0000354 /* tp_name */ "_thread._local",
Jim Fultond15dc062004-07-14 19:11:50 +0000355 /* tp_basicsize */ sizeof(localobject),
356 /* tp_itemsize */ 0,
357 /* tp_dealloc */ (destructor)local_dealloc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000358 /* tp_print */ 0,
359 /* tp_getattr */ 0,
360 /* tp_setattr */ 0,
361 /* tp_compare */ 0,
362 /* tp_repr */ 0,
Jim Fultond15dc062004-07-14 19:11:50 +0000363 /* tp_as_number */ 0,
364 /* tp_as_sequence */ 0,
365 /* tp_as_mapping */ 0,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000366 /* tp_hash */ 0,
367 /* tp_call */ 0,
368 /* tp_str */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000369 /* tp_getattro */ (getattrofunc)local_getattro,
370 /* tp_setattro */ (setattrofunc)local_setattro,
371 /* tp_as_buffer */ 0,
372 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Jim Fultond15dc062004-07-14 19:11:50 +0000373 /* tp_doc */ "Thread-local data",
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000374 /* tp_traverse */ (traverseproc)local_traverse,
375 /* tp_clear */ (inquiry)local_clear,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000376 /* tp_richcompare */ 0,
377 /* tp_weaklistoffset */ 0,
378 /* tp_iter */ 0,
379 /* tp_iternext */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000380 /* tp_methods */ 0,
381 /* tp_members */ 0,
382 /* tp_getset */ local_getset,
383 /* tp_base */ 0,
384 /* tp_dict */ 0, /* internal use */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000385 /* tp_descr_get */ 0,
386 /* tp_descr_set */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000387 /* tp_dictoffset */ offsetof(localobject, dict),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000388 /* tp_init */ 0,
389 /* tp_alloc */ 0,
390 /* tp_new */ local_new,
Jim Fultond15dc062004-07-14 19:11:50 +0000391 /* tp_free */ 0, /* Low-level free-mem routine */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000392 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000393};
394
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000395static PyObject *
396local_getattro(localobject *self, PyObject *name)
397{
398 PyObject *ldict, *value;
399
400 ldict = _ldict(self);
401 if (ldict == NULL)
402 return NULL;
403
Christian Heimes90aa7642007-12-19 02:45:37 +0000404 if (Py_TYPE(self) != &localtype)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000405 /* use generic lookup for subtypes */
406 return PyObject_GenericGetAttr((PyObject *)self, name);
407
408 /* Optimization: just look in dict ourselves */
409 value = PyDict_GetItem(ldict, name);
410 if (value == NULL)
411 /* Fall back on generic to get __class__ and __dict__ */
412 return PyObject_GenericGetAttr((PyObject *)self, name);
413
414 Py_INCREF(value);
415 return value;
416}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000417
418/* Module functions */
419
Guido van Rossuma027efa1997-05-05 20:56:21 +0000420struct bootstate {
421 PyInterpreterState *interp;
422 PyObject *func;
423 PyObject *args;
424 PyObject *keyw;
425};
426
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000427static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000428t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000429{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000430 struct bootstate *boot = (struct bootstate *) boot_raw;
Michael W. Hudson188d4362005-06-20 16:52:57 +0000431 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000432 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000433
Michael W. Hudson188d4362005-06-20 16:52:57 +0000434 tstate = PyThreadState_New(boot->interp);
435
436 PyEval_AcquireThread(tstate);
Guido van Rossuma027efa1997-05-05 20:56:21 +0000437 res = PyEval_CallObjectWithKeywords(
438 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000439 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000440 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000441 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000442 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000443 PyObject *file;
444 PySys_WriteStderr(
445 "Unhandled exception in thread started by ");
446 file = PySys_GetObject("stderr");
Christian Heimes2be03732007-11-15 02:26:46 +0000447 if (file != NULL && file != Py_None)
Guido van Rossum24ccca12003-04-29 19:44:05 +0000448 PyFile_WriteObject(boot->func, file, 0);
449 else
450 PyObject_Print(boot->func, stderr, 0);
451 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000452 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000453 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000454 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000455 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000456 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000457 Py_DECREF(boot->func);
458 Py_DECREF(boot->args);
459 Py_XDECREF(boot->keyw);
460 PyMem_DEL(boot_raw);
Michael W. Hudson188d4362005-06-20 16:52:57 +0000461 PyThreadState_Clear(tstate);
462 PyThreadState_DeleteCurrent();
Guido van Rossumbcc20741998-08-04 22:53:56 +0000463 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000464}
465
Barry Warsawd0c10421996-12-17 00:05:22 +0000466static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000467thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000468{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000469 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000470 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000471 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000472
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000473 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
474 &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000475 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000476 if (!PyCallable_Check(func)) {
477 PyErr_SetString(PyExc_TypeError,
478 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000479 return NULL;
480 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000481 if (!PyTuple_Check(args)) {
482 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000483 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000484 return NULL;
485 }
486 if (keyw != NULL && !PyDict_Check(keyw)) {
487 PyErr_SetString(PyExc_TypeError,
488 "optional 3rd arg must be a dictionary");
489 return NULL;
490 }
491 boot = PyMem_NEW(struct bootstate, 1);
492 if (boot == NULL)
493 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000494 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000495 boot->func = func;
496 boot->args = args;
497 boot->keyw = keyw;
498 Py_INCREF(func);
499 Py_INCREF(args);
500 Py_XINCREF(keyw);
501 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000502 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
503 if (ident == -1) {
Guido van Rossum54c273c2005-02-20 03:02:16 +0000504 PyErr_SetString(ThreadError, "can't start new thread");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000505 Py_DECREF(func);
506 Py_DECREF(args);
507 Py_XDECREF(keyw);
508 PyMem_DEL(boot);
509 return NULL;
510 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000511 return PyLong_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000512}
513
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000514PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000515"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000516(start_new() is an obsolete synonym)\n\
517\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000518Start a new thread and return its identifier. The thread will call the\n\
519function with positional arguments from the tuple args and keyword arguments\n\
520taken from the optional dictionary kwargs. The thread exits when the\n\
521function returns; the return value is ignored. The thread will also exit\n\
522when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000523printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000524
Barry Warsawd0c10421996-12-17 00:05:22 +0000525static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000526thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000527{
Barry Warsawd0c10421996-12-17 00:05:22 +0000528 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000529 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000530}
531
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000532PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000533"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000534(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000535\n\
536This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000537thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000538
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000539static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000540thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000541{
542 PyErr_SetInterrupt();
543 Py_INCREF(Py_None);
544 return Py_None;
545}
546
547PyDoc_STRVAR(interrupt_doc,
548"interrupt_main()\n\
549\n\
550Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000551A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000552);
553
Guido van Rossumb6775db1994-08-01 11:34:53 +0000554#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000555static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000556thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000557{
558 int sts;
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000559 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000560 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000561 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000562 for (;;) { } /* Should not be reached */
563}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000564#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000565
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000566static lockobject *newlockobject(void);
567
Barry Warsawd0c10421996-12-17 00:05:22 +0000568static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000569thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000570{
Barry Warsawd0c10421996-12-17 00:05:22 +0000571 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000572}
573
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000574PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000575"allocate_lock() -> lock object\n\
576(allocate() is an obsolete synonym)\n\
577\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000578Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000579
Barry Warsawd0c10421996-12-17 00:05:22 +0000580static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000581thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000582{
583 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000584 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000585 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000586 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000587 return NULL;
588 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000589 return PyLong_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000590}
591
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000592PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000593"get_ident() -> integer\n\
594\n\
595Return a non-zero integer that uniquely identifies the current thread\n\
596amongst other threads that exist simultaneously.\n\
597This may be used to identify per-thread resources.\n\
598Even though on some platforms threads identities may appear to be\n\
599allocated consecutive numbers starting at 1, this behavior should not\n\
600be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000601A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000602
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000603static PyObject *
604thread_stack_size(PyObject *self, PyObject *args)
605{
606 size_t old_size;
607 Py_ssize_t new_size = 0;
608 int rc;
609
610 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
611 return NULL;
612
613 if (new_size < 0) {
614 PyErr_SetString(PyExc_ValueError,
615 "size must be 0 or a positive value");
616 return NULL;
617 }
618
619 old_size = PyThread_get_stacksize();
620
621 rc = PyThread_set_stacksize((size_t) new_size);
622 if (rc == -1) {
623 PyErr_Format(PyExc_ValueError,
624 "size not valid: %zd bytes",
625 new_size);
626 return NULL;
627 }
628 if (rc == -2) {
629 PyErr_SetString(ThreadError,
630 "setting stack size not supported");
631 return NULL;
632 }
633
Christian Heimes217cfd12007-12-02 14:31:20 +0000634 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000635}
636
637PyDoc_STRVAR(stack_size_doc,
638"stack_size([size]) -> size\n\
639\n\
640Return the thread stack size used when creating new threads. The\n\
641optional size argument specifies the stack size (in bytes) to be used\n\
642for subsequently created threads, and must be 0 (use platform or\n\
643configured default) or a positive integer value of at least 32,768 (32k).\n\
644If changing the thread stack size is unsupported, a ThreadError\n\
645exception is raised. If the specified size is invalid, a ValueError\n\
646exception is raised, and the stack size is unmodified. 32k bytes\n\
647 currently the minimum supported stack size value to guarantee\n\
648sufficient stack space for the interpreter itself.\n\
649\n\
650Note that some platforms may have particular restrictions on values for\n\
651the stack size, such as requiring a minimum stack size larger than 32kB or\n\
652requiring allocation in multiples of the system memory page size\n\
653- platform documentation should be referred to for more information\n\
654(4kB pages are common; using multiples of 4096 for the stack size is\n\
655the suggested approach in the absence of more specific information).");
656
Barry Warsawd0c10421996-12-17 00:05:22 +0000657static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000658 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
659 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000660 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000661 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
662 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000663 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000664 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000665 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000666 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000667 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000668 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000669 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000670 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000671 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000672 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000673 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000674 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000675 METH_NOARGS, get_ident_doc},
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000676 {"stack_size", (PyCFunction)thread_stack_size,
677 METH_VARARGS,
678 stack_size_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000679#ifndef NO_EXIT_PROG
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000680 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
681 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000682#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000683 {NULL, NULL} /* sentinel */
684};
685
686
687/* Initialization function */
688
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000689PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000690"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000691The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000692
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000693PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000694"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000695call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000696\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000697acquire() -- lock the lock, possibly blocking until it can be obtained\n\
698release() -- unlock of the lock\n\
699locked() -- test whether the lock is currently locked\n\
700\n\
701A lock is not owned by the thread that locked it; another thread may\n\
702unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000703will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000704
Martin v. Löwis1a214512008-06-11 05:26:20 +0000705static struct PyModuleDef threadmodule = {
706 PyModuleDef_HEAD_INIT,
707 "_thread",
708 thread_doc,
709 -1,
710 thread_methods,
711 NULL,
712 NULL,
713 NULL,
714 NULL
715};
716
717
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000718PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000719PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000720{
Barry Warsawd0c10421996-12-17 00:05:22 +0000721 PyObject *m, *d;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000722
723 /* Initialize types: */
724 if (PyType_Ready(&localtype) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000725 return NULL;
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000726 if (PyType_Ready(&Locktype) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000727 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000728
729 /* Create the module and add the functions */
Martin v. Löwis1a214512008-06-11 05:26:20 +0000730 m = PyModule_Create(&threadmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000731 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000732 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000733
734 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000735 d = PyModule_GetDict(m);
Georg Brandl2067bfd2008-05-25 13:05:15 +0000736 ThreadError = PyErr_NewException("_thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000737 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000738 Locktype.tp_doc = lock_doc;
739 Py_INCREF(&Locktype);
740 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000741
Michael W. Hudson64e08142005-06-15 12:25:20 +0000742 Py_INCREF(&localtype);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000743 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000744 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000745
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000746 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000747 PyThread_init_thread();
Martin v. Löwis1a214512008-06-11 05:26:20 +0000748 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000749}