blob: 58aa231ceb9307a7c9425132218bb11de9a0d54e [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"
Benjamin Petersonbec4d572009-10-10 01:16:07 +00006#include "structmember.h" /* offsetof */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00007
Guido van Rossumb6775db1994-08-01 11:34:53 +00008#ifndef WITH_THREAD
Guido van Rossuma027efa1997-05-05 20:56:21 +00009#error "Error! The rest of Python is not compiled with thread support."
Neal Norwitz884baa12002-09-05 21:31:04 +000010#error "Rerun configure, adding a --with-threads option."
Guido van Rossuma027efa1997-05-05 20:56:21 +000011#error "Then run `make clean' followed by `make'."
Guido van Rossumb6775db1994-08-01 11:34:53 +000012#endif
13
Guido van Rossum49b56061998-10-01 20:42:43 +000014#include "pythread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000015
Barry Warsawd0c10421996-12-17 00:05:22 +000016static PyObject *ThreadError;
Antoine Pitrou65c9c642009-10-30 17:25:12 +000017static long nb_threads = 0;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000018
19/* Lock objects */
20
21typedef struct {
Barry Warsawd0c10421996-12-17 00:05:22 +000022 PyObject_HEAD
Guido van Rossum65d5b571998-12-21 19:32:43 +000023 PyThread_type_lock lock_lock;
Benjamin Petersonbec4d572009-10-10 01:16:07 +000024 PyObject *in_weakreflist;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000025} lockobject;
26
Guido van Rossum1984f1e1992-08-04 12:41:02 +000027static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000028lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000029{
Benjamin Petersonbec4d572009-10-10 01:16:07 +000030 if (self->in_weakreflist != NULL)
31 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner8f3216a2010-03-03 00:50:12 +000032 if (self->lock_lock != NULL) {
33 /* Unlock the lock so it's safe to free it */
34 PyThread_acquire_lock(self->lock_lock, 0);
35 PyThread_release_lock(self->lock_lock);
36
37 PyThread_free_lock(self->lock_lock);
38 }
Guido van Rossumb18618d2000-05-03 23:44:39 +000039 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000040}
41
Barry Warsawd0c10421996-12-17 00:05:22 +000042static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000043lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000044{
Neal Norwitzba3a16c2002-03-31 15:27:00 +000045 int i = 1;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000046
Neal Norwitzba3a16c2002-03-31 15:27:00 +000047 if (!PyArg_ParseTuple(args, "|i:acquire", &i))
48 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000049
Barry Warsawd0c10421996-12-17 00:05:22 +000050 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +000051 i = PyThread_acquire_lock(self->lock_lock, i);
Barry Warsawd0c10421996-12-17 00:05:22 +000052 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +000053
Andrew M. Kuchlinga43ece92005-06-02 17:07:11 +000054 return PyBool_FromLong((long)i);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000055}
56
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000057PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000058"acquire([wait]) -> None or bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000059(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000060\n\
61Lock the lock. Without argument, this blocks if the lock is already\n\
62locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000063the lock, and return None once the lock is acquired.\n\
64With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000065and the return value reflects whether the lock is acquired.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000066The blocking operation is not interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000067
Barry Warsawd0c10421996-12-17 00:05:22 +000068static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000069lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000070{
Guido van Rossum1984f1e1992-08-04 12:41:02 +000071 /* Sanity check: the lock must be locked */
Guido van Rossum65d5b571998-12-21 19:32:43 +000072 if (PyThread_acquire_lock(self->lock_lock, 0)) {
73 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000074 PyErr_SetString(ThreadError, "release unlocked lock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +000075 return NULL;
76 }
77
Guido van Rossum65d5b571998-12-21 19:32:43 +000078 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000079 Py_INCREF(Py_None);
80 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000081}
82
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000083PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +000084"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000085(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000086\n\
87Release the lock, allowing another thread that is blocked waiting for\n\
88the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000089but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000090
Barry Warsawd0c10421996-12-17 00:05:22 +000091static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000092lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000093{
Guido van Rossum65d5b571998-12-21 19:32:43 +000094 if (PyThread_acquire_lock(self->lock_lock, 0)) {
95 PyThread_release_lock(self->lock_lock);
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000096 return PyBool_FromLong(0L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000097 }
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000098 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000099}
100
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000101PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000102"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000103(locked_lock() is an obsolete synonym)\n\
104\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000105Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000106
Barry Warsawd0c10421996-12-17 00:05:22 +0000107static PyMethodDef lock_methods[] = {
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000108 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000109 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000110 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000111 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000112 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000113 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000114 {"release", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000115 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000116 {"locked_lock", (PyCFunction)lock_locked_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000117 METH_NOARGS, locked_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000118 {"locked", (PyCFunction)lock_locked_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000119 METH_NOARGS, locked_doc},
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000120 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
121 METH_VARARGS, acquire_doc},
Guido van Rossumf6694362006-03-10 02:28:35 +0000122 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
123 METH_VARARGS, release_doc},
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000124 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000125};
126
Barry Warsawd0c10421996-12-17 00:05:22 +0000127static PyTypeObject Locktype = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000128 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Georg Brandl0a7ac7d2008-05-26 10:29:35 +0000129 "_thread.lock", /*tp_name*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000130 sizeof(lockobject), /*tp_size*/
131 0, /*tp_itemsize*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000132 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000133 (destructor)lock_dealloc, /*tp_dealloc*/
134 0, /*tp_print*/
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000135 0, /*tp_getattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000136 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +0000137 0, /*tp_reserved*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000138 0, /*tp_repr*/
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000139 0, /*tp_as_number*/
140 0, /*tp_as_sequence*/
141 0, /*tp_as_mapping*/
142 0, /*tp_hash*/
143 0, /*tp_call*/
144 0, /*tp_str*/
145 0, /*tp_getattro*/
146 0, /*tp_setattro*/
147 0, /*tp_as_buffer*/
Benjamin Petersonfe51a1f2009-10-09 20:36:25 +0000148 Py_TPFLAGS_DEFAULT, /*tp_flags*/
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000149 0, /*tp_doc*/
150 0, /*tp_traverse*/
151 0, /*tp_clear*/
152 0, /*tp_richcompare*/
Benjamin Petersonbec4d572009-10-10 01:16:07 +0000153 offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000154 0, /*tp_iter*/
155 0, /*tp_iternext*/
156 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000157};
158
Antoine Pitrou434736a2009-11-10 18:46:01 +0000159/* Recursive lock objects */
160
161typedef struct {
162 PyObject_HEAD
163 PyThread_type_lock rlock_lock;
164 long rlock_owner;
165 unsigned long rlock_count;
166 PyObject *in_weakreflist;
167} rlockobject;
168
169static void
170rlock_dealloc(rlockobject *self)
171{
172 assert(self->rlock_lock);
173 if (self->in_weakreflist != NULL)
174 PyObject_ClearWeakRefs((PyObject *) self);
175 /* Unlock the lock so it's safe to free it */
176 if (self->rlock_count > 0)
177 PyThread_release_lock(self->rlock_lock);
178
179 PyThread_free_lock(self->rlock_lock);
180 Py_TYPE(self)->tp_free(self);
181}
182
183static PyObject *
184rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
185{
186 char *kwlist[] = {"blocking", NULL};
187 int blocking = 1;
188 long tid;
189 int r = 1;
190
191 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:acquire", kwlist,
192 &blocking))
193 return NULL;
194
195 tid = PyThread_get_thread_ident();
196 if (self->rlock_count > 0 && tid == self->rlock_owner) {
197 unsigned long count = self->rlock_count + 1;
198 if (count <= self->rlock_count) {
199 PyErr_SetString(PyExc_OverflowError,
200 "Internal lock count overflowed");
201 return NULL;
202 }
203 self->rlock_count = count;
204 Py_RETURN_TRUE;
205 }
206
207 if (self->rlock_count > 0 ||
208 !PyThread_acquire_lock(self->rlock_lock, 0)) {
209 if (!blocking) {
210 Py_RETURN_FALSE;
211 }
212 Py_BEGIN_ALLOW_THREADS
213 r = PyThread_acquire_lock(self->rlock_lock, blocking);
214 Py_END_ALLOW_THREADS
215 }
216 if (r) {
217 assert(self->rlock_count == 0);
218 self->rlock_owner = tid;
219 self->rlock_count = 1;
220 }
221
222 return PyBool_FromLong(r);
223}
224
225PyDoc_STRVAR(rlock_acquire_doc,
226"acquire(blocking=True) -> bool\n\
227\n\
228Lock the lock. `blocking` indicates whether we should wait\n\
229for the lock to be available or not. If `blocking` is False\n\
230and another thread holds the lock, the method will return False\n\
231immediately. If `blocking` is True and another thread holds\n\
232the lock, the method will wait for the lock to be released,\n\
233take it and then return True.\n\
234(note: the blocking operation is not interruptible.)\n\
235\n\
236In all other cases, the method will return True immediately.\n\
237Precisely, if the current thread already holds the lock, its\n\
238internal counter is simply incremented. If nobody holds the lock,\n\
239the lock is taken and its internal counter initialized to 1.");
240
241static PyObject *
242rlock_release(rlockobject *self)
243{
244 long tid = PyThread_get_thread_ident();
245
246 if (self->rlock_count == 0 || self->rlock_owner != tid) {
247 PyErr_SetString(PyExc_RuntimeError,
248 "cannot release un-acquired lock");
249 return NULL;
250 }
251 if (--self->rlock_count == 0) {
252 self->rlock_owner = 0;
253 PyThread_release_lock(self->rlock_lock);
254 }
255 Py_RETURN_NONE;
256}
257
258PyDoc_STRVAR(rlock_release_doc,
259"release()\n\
260\n\
261Release the lock, allowing another thread that is blocked waiting for\n\
262the lock to acquire the lock. The lock must be in the locked state,\n\
263and must be locked by the same thread that unlocks it; otherwise a\n\
264`RuntimeError` is raised.\n\
265\n\
266Do note that if the lock was acquire()d several times in a row by the\n\
267current thread, release() needs to be called as many times for the lock\n\
268to be available for other threads.");
269
270static PyObject *
271rlock_acquire_restore(rlockobject *self, PyObject *arg)
272{
273 long owner;
274 unsigned long count;
275 int r = 1;
276
277 if (!PyArg_ParseTuple(arg, "kl:_acquire_restore", &count, &owner))
278 return NULL;
279
280 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
281 Py_BEGIN_ALLOW_THREADS
282 r = PyThread_acquire_lock(self->rlock_lock, 1);
283 Py_END_ALLOW_THREADS
284 }
285 if (!r) {
286 PyErr_SetString(ThreadError, "couldn't acquire lock");
287 return NULL;
288 }
289 assert(self->rlock_count == 0);
290 self->rlock_owner = owner;
291 self->rlock_count = count;
292 Py_RETURN_NONE;
293}
294
295PyDoc_STRVAR(rlock_acquire_restore_doc,
296"_acquire_restore(state) -> None\n\
297\n\
298For internal use by `threading.Condition`.");
299
300static PyObject *
301rlock_release_save(rlockobject *self)
302{
303 long owner;
304 unsigned long count;
305
306 owner = self->rlock_owner;
307 count = self->rlock_count;
308 self->rlock_count = 0;
309 self->rlock_owner = 0;
310 PyThread_release_lock(self->rlock_lock);
311 return Py_BuildValue("kl", count, owner);
312}
313
314PyDoc_STRVAR(rlock_release_save_doc,
315"_release_save() -> tuple\n\
316\n\
317For internal use by `threading.Condition`.");
318
319
320static PyObject *
321rlock_is_owned(rlockobject *self)
322{
323 long tid = PyThread_get_thread_ident();
324
325 if (self->rlock_count > 0 && self->rlock_owner == tid) {
326 Py_RETURN_TRUE;
327 }
328 Py_RETURN_FALSE;
329}
330
331PyDoc_STRVAR(rlock_is_owned_doc,
332"_is_owned() -> bool\n\
333\n\
334For internal use by `threading.Condition`.");
335
336static PyObject *
337rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
338{
339 rlockobject *self;
340
341 self = (rlockobject *) type->tp_alloc(type, 0);
342 if (self != NULL) {
343 self->rlock_lock = PyThread_allocate_lock();
344 if (self->rlock_lock == NULL) {
345 type->tp_free(self);
346 PyErr_SetString(ThreadError, "can't allocate lock");
347 return NULL;
348 }
349 self->in_weakreflist = NULL;
350 self->rlock_owner = 0;
351 self->rlock_count = 0;
352 }
353
354 return (PyObject *) self;
355}
356
357static PyObject *
358rlock_repr(rlockobject *self)
359{
360 return PyUnicode_FromFormat("<%s owner=%ld count=%lu>",
361 Py_TYPE(self)->tp_name, self->rlock_owner, self->rlock_count);
362}
363
364
365static PyMethodDef rlock_methods[] = {
366 {"acquire", (PyCFunction)rlock_acquire,
367 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
368 {"release", (PyCFunction)rlock_release,
369 METH_NOARGS, rlock_release_doc},
370 {"_is_owned", (PyCFunction)rlock_is_owned,
371 METH_NOARGS, rlock_is_owned_doc},
372 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
373 METH_O, rlock_acquire_restore_doc},
374 {"_release_save", (PyCFunction)rlock_release_save,
375 METH_NOARGS, rlock_release_save_doc},
376 {"__enter__", (PyCFunction)rlock_acquire,
377 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
378 {"__exit__", (PyCFunction)rlock_release,
379 METH_VARARGS, rlock_release_doc},
380 {NULL, NULL} /* sentinel */
381};
382
383
384static PyTypeObject RLocktype = {
385 PyVarObject_HEAD_INIT(&PyType_Type, 0)
386 "_thread.RLock", /*tp_name*/
387 sizeof(rlockobject), /*tp_size*/
388 0, /*tp_itemsize*/
389 /* methods */
390 (destructor)rlock_dealloc, /*tp_dealloc*/
391 0, /*tp_print*/
392 0, /*tp_getattr*/
393 0, /*tp_setattr*/
394 0, /*tp_reserved*/
395 (reprfunc)rlock_repr, /*tp_repr*/
396 0, /*tp_as_number*/
397 0, /*tp_as_sequence*/
398 0, /*tp_as_mapping*/
399 0, /*tp_hash*/
400 0, /*tp_call*/
401 0, /*tp_str*/
402 0, /*tp_getattro*/
403 0, /*tp_setattro*/
404 0, /*tp_as_buffer*/
405 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
406 0, /*tp_doc*/
407 0, /*tp_traverse*/
408 0, /*tp_clear*/
409 0, /*tp_richcompare*/
410 offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
411 0, /*tp_iter*/
412 0, /*tp_iternext*/
413 rlock_methods, /*tp_methods*/
414 0, /* tp_members */
415 0, /* tp_getset */
416 0, /* tp_base */
417 0, /* tp_dict */
418 0, /* tp_descr_get */
419 0, /* tp_descr_set */
420 0, /* tp_dictoffset */
421 0, /* tp_init */
422 PyType_GenericAlloc, /* tp_alloc */
423 rlock_new /* tp_new */
424};
425
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000426static lockobject *
427newlockobject(void)
428{
429 lockobject *self;
430 self = PyObject_New(lockobject, &Locktype);
431 if (self == NULL)
432 return NULL;
433 self->lock_lock = PyThread_allocate_lock();
Benjamin Petersonbec4d572009-10-10 01:16:07 +0000434 self->in_weakreflist = NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000435 if (self->lock_lock == NULL) {
Victor Stinner8f3216a2010-03-03 00:50:12 +0000436 Py_DECREF(self);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000437 PyErr_SetString(ThreadError, "can't allocate lock");
Victor Stinner8f3216a2010-03-03 00:50:12 +0000438 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000439 }
440 return self;
441}
442
Jim Fultond15dc062004-07-14 19:11:50 +0000443/* Thread-local objects */
444
445#include "structmember.h"
446
447typedef struct {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000448 PyObject_HEAD
449 PyObject *key;
450 PyObject *args;
451 PyObject *kw;
452 PyObject *dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000453} localobject;
454
Jim Fultond15dc062004-07-14 19:11:50 +0000455static PyObject *
456local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
457{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000458 localobject *self;
459 PyObject *tdict;
Jim Fultond15dc062004-07-14 19:11:50 +0000460
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000461 if (type->tp_init == PyBaseObject_Type.tp_init
462 && ((args && PyObject_IsTrue(args))
463 || (kw && PyObject_IsTrue(kw)))) {
464 PyErr_SetString(PyExc_TypeError,
465 "Initialization arguments are not supported");
466 return NULL;
467 }
Jim Fultond15dc062004-07-14 19:11:50 +0000468
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000469 self = (localobject *)type->tp_alloc(type, 0);
470 if (self == NULL)
471 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000472
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000473 Py_XINCREF(args);
474 self->args = args;
475 Py_XINCREF(kw);
476 self->kw = kw;
477 self->dict = NULL; /* making sure */
Walter Dörwald4ee631e2007-06-20 14:55:01 +0000478 self->key = PyUnicode_FromFormat("thread.local.%p", self);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000479 if (self->key == NULL)
480 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000481
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000482 self->dict = PyDict_New();
483 if (self->dict == NULL)
484 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000485
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000486 tdict = PyThreadState_GetDict();
487 if (tdict == NULL) {
488 PyErr_SetString(PyExc_SystemError,
489 "Couldn't get thread-state dictionary");
490 goto err;
491 }
Jim Fultond15dc062004-07-14 19:11:50 +0000492
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000493 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
494 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000495
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000496 return (PyObject *)self;
497
498 err:
499 Py_DECREF(self);
500 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000501}
502
503static int
504local_traverse(localobject *self, visitproc visit, void *arg)
505{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000506 Py_VISIT(self->args);
507 Py_VISIT(self->kw);
508 Py_VISIT(self->dict);
Jim Fultond15dc062004-07-14 19:11:50 +0000509 return 0;
510}
511
512static int
513local_clear(localobject *self)
514{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000515 Py_CLEAR(self->args);
516 Py_CLEAR(self->kw);
517 Py_CLEAR(self->dict);
518 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000519}
520
521static void
522local_dealloc(localobject *self)
523{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000524 PyThreadState *tstate;
525 if (self->key
526 && (tstate = PyThreadState_Get())
527 && tstate->interp) {
528 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
529 tstate;
530 tstate = PyThreadState_Next(tstate))
531 if (tstate->dict &&
532 PyDict_GetItem(tstate->dict, self->key))
533 PyDict_DelItem(tstate->dict, self->key);
534 }
Jim Fultond15dc062004-07-14 19:11:50 +0000535
Philip Jenvey26713ca2009-09-29 04:57:18 +0000536 Py_XDECREF(self->key);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000537 local_clear(self);
Christian Heimes90aa7642007-12-19 02:45:37 +0000538 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000539}
540
541static PyObject *
542_ldict(localobject *self)
543{
544 PyObject *tdict, *ldict;
545
546 tdict = PyThreadState_GetDict();
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000547 if (tdict == NULL) {
548 PyErr_SetString(PyExc_SystemError,
549 "Couldn't get thread-state dictionary");
550 return NULL;
551 }
Jim Fultond15dc062004-07-14 19:11:50 +0000552
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000553 ldict = PyDict_GetItem(tdict, self->key);
554 if (ldict == NULL) {
555 ldict = PyDict_New(); /* we own ldict */
Jim Fultond15dc062004-07-14 19:11:50 +0000556
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000557 if (ldict == NULL)
558 return NULL;
559 else {
560 int i = PyDict_SetItem(tdict, self->key, ldict);
Georg Brandlf3c4ad12006-03-08 12:24:33 +0000561 Py_DECREF(ldict); /* now ldict is borrowed */
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000562 if (i < 0)
563 return NULL;
564 }
Jim Fultond15dc062004-07-14 19:11:50 +0000565
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000566 Py_CLEAR(self->dict);
567 Py_INCREF(ldict);
568 self->dict = ldict; /* still borrowed */
Jim Fultond15dc062004-07-14 19:11:50 +0000569
Christian Heimes90aa7642007-12-19 02:45:37 +0000570 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
571 Py_TYPE(self)->tp_init((PyObject*)self,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000572 self->args, self->kw) < 0) {
573 /* we need to get rid of ldict from thread so
574 we create a new one the next time we do an attr
575 acces */
576 PyDict_DelItem(tdict, self->key);
577 return NULL;
578 }
579
580 }
Benjamin Peterson8a250ae2008-06-30 23:30:24 +0000581
582 /* The call to tp_init above may have caused another thread to run.
583 Install our ldict again. */
584 if (self->dict != ldict) {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000585 Py_CLEAR(self->dict);
586 Py_INCREF(ldict);
587 self->dict = ldict;
588 }
Jim Fultond15dc062004-07-14 19:11:50 +0000589
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000590 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000591}
592
Jim Fultond15dc062004-07-14 19:11:50 +0000593static int
594local_setattro(localobject *self, PyObject *name, PyObject *v)
595{
596 PyObject *ldict;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000597
598 ldict = _ldict(self);
599 if (ldict == NULL)
600 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000601
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000602 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000603}
604
605static PyObject *
606local_getdict(localobject *self, void *closure)
607{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000608 if (self->dict == NULL) {
609 PyErr_SetString(PyExc_AttributeError, "__dict__");
610 return NULL;
611 }
Jim Fultond15dc062004-07-14 19:11:50 +0000612
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000613 Py_INCREF(self->dict);
614 return self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000615}
616
617static PyGetSetDef local_getset[] = {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000618 {"__dict__", (getter)local_getdict, (setter)NULL,
619 "Local-data dictionary", NULL},
620 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000621};
622
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000623static PyObject *local_getattro(localobject *, PyObject *);
624
Jim Fultond15dc062004-07-14 19:11:50 +0000625static PyTypeObject localtype = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000626 PyVarObject_HEAD_INIT(NULL, 0)
Georg Brandl0a7ac7d2008-05-26 10:29:35 +0000627 /* tp_name */ "_thread._local",
Jim Fultond15dc062004-07-14 19:11:50 +0000628 /* tp_basicsize */ sizeof(localobject),
629 /* tp_itemsize */ 0,
630 /* tp_dealloc */ (destructor)local_dealloc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000631 /* tp_print */ 0,
632 /* tp_getattr */ 0,
633 /* tp_setattr */ 0,
Mark Dickinsone94c6792009-02-02 20:36:42 +0000634 /* tp_reserved */ 0,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000635 /* tp_repr */ 0,
Jim Fultond15dc062004-07-14 19:11:50 +0000636 /* tp_as_number */ 0,
637 /* tp_as_sequence */ 0,
638 /* tp_as_mapping */ 0,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000639 /* tp_hash */ 0,
640 /* tp_call */ 0,
641 /* tp_str */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000642 /* tp_getattro */ (getattrofunc)local_getattro,
643 /* tp_setattro */ (setattrofunc)local_setattro,
644 /* tp_as_buffer */ 0,
645 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Jim Fultond15dc062004-07-14 19:11:50 +0000646 /* tp_doc */ "Thread-local data",
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000647 /* tp_traverse */ (traverseproc)local_traverse,
648 /* tp_clear */ (inquiry)local_clear,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000649 /* tp_richcompare */ 0,
650 /* tp_weaklistoffset */ 0,
651 /* tp_iter */ 0,
652 /* tp_iternext */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000653 /* tp_methods */ 0,
654 /* tp_members */ 0,
655 /* tp_getset */ local_getset,
656 /* tp_base */ 0,
657 /* tp_dict */ 0, /* internal use */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000658 /* tp_descr_get */ 0,
659 /* tp_descr_set */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000660 /* tp_dictoffset */ offsetof(localobject, dict),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000661 /* tp_init */ 0,
662 /* tp_alloc */ 0,
663 /* tp_new */ local_new,
Jim Fultond15dc062004-07-14 19:11:50 +0000664 /* tp_free */ 0, /* Low-level free-mem routine */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000665 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000666};
667
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000668static PyObject *
669local_getattro(localobject *self, PyObject *name)
670{
671 PyObject *ldict, *value;
672
673 ldict = _ldict(self);
674 if (ldict == NULL)
675 return NULL;
676
Christian Heimes90aa7642007-12-19 02:45:37 +0000677 if (Py_TYPE(self) != &localtype)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000678 /* use generic lookup for subtypes */
679 return PyObject_GenericGetAttr((PyObject *)self, name);
680
681 /* Optimization: just look in dict ourselves */
682 value = PyDict_GetItem(ldict, name);
683 if (value == NULL)
684 /* Fall back on generic to get __class__ and __dict__ */
685 return PyObject_GenericGetAttr((PyObject *)self, name);
686
687 Py_INCREF(value);
688 return value;
689}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000690
691/* Module functions */
692
Guido van Rossuma027efa1997-05-05 20:56:21 +0000693struct bootstate {
694 PyInterpreterState *interp;
695 PyObject *func;
696 PyObject *args;
697 PyObject *keyw;
Victor Stinner45b9be52010-03-03 23:28:07 +0000698 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000699};
700
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000701static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000702t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000703{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000704 struct bootstate *boot = (struct bootstate *) boot_raw;
Michael W. Hudson188d4362005-06-20 16:52:57 +0000705 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000706 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000707
Victor Stinner45b9be52010-03-03 23:28:07 +0000708 tstate = boot->tstate;
709 tstate->thread_id = PyThread_get_thread_ident();
710 _PyThreadState_Init(tstate);
Michael W. Hudson188d4362005-06-20 16:52:57 +0000711 PyEval_AcquireThread(tstate);
Antoine Pitrou65c9c642009-10-30 17:25:12 +0000712 nb_threads++;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000713 res = PyEval_CallObjectWithKeywords(
714 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000715 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000716 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000717 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000718 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000719 PyObject *file;
720 PySys_WriteStderr(
721 "Unhandled exception in thread started by ");
722 file = PySys_GetObject("stderr");
Christian Heimes2be03732007-11-15 02:26:46 +0000723 if (file != NULL && file != Py_None)
Guido van Rossum24ccca12003-04-29 19:44:05 +0000724 PyFile_WriteObject(boot->func, file, 0);
725 else
726 PyObject_Print(boot->func, stderr, 0);
727 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000728 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000729 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000730 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000731 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000732 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000733 Py_DECREF(boot->func);
734 Py_DECREF(boot->args);
735 Py_XDECREF(boot->keyw);
736 PyMem_DEL(boot_raw);
Antoine Pitrou65c9c642009-10-30 17:25:12 +0000737 nb_threads--;
Michael W. Hudson188d4362005-06-20 16:52:57 +0000738 PyThreadState_Clear(tstate);
739 PyThreadState_DeleteCurrent();
Guido van Rossumbcc20741998-08-04 22:53:56 +0000740 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000741}
742
Barry Warsawd0c10421996-12-17 00:05:22 +0000743static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000744thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000745{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000746 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000747 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000748 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000749
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000750 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
751 &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000752 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000753 if (!PyCallable_Check(func)) {
754 PyErr_SetString(PyExc_TypeError,
755 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000756 return NULL;
757 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000758 if (!PyTuple_Check(args)) {
759 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000760 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000761 return NULL;
762 }
763 if (keyw != NULL && !PyDict_Check(keyw)) {
764 PyErr_SetString(PyExc_TypeError,
765 "optional 3rd arg must be a dictionary");
766 return NULL;
767 }
768 boot = PyMem_NEW(struct bootstate, 1);
769 if (boot == NULL)
770 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000771 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000772 boot->func = func;
773 boot->args = args;
774 boot->keyw = keyw;
Victor Stinner45b9be52010-03-03 23:28:07 +0000775 boot->tstate = _PyThreadState_Prealloc(boot->interp);
776 if (boot->tstate == NULL) {
777 PyMem_DEL(boot);
778 return PyErr_NoMemory();
779 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000780 Py_INCREF(func);
781 Py_INCREF(args);
782 Py_XINCREF(keyw);
783 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000784 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
785 if (ident == -1) {
Guido van Rossum54c273c2005-02-20 03:02:16 +0000786 PyErr_SetString(ThreadError, "can't start new thread");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000787 Py_DECREF(func);
788 Py_DECREF(args);
789 Py_XDECREF(keyw);
Victor Stinner45b9be52010-03-03 23:28:07 +0000790 PyThreadState_Clear(boot->tstate);
Guido van Rossuma027efa1997-05-05 20:56:21 +0000791 PyMem_DEL(boot);
792 return NULL;
793 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000794 return PyLong_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000795}
796
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000797PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000798"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000799(start_new() is an obsolete synonym)\n\
800\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000801Start a new thread and return its identifier. The thread will call the\n\
802function with positional arguments from the tuple args and keyword arguments\n\
803taken from the optional dictionary kwargs. The thread exits when the\n\
804function returns; the return value is ignored. The thread will also exit\n\
805when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000806printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000807
Barry Warsawd0c10421996-12-17 00:05:22 +0000808static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000809thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000810{
Barry Warsawd0c10421996-12-17 00:05:22 +0000811 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000812 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000813}
814
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000815PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000816"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000817(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000818\n\
819This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000820thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000821
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000822static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000823thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000824{
825 PyErr_SetInterrupt();
826 Py_INCREF(Py_None);
827 return Py_None;
828}
829
830PyDoc_STRVAR(interrupt_doc,
831"interrupt_main()\n\
832\n\
833Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000834A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000835);
836
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000837static lockobject *newlockobject(void);
838
Barry Warsawd0c10421996-12-17 00:05:22 +0000839static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000840thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000841{
Barry Warsawd0c10421996-12-17 00:05:22 +0000842 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000843}
844
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000845PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000846"allocate_lock() -> lock object\n\
847(allocate() is an obsolete synonym)\n\
848\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000849Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000850
Barry Warsawd0c10421996-12-17 00:05:22 +0000851static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000852thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000853{
854 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000855 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000856 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000857 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000858 return NULL;
859 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000860 return PyLong_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000861}
862
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000863PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000864"get_ident() -> integer\n\
865\n\
866Return a non-zero integer that uniquely identifies the current thread\n\
867amongst other threads that exist simultaneously.\n\
868This may be used to identify per-thread resources.\n\
869Even though on some platforms threads identities may appear to be\n\
870allocated consecutive numbers starting at 1, this behavior should not\n\
871be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000872A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000873
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000874static PyObject *
Antoine Pitrou65c9c642009-10-30 17:25:12 +0000875thread__count(PyObject *self)
876{
877 return PyLong_FromLong(nb_threads);
878}
879
880PyDoc_STRVAR(_count_doc,
881"_count() -> integer\n\
882\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +0000883\
884Return the number of currently running Python threads, excluding \n\
885the main thread. The returned number comprises all threads created\n\
886through `start_new_thread()` as well as `threading.Thread`, and not\n\
887yet finished.\n\
888\n\
889This function is meant for internal and specialized purposes only.\n\
890In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +0000891
892static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000893thread_stack_size(PyObject *self, PyObject *args)
894{
895 size_t old_size;
896 Py_ssize_t new_size = 0;
897 int rc;
898
899 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
900 return NULL;
901
902 if (new_size < 0) {
903 PyErr_SetString(PyExc_ValueError,
904 "size must be 0 or a positive value");
905 return NULL;
906 }
907
908 old_size = PyThread_get_stacksize();
909
910 rc = PyThread_set_stacksize((size_t) new_size);
911 if (rc == -1) {
912 PyErr_Format(PyExc_ValueError,
913 "size not valid: %zd bytes",
914 new_size);
915 return NULL;
916 }
917 if (rc == -2) {
918 PyErr_SetString(ThreadError,
919 "setting stack size not supported");
920 return NULL;
921 }
922
Christian Heimes217cfd12007-12-02 14:31:20 +0000923 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000924}
925
926PyDoc_STRVAR(stack_size_doc,
927"stack_size([size]) -> size\n\
928\n\
929Return the thread stack size used when creating new threads. The\n\
930optional size argument specifies the stack size (in bytes) to be used\n\
931for subsequently created threads, and must be 0 (use platform or\n\
932configured default) or a positive integer value of at least 32,768 (32k).\n\
933If changing the thread stack size is unsupported, a ThreadError\n\
934exception is raised. If the specified size is invalid, a ValueError\n\
935exception is raised, and the stack size is unmodified. 32k bytes\n\
936 currently the minimum supported stack size value to guarantee\n\
937sufficient stack space for the interpreter itself.\n\
938\n\
939Note that some platforms may have particular restrictions on values for\n\
940the stack size, such as requiring a minimum stack size larger than 32kB or\n\
941requiring allocation in multiples of the system memory page size\n\
942- platform documentation should be referred to for more information\n\
943(4kB pages are common; using multiples of 4096 for the stack size is\n\
944the suggested approach in the absence of more specific information).");
945
Barry Warsawd0c10421996-12-17 00:05:22 +0000946static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000947 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
948 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000949 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000950 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
951 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000952 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000953 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000954 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000955 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000956 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000957 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000958 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000959 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000960 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000961 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000962 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000963 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000964 METH_NOARGS, get_ident_doc},
Antoine Pitrou65c9c642009-10-30 17:25:12 +0000965 {"_count", (PyCFunction)thread__count,
966 METH_NOARGS, _count_doc},
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000967 {"stack_size", (PyCFunction)thread_stack_size,
968 METH_VARARGS,
969 stack_size_doc},
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000970 {NULL, NULL} /* sentinel */
971};
972
973
974/* Initialization function */
975
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000976PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000977"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000978The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000979
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000980PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000981"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000982call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000983\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000984acquire() -- lock the lock, possibly blocking until it can be obtained\n\
985release() -- unlock of the lock\n\
986locked() -- test whether the lock is currently locked\n\
987\n\
988A lock is not owned by the thread that locked it; another thread may\n\
989unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000990will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000991
Martin v. Löwis1a214512008-06-11 05:26:20 +0000992static struct PyModuleDef threadmodule = {
993 PyModuleDef_HEAD_INIT,
994 "_thread",
995 thread_doc,
996 -1,
997 thread_methods,
998 NULL,
999 NULL,
1000 NULL,
1001 NULL
1002};
1003
1004
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001005PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001006PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001007{
Barry Warsawd0c10421996-12-17 00:05:22 +00001008 PyObject *m, *d;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +00001009
1010 /* Initialize types: */
1011 if (PyType_Ready(&localtype) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001012 return NULL;
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001013 if (PyType_Ready(&Locktype) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001014 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +00001015 if (PyType_Ready(&RLocktype) < 0)
1016 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001017
1018 /* Create the module and add the functions */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001019 m = PyModule_Create(&threadmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001020 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001021 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001022
1023 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +00001024 d = PyModule_GetDict(m);
Georg Brandl2067bfd2008-05-25 13:05:15 +00001025 ThreadError = PyErr_NewException("_thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +00001026 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001027 Locktype.tp_doc = lock_doc;
1028 Py_INCREF(&Locktype);
1029 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001030
Antoine Pitrou434736a2009-11-10 18:46:01 +00001031 Py_INCREF(&RLocktype);
1032 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1033 return NULL;
1034
Michael W. Hudson64e08142005-06-15 12:25:20 +00001035 Py_INCREF(&localtype);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +00001036 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001037 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001038
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001039 nb_threads = 0;
1040
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001041 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +00001042 PyThread_init_thread();
Martin v. Löwis1a214512008-06-11 05:26:20 +00001043 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001044}