blob: 83313df787e3703ceb2a088b85e9312fb2673db0 [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{
28 /* Unlock the lock so it's safe to free it */
Guido van Rossum65d5b571998-12-21 19:32:43 +000029 PyThread_acquire_lock(self->lock_lock, 0);
30 PyThread_release_lock(self->lock_lock);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000031
Guido van Rossum65d5b571998-12-21 19:32:43 +000032 PyThread_free_lock(self->lock_lock);
Guido van Rossumb18618d2000-05-03 23:44:39 +000033 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000034}
35
Barry Warsawd0c10421996-12-17 00:05:22 +000036static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000037lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000038{
Neal Norwitzba3a16c2002-03-31 15:27:00 +000039 int i = 1;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000040
Neal Norwitzba3a16c2002-03-31 15:27:00 +000041 if (!PyArg_ParseTuple(args, "|i:acquire", &i))
42 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000043
Barry Warsawd0c10421996-12-17 00:05:22 +000044 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +000045 i = PyThread_acquire_lock(self->lock_lock, i);
Barry Warsawd0c10421996-12-17 00:05:22 +000046 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +000047
Andrew M. Kuchlinga43ece92005-06-02 17:07:11 +000048 return PyBool_FromLong((long)i);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000049}
50
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000051PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000052"acquire([wait]) -> None or bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000053(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000054\n\
55Lock the lock. Without argument, this blocks if the lock is already\n\
56locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000057the lock, and return None once the lock is acquired.\n\
58With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000059and the return value reflects whether the lock is acquired.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000060The blocking operation is not interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000061
Barry Warsawd0c10421996-12-17 00:05:22 +000062static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000063lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000064{
Guido van Rossum1984f1e1992-08-04 12:41:02 +000065 /* Sanity check: the lock must be locked */
Guido van Rossum65d5b571998-12-21 19:32:43 +000066 if (PyThread_acquire_lock(self->lock_lock, 0)) {
67 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000068 PyErr_SetString(ThreadError, "release unlocked lock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +000069 return NULL;
70 }
71
Guido van Rossum65d5b571998-12-21 19:32:43 +000072 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000073 Py_INCREF(Py_None);
74 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000075}
76
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000077PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +000078"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000079(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000080\n\
81Release the lock, allowing another thread that is blocked waiting for\n\
82the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000083but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000084
Barry Warsawd0c10421996-12-17 00:05:22 +000085static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000086lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000087{
Guido van Rossum65d5b571998-12-21 19:32:43 +000088 if (PyThread_acquire_lock(self->lock_lock, 0)) {
89 PyThread_release_lock(self->lock_lock);
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000090 return PyBool_FromLong(0L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000091 }
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000092 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000093}
94
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000095PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000096"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000097(locked_lock() is an obsolete synonym)\n\
98\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000099Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000100
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000101static PyObject *
102lock_context(lockobject *self)
103{
104 Py_INCREF(self);
105 return (PyObject *)self;
106}
107
Barry Warsawd0c10421996-12-17 00:05:22 +0000108static PyMethodDef lock_methods[] = {
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000109 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000110 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000111 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000112 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000113 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000114 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000115 {"release", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000116 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000117 {"locked_lock", (PyCFunction)lock_locked_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000118 METH_NOARGS, locked_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000119 {"locked", (PyCFunction)lock_locked_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000120 METH_NOARGS, locked_doc},
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000121 {"__context__", (PyCFunction)lock_context,
122 METH_NOARGS, PyDoc_STR("__context__() -> self.")},
123 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
124 METH_VARARGS, acquire_doc},
Guido van Rossumf6694362006-03-10 02:28:35 +0000125 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
126 METH_VARARGS, release_doc},
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000127 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000128};
129
Barry Warsawd0c10421996-12-17 00:05:22 +0000130static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000131lock_getattr(lockobject *self, char *name)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000132{
Barry Warsawd0c10421996-12-17 00:05:22 +0000133 return Py_FindMethod(lock_methods, (PyObject *)self, name);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000134}
135
Barry Warsawd0c10421996-12-17 00:05:22 +0000136static PyTypeObject Locktype = {
137 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000138 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000139 "thread.lock", /*tp_name*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000140 sizeof(lockobject), /*tp_size*/
141 0, /*tp_itemsize*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000142 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000143 (destructor)lock_dealloc, /*tp_dealloc*/
144 0, /*tp_print*/
145 (getattrfunc)lock_getattr, /*tp_getattr*/
146 0, /*tp_setattr*/
147 0, /*tp_compare*/
148 0, /*tp_repr*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000149};
150
Anthony Baxter5576b542006-04-12 04:08:46 +0000151static lockobject *
152newlockobject(void)
153{
154 lockobject *self;
155 self = PyObject_New(lockobject, &Locktype);
156 if (self == NULL)
157 return NULL;
158 self->lock_lock = PyThread_allocate_lock();
159 if (self->lock_lock == NULL) {
160 PyObject_Del(self);
161 self = NULL;
162 PyErr_SetString(ThreadError, "can't allocate lock");
163 }
164 return self;
165}
166
Jim Fultond15dc062004-07-14 19:11:50 +0000167/* Thread-local objects */
168
169#include "structmember.h"
170
171typedef struct {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000172 PyObject_HEAD
173 PyObject *key;
174 PyObject *args;
175 PyObject *kw;
176 PyObject *dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000177} localobject;
178
Jim Fultond15dc062004-07-14 19:11:50 +0000179static PyObject *
180local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
181{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000182 localobject *self;
183 PyObject *tdict;
Jim Fultond15dc062004-07-14 19:11:50 +0000184
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000185 if (type->tp_init == PyBaseObject_Type.tp_init
186 && ((args && PyObject_IsTrue(args))
187 || (kw && PyObject_IsTrue(kw)))) {
188 PyErr_SetString(PyExc_TypeError,
189 "Initialization arguments are not supported");
190 return NULL;
191 }
Jim Fultond15dc062004-07-14 19:11:50 +0000192
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000193 self = (localobject *)type->tp_alloc(type, 0);
194 if (self == NULL)
195 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000196
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000197 Py_XINCREF(args);
198 self->args = args;
199 Py_XINCREF(kw);
200 self->kw = kw;
201 self->dict = NULL; /* making sure */
202 self->key = PyString_FromFormat("thread.local.%p", self);
203 if (self->key == NULL)
204 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000205
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000206 self->dict = PyDict_New();
207 if (self->dict == NULL)
208 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000209
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000210 tdict = PyThreadState_GetDict();
211 if (tdict == NULL) {
212 PyErr_SetString(PyExc_SystemError,
213 "Couldn't get thread-state dictionary");
214 goto err;
215 }
Jim Fultond15dc062004-07-14 19:11:50 +0000216
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000217 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
218 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000219
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000220 return (PyObject *)self;
221
222 err:
223 Py_DECREF(self);
224 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000225}
226
227static int
228local_traverse(localobject *self, visitproc visit, void *arg)
229{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000230 Py_VISIT(self->args);
231 Py_VISIT(self->kw);
232 Py_VISIT(self->dict);
Jim Fultond15dc062004-07-14 19:11:50 +0000233 return 0;
234}
235
236static int
237local_clear(localobject *self)
238{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000239 Py_CLEAR(self->key);
240 Py_CLEAR(self->args);
241 Py_CLEAR(self->kw);
242 Py_CLEAR(self->dict);
243 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000244}
245
246static void
247local_dealloc(localobject *self)
248{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000249 PyThreadState *tstate;
250 if (self->key
251 && (tstate = PyThreadState_Get())
252 && tstate->interp) {
253 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
254 tstate;
255 tstate = PyThreadState_Next(tstate))
256 if (tstate->dict &&
257 PyDict_GetItem(tstate->dict, self->key))
258 PyDict_DelItem(tstate->dict, self->key);
259 }
Jim Fultond15dc062004-07-14 19:11:50 +0000260
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000261 local_clear(self);
262 self->ob_type->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000263}
264
265static PyObject *
266_ldict(localobject *self)
267{
268 PyObject *tdict, *ldict;
269
270 tdict = PyThreadState_GetDict();
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000271 if (tdict == NULL) {
272 PyErr_SetString(PyExc_SystemError,
273 "Couldn't get thread-state dictionary");
274 return NULL;
275 }
Jim Fultond15dc062004-07-14 19:11:50 +0000276
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000277 ldict = PyDict_GetItem(tdict, self->key);
278 if (ldict == NULL) {
279 ldict = PyDict_New(); /* we own ldict */
Jim Fultond15dc062004-07-14 19:11:50 +0000280
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000281 if (ldict == NULL)
282 return NULL;
283 else {
284 int i = PyDict_SetItem(tdict, self->key, ldict);
Georg Brandlf3c4ad12006-03-08 12:24:33 +0000285 Py_DECREF(ldict); /* now ldict is borrowed */
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000286 if (i < 0)
287 return NULL;
288 }
Jim Fultond15dc062004-07-14 19:11:50 +0000289
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000290 Py_CLEAR(self->dict);
291 Py_INCREF(ldict);
292 self->dict = ldict; /* still borrowed */
Jim Fultond15dc062004-07-14 19:11:50 +0000293
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000294 if (self->ob_type->tp_init != PyBaseObject_Type.tp_init &&
295 self->ob_type->tp_init((PyObject*)self,
296 self->args, self->kw) < 0) {
297 /* we need to get rid of ldict from thread so
298 we create a new one the next time we do an attr
299 acces */
300 PyDict_DelItem(tdict, self->key);
301 return NULL;
302 }
303
304 }
305 else if (self->dict != ldict) {
306 Py_CLEAR(self->dict);
307 Py_INCREF(ldict);
308 self->dict = ldict;
309 }
Jim Fultond15dc062004-07-14 19:11:50 +0000310
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000311 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000312}
313
Jim Fultond15dc062004-07-14 19:11:50 +0000314static int
315local_setattro(localobject *self, PyObject *name, PyObject *v)
316{
317 PyObject *ldict;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000318
319 ldict = _ldict(self);
320 if (ldict == NULL)
321 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000322
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000323 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000324}
325
326static PyObject *
327local_getdict(localobject *self, void *closure)
328{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000329 if (self->dict == NULL) {
330 PyErr_SetString(PyExc_AttributeError, "__dict__");
331 return NULL;
332 }
Jim Fultond15dc062004-07-14 19:11:50 +0000333
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000334 Py_INCREF(self->dict);
335 return self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000336}
337
338static PyGetSetDef local_getset[] = {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000339 {"__dict__", (getter)local_getdict, (setter)NULL,
340 "Local-data dictionary", NULL},
341 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000342};
343
Anthony Baxter5576b542006-04-12 04:08:46 +0000344static PyObject *local_getattro(localobject *, PyObject *);
345
Jim Fultond15dc062004-07-14 19:11:50 +0000346static PyTypeObject localtype = {
347 PyObject_HEAD_INIT(NULL)
348 /* ob_size */ 0,
349 /* tp_name */ "thread._local",
350 /* tp_basicsize */ sizeof(localobject),
351 /* tp_itemsize */ 0,
352 /* tp_dealloc */ (destructor)local_dealloc,
Georg Brandld37ac692006-03-30 11:58:57 +0000353 /* tp_print */ 0,
354 /* tp_getattr */ 0,
355 /* tp_setattr */ 0,
356 /* tp_compare */ 0,
357 /* tp_repr */ 0,
Jim Fultond15dc062004-07-14 19:11:50 +0000358 /* tp_as_number */ 0,
359 /* tp_as_sequence */ 0,
360 /* tp_as_mapping */ 0,
Georg Brandld37ac692006-03-30 11:58:57 +0000361 /* tp_hash */ 0,
362 /* tp_call */ 0,
363 /* tp_str */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000364 /* tp_getattro */ (getattrofunc)local_getattro,
365 /* tp_setattro */ (setattrofunc)local_setattro,
366 /* tp_as_buffer */ 0,
367 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Jim Fultond15dc062004-07-14 19:11:50 +0000368 /* tp_doc */ "Thread-local data",
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000369 /* tp_traverse */ (traverseproc)local_traverse,
370 /* tp_clear */ (inquiry)local_clear,
Georg Brandld37ac692006-03-30 11:58:57 +0000371 /* tp_richcompare */ 0,
372 /* tp_weaklistoffset */ 0,
373 /* tp_iter */ 0,
374 /* tp_iternext */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000375 /* tp_methods */ 0,
376 /* tp_members */ 0,
377 /* tp_getset */ local_getset,
378 /* tp_base */ 0,
379 /* tp_dict */ 0, /* internal use */
Georg Brandld37ac692006-03-30 11:58:57 +0000380 /* tp_descr_get */ 0,
381 /* tp_descr_set */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000382 /* tp_dictoffset */ offsetof(localobject, dict),
Georg Brandld37ac692006-03-30 11:58:57 +0000383 /* tp_init */ 0,
384 /* tp_alloc */ 0,
385 /* tp_new */ local_new,
Jim Fultond15dc062004-07-14 19:11:50 +0000386 /* tp_free */ 0, /* Low-level free-mem routine */
Georg Brandld37ac692006-03-30 11:58:57 +0000387 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000388};
389
Anthony Baxter5576b542006-04-12 04:08:46 +0000390static PyObject *
391local_getattro(localobject *self, PyObject *name)
392{
393 PyObject *ldict, *value;
394
395 ldict = _ldict(self);
396 if (ldict == NULL)
397 return NULL;
398
399 if (self->ob_type != &localtype)
400 /* use generic lookup for subtypes */
401 return PyObject_GenericGetAttr((PyObject *)self, name);
402
403 /* Optimization: just look in dict ourselves */
404 value = PyDict_GetItem(ldict, name);
405 if (value == NULL)
406 /* Fall back on generic to get __class__ and __dict__ */
407 return PyObject_GenericGetAttr((PyObject *)self, name);
408
409 Py_INCREF(value);
410 return value;
411}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000412
413/* Module functions */
414
Guido van Rossuma027efa1997-05-05 20:56:21 +0000415struct bootstate {
416 PyInterpreterState *interp;
417 PyObject *func;
418 PyObject *args;
419 PyObject *keyw;
420};
421
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000422static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000423t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000424{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000425 struct bootstate *boot = (struct bootstate *) boot_raw;
Michael W. Hudson188d4362005-06-20 16:52:57 +0000426 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000427 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000428
Michael W. Hudson188d4362005-06-20 16:52:57 +0000429 tstate = PyThreadState_New(boot->interp);
430
431 PyEval_AcquireThread(tstate);
Guido van Rossuma027efa1997-05-05 20:56:21 +0000432 res = PyEval_CallObjectWithKeywords(
433 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000434 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000435 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000436 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000437 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000438 PyObject *file;
439 PySys_WriteStderr(
440 "Unhandled exception in thread started by ");
441 file = PySys_GetObject("stderr");
442 if (file)
443 PyFile_WriteObject(boot->func, file, 0);
444 else
445 PyObject_Print(boot->func, stderr, 0);
446 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000447 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000448 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000449 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000450 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000451 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000452 Py_DECREF(boot->func);
453 Py_DECREF(boot->args);
454 Py_XDECREF(boot->keyw);
455 PyMem_DEL(boot_raw);
Michael W. Hudson188d4362005-06-20 16:52:57 +0000456 PyThreadState_Clear(tstate);
457 PyThreadState_DeleteCurrent();
Guido van Rossumbcc20741998-08-04 22:53:56 +0000458 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000459}
460
Barry Warsawd0c10421996-12-17 00:05:22 +0000461static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000462thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000463{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000464 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000465 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000466 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000467
Guido van Rossum43713e52000-02-29 13:59:29 +0000468 if (!PyArg_ParseTuple(fargs, "OO|O:start_new_thread", &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000469 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000470 if (!PyCallable_Check(func)) {
471 PyErr_SetString(PyExc_TypeError,
472 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000473 return NULL;
474 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000475 if (!PyTuple_Check(args)) {
476 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000477 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000478 return NULL;
479 }
480 if (keyw != NULL && !PyDict_Check(keyw)) {
481 PyErr_SetString(PyExc_TypeError,
482 "optional 3rd arg must be a dictionary");
483 return NULL;
484 }
485 boot = PyMem_NEW(struct bootstate, 1);
486 if (boot == NULL)
487 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000488 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000489 boot->func = func;
490 boot->args = args;
491 boot->keyw = keyw;
492 Py_INCREF(func);
493 Py_INCREF(args);
494 Py_XINCREF(keyw);
495 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000496 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
497 if (ident == -1) {
Guido van Rossum54c273c2005-02-20 03:02:16 +0000498 PyErr_SetString(ThreadError, "can't start new thread");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000499 Py_DECREF(func);
500 Py_DECREF(args);
501 Py_XDECREF(keyw);
502 PyMem_DEL(boot);
503 return NULL;
504 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000505 return PyInt_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000506}
507
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000508PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000509"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000510(start_new() is an obsolete synonym)\n\
511\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000512Start a new thread and return its identifier. The thread will call the\n\
513function with positional arguments from the tuple args and keyword arguments\n\
514taken from the optional dictionary kwargs. The thread exits when the\n\
515function returns; the return value is ignored. The thread will also exit\n\
516when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000517printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000518
Barry Warsawd0c10421996-12-17 00:05:22 +0000519static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000520thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000521{
Barry Warsawd0c10421996-12-17 00:05:22 +0000522 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000523 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000524}
525
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000526PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000527"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000528(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000529\n\
530This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000531thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000532
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000533static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000534thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000535{
536 PyErr_SetInterrupt();
537 Py_INCREF(Py_None);
538 return Py_None;
539}
540
541PyDoc_STRVAR(interrupt_doc,
542"interrupt_main()\n\
543\n\
544Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000545A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000546);
547
Guido van Rossumb6775db1994-08-01 11:34:53 +0000548#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000549static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000550thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000551{
552 int sts;
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000553 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000554 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000555 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000556 for (;;) { } /* Should not be reached */
557}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000558#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000559
Anthony Baxter5576b542006-04-12 04:08:46 +0000560static lockobject *newlockobject(void);
561
Barry Warsawd0c10421996-12-17 00:05:22 +0000562static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000563thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000564{
Barry Warsawd0c10421996-12-17 00:05:22 +0000565 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000566}
567
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000568PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000569"allocate_lock() -> lock object\n\
570(allocate() is an obsolete synonym)\n\
571\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000572Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000573
Barry Warsawd0c10421996-12-17 00:05:22 +0000574static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000575thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000576{
577 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000578 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000579 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000580 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000581 return NULL;
582 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000583 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000584}
585
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000586PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000587"get_ident() -> integer\n\
588\n\
589Return a non-zero integer that uniquely identifies the current thread\n\
590amongst other threads that exist simultaneously.\n\
591This may be used to identify per-thread resources.\n\
592Even though on some platforms threads identities may appear to be\n\
593allocated consecutive numbers starting at 1, this behavior should not\n\
594be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000595A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000596
Barry Warsawd0c10421996-12-17 00:05:22 +0000597static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000598 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
599 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000600 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000601 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
602 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000603 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000604 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000605 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000606 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000607 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000608 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000609 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000610 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000611 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000612 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000613 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000614 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000615 METH_NOARGS, get_ident_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000616#ifndef NO_EXIT_PROG
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000617 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
618 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000619#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000620 {NULL, NULL} /* sentinel */
621};
622
623
624/* Initialization function */
625
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000626PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000627"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000628The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000629
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000630PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000631"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000632call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000633\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000634acquire() -- lock the lock, possibly blocking until it can be obtained\n\
635release() -- unlock of the lock\n\
636locked() -- test whether the lock is currently locked\n\
637\n\
638A lock is not owned by the thread that locked it; another thread may\n\
639unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000640will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000641
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000642PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000643initthread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000644{
Barry Warsawd0c10421996-12-17 00:05:22 +0000645 PyObject *m, *d;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000646
647 /* Initialize types: */
648 if (PyType_Ready(&localtype) < 0)
649 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000650
651 /* Create the module and add the functions */
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000652 m = Py_InitModule3("thread", thread_methods, thread_doc);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000653 if (m == NULL)
654 return;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000655
656 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000657 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000658 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000659 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000660 Locktype.tp_doc = lock_doc;
661 Py_INCREF(&Locktype);
662 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000663
Michael W. Hudson64e08142005-06-15 12:25:20 +0000664 Py_INCREF(&localtype);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000665 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
666 return;
Jim Fultond15dc062004-07-14 19:11:50 +0000667
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000668 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000669 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000670}