blob: 036619a8fbd08e473c65092230dab6574d9b8794 [file] [log] [blame]
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001
2/* Thread module */
3/* Interface to Sjoerd's portable C thread library */
4
Barry Warsawd0c10421996-12-17 00:05:22 +00005#include "Python.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +00006
Guido van Rossumb6775db1994-08-01 11:34:53 +00007#ifndef WITH_THREAD
Guido van Rossuma027efa1997-05-05 20:56:21 +00008#error "Error! The rest of Python is not compiled with thread support."
Neal Norwitz884baa12002-09-05 21:31:04 +00009#error "Rerun configure, adding a --with-threads option."
Guido van Rossuma027efa1997-05-05 20:56:21 +000010#error "Then run `make clean' followed by `make'."
Guido van Rossumb6775db1994-08-01 11:34:53 +000011#endif
12
Guido van Rossum49b56061998-10-01 20:42:43 +000013#include "pythread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000014
Barry Warsawd0c10421996-12-17 00:05:22 +000015static PyObject *ThreadError;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000016
17
18/* Lock objects */
19
20typedef struct {
Barry Warsawd0c10421996-12-17 00:05:22 +000021 PyObject_HEAD
Guido van Rossum65d5b571998-12-21 19:32:43 +000022 PyThread_type_lock lock_lock;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000023} lockobject;
24
Guido van Rossum1984f1e1992-08-04 12:41:02 +000025static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000026lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000027{
Neal Norwitzb5fdf0d2006-10-28 21:36:37 +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 = {
129 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000130 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000131 "thread.lock", /*tp_name*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000132 sizeof(lockobject), /*tp_size*/
133 0, /*tp_itemsize*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000134 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000135 (destructor)lock_dealloc, /*tp_dealloc*/
136 0, /*tp_print*/
137 (getattrfunc)lock_getattr, /*tp_getattr*/
138 0, /*tp_setattr*/
139 0, /*tp_compare*/
140 0, /*tp_repr*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000141};
142
Anthony Baxter5576b542006-04-12 04:08:46 +0000143static lockobject *
144newlockobject(void)
145{
146 lockobject *self;
147 self = PyObject_New(lockobject, &Locktype);
148 if (self == NULL)
149 return NULL;
150 self->lock_lock = PyThread_allocate_lock();
151 if (self->lock_lock == NULL) {
152 PyObject_Del(self);
153 self = NULL;
154 PyErr_SetString(ThreadError, "can't allocate lock");
155 }
156 return self;
157}
158
Jim Fultond15dc062004-07-14 19:11:50 +0000159/* Thread-local objects */
160
161#include "structmember.h"
162
163typedef struct {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000164 PyObject_HEAD
165 PyObject *key;
166 PyObject *args;
167 PyObject *kw;
168 PyObject *dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000169} localobject;
170
Jim Fultond15dc062004-07-14 19:11:50 +0000171static PyObject *
172local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
173{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000174 localobject *self;
175 PyObject *tdict;
Jim Fultond15dc062004-07-14 19:11:50 +0000176
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000177 if (type->tp_init == PyBaseObject_Type.tp_init
178 && ((args && PyObject_IsTrue(args))
179 || (kw && PyObject_IsTrue(kw)))) {
180 PyErr_SetString(PyExc_TypeError,
181 "Initialization arguments are not supported");
182 return NULL;
183 }
Jim Fultond15dc062004-07-14 19:11:50 +0000184
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000185 self = (localobject *)type->tp_alloc(type, 0);
186 if (self == NULL)
187 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000188
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000189 Py_XINCREF(args);
190 self->args = args;
191 Py_XINCREF(kw);
192 self->kw = kw;
193 self->dict = NULL; /* making sure */
194 self->key = PyString_FromFormat("thread.local.%p", self);
195 if (self->key == NULL)
196 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000197
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000198 self->dict = PyDict_New();
199 if (self->dict == NULL)
200 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000201
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000202 tdict = PyThreadState_GetDict();
203 if (tdict == NULL) {
204 PyErr_SetString(PyExc_SystemError,
205 "Couldn't get thread-state dictionary");
206 goto err;
207 }
Jim Fultond15dc062004-07-14 19:11:50 +0000208
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000209 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
210 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000211
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000212 return (PyObject *)self;
213
214 err:
215 Py_DECREF(self);
216 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000217}
218
219static int
220local_traverse(localobject *self, visitproc visit, void *arg)
221{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000222 Py_VISIT(self->args);
223 Py_VISIT(self->kw);
224 Py_VISIT(self->dict);
Jim Fultond15dc062004-07-14 19:11:50 +0000225 return 0;
226}
227
228static int
229local_clear(localobject *self)
230{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000231 Py_CLEAR(self->key);
232 Py_CLEAR(self->args);
233 Py_CLEAR(self->kw);
234 Py_CLEAR(self->dict);
235 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000236}
237
238static void
239local_dealloc(localobject *self)
240{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000241 PyThreadState *tstate;
242 if (self->key
243 && (tstate = PyThreadState_Get())
244 && tstate->interp) {
245 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
246 tstate;
247 tstate = PyThreadState_Next(tstate))
248 if (tstate->dict &&
249 PyDict_GetItem(tstate->dict, self->key))
250 PyDict_DelItem(tstate->dict, self->key);
251 }
Jim Fultond15dc062004-07-14 19:11:50 +0000252
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000253 local_clear(self);
254 self->ob_type->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000255}
256
257static PyObject *
258_ldict(localobject *self)
259{
260 PyObject *tdict, *ldict;
261
262 tdict = PyThreadState_GetDict();
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000263 if (tdict == NULL) {
264 PyErr_SetString(PyExc_SystemError,
265 "Couldn't get thread-state dictionary");
266 return NULL;
267 }
Jim Fultond15dc062004-07-14 19:11:50 +0000268
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000269 ldict = PyDict_GetItem(tdict, self->key);
270 if (ldict == NULL) {
271 ldict = PyDict_New(); /* we own ldict */
Jim Fultond15dc062004-07-14 19:11:50 +0000272
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000273 if (ldict == NULL)
274 return NULL;
275 else {
276 int i = PyDict_SetItem(tdict, self->key, ldict);
Georg Brandlf3c4ad12006-03-08 12:24:33 +0000277 Py_DECREF(ldict); /* now ldict is borrowed */
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000278 if (i < 0)
279 return NULL;
280 }
Jim Fultond15dc062004-07-14 19:11:50 +0000281
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000282 Py_CLEAR(self->dict);
283 Py_INCREF(ldict);
284 self->dict = ldict; /* still borrowed */
Jim Fultond15dc062004-07-14 19:11:50 +0000285
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000286 if (self->ob_type->tp_init != PyBaseObject_Type.tp_init &&
287 self->ob_type->tp_init((PyObject*)self,
288 self->args, self->kw) < 0) {
289 /* we need to get rid of ldict from thread so
290 we create a new one the next time we do an attr
291 acces */
292 PyDict_DelItem(tdict, self->key);
293 return NULL;
294 }
295
296 }
297 else if (self->dict != ldict) {
298 Py_CLEAR(self->dict);
299 Py_INCREF(ldict);
300 self->dict = ldict;
301 }
Jim Fultond15dc062004-07-14 19:11:50 +0000302
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000303 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000304}
305
Jim Fultond15dc062004-07-14 19:11:50 +0000306static int
307local_setattro(localobject *self, PyObject *name, PyObject *v)
308{
309 PyObject *ldict;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000310
311 ldict = _ldict(self);
312 if (ldict == NULL)
313 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000314
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000315 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000316}
317
318static PyObject *
319local_getdict(localobject *self, void *closure)
320{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000321 if (self->dict == NULL) {
322 PyErr_SetString(PyExc_AttributeError, "__dict__");
323 return NULL;
324 }
Jim Fultond15dc062004-07-14 19:11:50 +0000325
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000326 Py_INCREF(self->dict);
327 return self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000328}
329
330static PyGetSetDef local_getset[] = {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000331 {"__dict__", (getter)local_getdict, (setter)NULL,
332 "Local-data dictionary", NULL},
333 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000334};
335
Anthony Baxter5576b542006-04-12 04:08:46 +0000336static PyObject *local_getattro(localobject *, PyObject *);
337
Jim Fultond15dc062004-07-14 19:11:50 +0000338static PyTypeObject localtype = {
339 PyObject_HEAD_INIT(NULL)
340 /* ob_size */ 0,
341 /* tp_name */ "thread._local",
342 /* tp_basicsize */ sizeof(localobject),
343 /* tp_itemsize */ 0,
344 /* tp_dealloc */ (destructor)local_dealloc,
Georg Brandld37ac692006-03-30 11:58:57 +0000345 /* tp_print */ 0,
346 /* tp_getattr */ 0,
347 /* tp_setattr */ 0,
348 /* tp_compare */ 0,
349 /* tp_repr */ 0,
Jim Fultond15dc062004-07-14 19:11:50 +0000350 /* tp_as_number */ 0,
351 /* tp_as_sequence */ 0,
352 /* tp_as_mapping */ 0,
Georg Brandld37ac692006-03-30 11:58:57 +0000353 /* tp_hash */ 0,
354 /* tp_call */ 0,
355 /* tp_str */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000356 /* tp_getattro */ (getattrofunc)local_getattro,
357 /* tp_setattro */ (setattrofunc)local_setattro,
358 /* tp_as_buffer */ 0,
359 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Jim Fultond15dc062004-07-14 19:11:50 +0000360 /* tp_doc */ "Thread-local data",
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000361 /* tp_traverse */ (traverseproc)local_traverse,
362 /* tp_clear */ (inquiry)local_clear,
Georg Brandld37ac692006-03-30 11:58:57 +0000363 /* tp_richcompare */ 0,
364 /* tp_weaklistoffset */ 0,
365 /* tp_iter */ 0,
366 /* tp_iternext */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000367 /* tp_methods */ 0,
368 /* tp_members */ 0,
369 /* tp_getset */ local_getset,
370 /* tp_base */ 0,
371 /* tp_dict */ 0, /* internal use */
Georg Brandld37ac692006-03-30 11:58:57 +0000372 /* tp_descr_get */ 0,
373 /* tp_descr_set */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000374 /* tp_dictoffset */ offsetof(localobject, dict),
Georg Brandld37ac692006-03-30 11:58:57 +0000375 /* tp_init */ 0,
376 /* tp_alloc */ 0,
377 /* tp_new */ local_new,
Jim Fultond15dc062004-07-14 19:11:50 +0000378 /* tp_free */ 0, /* Low-level free-mem routine */
Georg Brandld37ac692006-03-30 11:58:57 +0000379 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000380};
381
Anthony Baxter5576b542006-04-12 04:08:46 +0000382static PyObject *
383local_getattro(localobject *self, PyObject *name)
384{
385 PyObject *ldict, *value;
386
387 ldict = _ldict(self);
388 if (ldict == NULL)
389 return NULL;
390
391 if (self->ob_type != &localtype)
392 /* use generic lookup for subtypes */
393 return PyObject_GenericGetAttr((PyObject *)self, name);
394
395 /* Optimization: just look in dict ourselves */
396 value = PyDict_GetItem(ldict, name);
397 if (value == NULL)
398 /* Fall back on generic to get __class__ and __dict__ */
399 return PyObject_GenericGetAttr((PyObject *)self, name);
400
401 Py_INCREF(value);
402 return value;
403}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000404
405/* Module functions */
406
Guido van Rossuma027efa1997-05-05 20:56:21 +0000407struct bootstate {
408 PyInterpreterState *interp;
409 PyObject *func;
410 PyObject *args;
411 PyObject *keyw;
412};
413
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000414static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000415t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000416{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000417 struct bootstate *boot = (struct bootstate *) boot_raw;
Michael W. Hudson188d4362005-06-20 16:52:57 +0000418 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000419 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000420
Michael W. Hudson188d4362005-06-20 16:52:57 +0000421 tstate = PyThreadState_New(boot->interp);
422
423 PyEval_AcquireThread(tstate);
Guido van Rossuma027efa1997-05-05 20:56:21 +0000424 res = PyEval_CallObjectWithKeywords(
425 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000426 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000427 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000428 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000429 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000430 PyObject *file;
431 PySys_WriteStderr(
432 "Unhandled exception in thread started by ");
433 file = PySys_GetObject("stderr");
434 if (file)
435 PyFile_WriteObject(boot->func, file, 0);
436 else
437 PyObject_Print(boot->func, stderr, 0);
438 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000439 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000440 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000441 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000442 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000443 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000444 Py_DECREF(boot->func);
445 Py_DECREF(boot->args);
446 Py_XDECREF(boot->keyw);
447 PyMem_DEL(boot_raw);
Michael W. Hudson188d4362005-06-20 16:52:57 +0000448 PyThreadState_Clear(tstate);
449 PyThreadState_DeleteCurrent();
Guido van Rossumbcc20741998-08-04 22:53:56 +0000450 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000451}
452
Barry Warsawd0c10421996-12-17 00:05:22 +0000453static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000454thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000455{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000456 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000457 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000458 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000459
Georg Brandl96a8c392006-05-29 21:04:52 +0000460 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
461 &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000462 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000463 if (!PyCallable_Check(func)) {
464 PyErr_SetString(PyExc_TypeError,
465 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000466 return NULL;
467 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000468 if (!PyTuple_Check(args)) {
469 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000470 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000471 return NULL;
472 }
473 if (keyw != NULL && !PyDict_Check(keyw)) {
474 PyErr_SetString(PyExc_TypeError,
475 "optional 3rd arg must be a dictionary");
476 return NULL;
477 }
478 boot = PyMem_NEW(struct bootstate, 1);
479 if (boot == NULL)
480 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000481 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000482 boot->func = func;
483 boot->args = args;
484 boot->keyw = keyw;
485 Py_INCREF(func);
486 Py_INCREF(args);
487 Py_XINCREF(keyw);
488 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000489 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
490 if (ident == -1) {
Guido van Rossum54c273c2005-02-20 03:02:16 +0000491 PyErr_SetString(ThreadError, "can't start new thread");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000492 Py_DECREF(func);
493 Py_DECREF(args);
494 Py_XDECREF(keyw);
495 PyMem_DEL(boot);
496 return NULL;
497 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000498 return PyInt_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000499}
500
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000501PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000502"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000503(start_new() is an obsolete synonym)\n\
504\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000505Start a new thread and return its identifier. The thread will call the\n\
506function with positional arguments from the tuple args and keyword arguments\n\
507taken from the optional dictionary kwargs. The thread exits when the\n\
508function returns; the return value is ignored. The thread will also exit\n\
509when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000510printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000511
Barry Warsawd0c10421996-12-17 00:05:22 +0000512static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000513thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000514{
Barry Warsawd0c10421996-12-17 00:05:22 +0000515 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000516 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000517}
518
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000519PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000520"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000521(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000522\n\
523This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000524thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000525
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000526static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000527thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000528{
529 PyErr_SetInterrupt();
530 Py_INCREF(Py_None);
531 return Py_None;
532}
533
534PyDoc_STRVAR(interrupt_doc,
535"interrupt_main()\n\
536\n\
537Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000538A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000539);
540
Guido van Rossumb6775db1994-08-01 11:34:53 +0000541#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000542static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000543thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000544{
545 int sts;
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000546 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000547 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000548 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000549 for (;;) { } /* Should not be reached */
550}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000551#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000552
Anthony Baxter5576b542006-04-12 04:08:46 +0000553static lockobject *newlockobject(void);
554
Barry Warsawd0c10421996-12-17 00:05:22 +0000555static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000556thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000557{
Barry Warsawd0c10421996-12-17 00:05:22 +0000558 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000559}
560
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000561PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000562"allocate_lock() -> lock object\n\
563(allocate() is an obsolete synonym)\n\
564\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000565Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000566
Barry Warsawd0c10421996-12-17 00:05:22 +0000567static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000568thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000569{
570 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000571 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000572 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000573 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000574 return NULL;
575 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000576 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000577}
578
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000579PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000580"get_ident() -> integer\n\
581\n\
582Return a non-zero integer that uniquely identifies the current thread\n\
583amongst other threads that exist simultaneously.\n\
584This may be used to identify per-thread resources.\n\
585Even though on some platforms threads identities may appear to be\n\
586allocated consecutive numbers starting at 1, this behavior should not\n\
587be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000588A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000589
Andrew MacIntyre92913322006-06-13 15:04:24 +0000590static PyObject *
591thread_stack_size(PyObject *self, PyObject *args)
592{
593 size_t old_size;
594 Py_ssize_t new_size = 0;
Andrew MacIntyre92913322006-06-13 15:04:24 +0000595 int rc;
596
597 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
598 return NULL;
599
600 if (new_size < 0) {
601 PyErr_SetString(PyExc_ValueError,
602 "size must be 0 or a positive value");
603 return NULL;
604 }
605
606 old_size = PyThread_get_stacksize();
607
608 rc = PyThread_set_stacksize((size_t) new_size);
609 if (rc == -1) {
610 PyErr_Format(PyExc_ValueError,
611 "size not valid: %zd bytes",
612 new_size);
613 return NULL;
614 }
615 if (rc == -2) {
616 PyErr_SetString(ThreadError,
617 "setting stack size not supported");
618 return NULL;
619 }
620
621 return PyInt_FromSsize_t((Py_ssize_t) old_size);
622}
623
624PyDoc_STRVAR(stack_size_doc,
625"stack_size([size]) -> size\n\
626\n\
627Return the thread stack size used when creating new threads. The\n\
628optional size argument specifies the stack size (in bytes) to be used\n\
629for subsequently created threads, and must be 0 (use platform or\n\
630configured default) or a positive integer value of at least 32,768 (32k).\n\
631If changing the thread stack size is unsupported, a ThreadError\n\
632exception is raised. If the specified size is invalid, a ValueError\n\
633exception is raised, and the stack size is unmodified. 32k bytes\n\
634 currently the minimum supported stack size value to guarantee\n\
635sufficient stack space for the interpreter itself.\n\
636\n\
637Note that some platforms may have particular restrictions on values for\n\
638the stack size, such as requiring a minimum stack size larger than 32kB or\n\
639requiring allocation in multiples of the system memory page size\n\
640- platform documentation should be referred to for more information\n\
641(4kB pages are common; using multiples of 4096 for the stack size is\n\
642the suggested approach in the absence of more specific information).");
643
Barry Warsawd0c10421996-12-17 00:05:22 +0000644static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000645 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
646 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000647 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000648 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
649 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000650 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000651 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000652 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000653 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000654 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000655 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000656 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000657 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000658 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000659 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000660 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000661 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000662 METH_NOARGS, get_ident_doc},
Andrew MacIntyre92913322006-06-13 15:04:24 +0000663 {"stack_size", (PyCFunction)thread_stack_size,
664 METH_VARARGS,
665 stack_size_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000666#ifndef NO_EXIT_PROG
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000667 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
668 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000669#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000670 {NULL, NULL} /* sentinel */
671};
672
673
674/* Initialization function */
675
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000676PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000677"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000678The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000679
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000680PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000681"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000682call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000683\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000684acquire() -- lock the lock, possibly blocking until it can be obtained\n\
685release() -- unlock of the lock\n\
686locked() -- test whether the lock is currently locked\n\
687\n\
688A lock is not owned by the thread that locked it; another thread may\n\
689unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000690will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000691
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000692PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000693initthread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000694{
Barry Warsawd0c10421996-12-17 00:05:22 +0000695 PyObject *m, *d;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000696
697 /* Initialize types: */
698 if (PyType_Ready(&localtype) < 0)
699 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000700
701 /* Create the module and add the functions */
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000702 m = Py_InitModule3("thread", thread_methods, thread_doc);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000703 if (m == NULL)
704 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000705
706 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000707 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000708 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000709 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000710 Locktype.tp_doc = lock_doc;
711 Py_INCREF(&Locktype);
712 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000713
Michael W. Hudson64e08142005-06-15 12:25:20 +0000714 Py_INCREF(&localtype);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000715 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
716 return;
Jim Fultond15dc062004-07-14 19:11:50 +0000717
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000718 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000719 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000720}