blob: 5a3f92a543feb480d7fe5abdb8cf25028ae68a33 [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{
Thomas Wouters89f507f2006-12-13 04:49:30 +000030 assert(self->lock_lock);
Benjamin Petersonbec4d572009-10-10 01:16:07 +000031 if (self->in_weakreflist != NULL)
32 PyObject_ClearWeakRefs((PyObject *) self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000033 /* Unlock the lock so it's safe to free it */
Guido van Rossum65d5b571998-12-21 19:32:43 +000034 PyThread_acquire_lock(self->lock_lock, 0);
35 PyThread_release_lock(self->lock_lock);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000036
Guido van Rossum65d5b571998-12-21 19:32:43 +000037 PyThread_free_lock(self->lock_lock);
Guido van Rossumb18618d2000-05-03 23:44:39 +000038 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000039}
40
Barry Warsawd0c10421996-12-17 00:05:22 +000041static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000042lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000043{
Neal Norwitzba3a16c2002-03-31 15:27:00 +000044 int i = 1;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000045
Neal Norwitzba3a16c2002-03-31 15:27:00 +000046 if (!PyArg_ParseTuple(args, "|i:acquire", &i))
47 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000048
Barry Warsawd0c10421996-12-17 00:05:22 +000049 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +000050 i = PyThread_acquire_lock(self->lock_lock, i);
Barry Warsawd0c10421996-12-17 00:05:22 +000051 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +000052
Andrew M. Kuchlinga43ece92005-06-02 17:07:11 +000053 return PyBool_FromLong((long)i);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000054}
55
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000056PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000057"acquire([wait]) -> None or bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000058(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000059\n\
60Lock the lock. Without argument, this blocks if the lock is already\n\
61locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000062the lock, and return None once the lock is acquired.\n\
63With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000064and the return value reflects whether the lock is acquired.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000065The blocking operation is not interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000066
Barry Warsawd0c10421996-12-17 00:05:22 +000067static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000068lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000069{
Guido van Rossum1984f1e1992-08-04 12:41:02 +000070 /* Sanity check: the lock must be locked */
Guido van Rossum65d5b571998-12-21 19:32:43 +000071 if (PyThread_acquire_lock(self->lock_lock, 0)) {
72 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000073 PyErr_SetString(ThreadError, "release unlocked lock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +000074 return NULL;
75 }
76
Guido van Rossum65d5b571998-12-21 19:32:43 +000077 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000078 Py_INCREF(Py_None);
79 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000080}
81
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000082PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +000083"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000084(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000085\n\
86Release the lock, allowing another thread that is blocked waiting for\n\
87the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000088but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000089
Barry Warsawd0c10421996-12-17 00:05:22 +000090static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000091lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000092{
Guido van Rossum65d5b571998-12-21 19:32:43 +000093 if (PyThread_acquire_lock(self->lock_lock, 0)) {
94 PyThread_release_lock(self->lock_lock);
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000095 return PyBool_FromLong(0L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000096 }
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000097 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000098}
99
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000100PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000101"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000102(locked_lock() is an obsolete synonym)\n\
103\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000104Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000105
Barry Warsawd0c10421996-12-17 00:05:22 +0000106static PyMethodDef lock_methods[] = {
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000107 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000108 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000109 {"acquire", (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 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000112 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000113 {"release", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000114 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000115 {"locked_lock", (PyCFunction)lock_locked_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000116 METH_NOARGS, locked_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000117 {"locked", (PyCFunction)lock_locked_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000118 METH_NOARGS, locked_doc},
Guido van Rossum1a5e21e2006-02-28 21:57:43 +0000119 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
120 METH_VARARGS, acquire_doc},
Guido van Rossumf6694362006-03-10 02:28:35 +0000121 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
122 METH_VARARGS, release_doc},
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000123 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000124};
125
Barry Warsawd0c10421996-12-17 00:05:22 +0000126static PyTypeObject Locktype = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000127 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Georg Brandl0a7ac7d2008-05-26 10:29:35 +0000128 "_thread.lock", /*tp_name*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000129 sizeof(lockobject), /*tp_size*/
130 0, /*tp_itemsize*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000131 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000132 (destructor)lock_dealloc, /*tp_dealloc*/
133 0, /*tp_print*/
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000134 0, /*tp_getattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000135 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +0000136 0, /*tp_reserved*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000137 0, /*tp_repr*/
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000138 0, /*tp_as_number*/
139 0, /*tp_as_sequence*/
140 0, /*tp_as_mapping*/
141 0, /*tp_hash*/
142 0, /*tp_call*/
143 0, /*tp_str*/
144 0, /*tp_getattro*/
145 0, /*tp_setattro*/
146 0, /*tp_as_buffer*/
Benjamin Petersonfe51a1f2009-10-09 20:36:25 +0000147 Py_TPFLAGS_DEFAULT, /*tp_flags*/
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000148 0, /*tp_doc*/
149 0, /*tp_traverse*/
150 0, /*tp_clear*/
151 0, /*tp_richcompare*/
Benjamin Petersonbec4d572009-10-10 01:16:07 +0000152 offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000153 0, /*tp_iter*/
154 0, /*tp_iternext*/
155 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000156};
157
Antoine Pitrou434736a2009-11-10 18:46:01 +0000158/* Recursive lock objects */
159
160typedef struct {
161 PyObject_HEAD
162 PyThread_type_lock rlock_lock;
163 long rlock_owner;
164 unsigned long rlock_count;
165 PyObject *in_weakreflist;
166} rlockobject;
167
168static void
169rlock_dealloc(rlockobject *self)
170{
171 assert(self->rlock_lock);
172 if (self->in_weakreflist != NULL)
173 PyObject_ClearWeakRefs((PyObject *) self);
174 /* Unlock the lock so it's safe to free it */
175 if (self->rlock_count > 0)
176 PyThread_release_lock(self->rlock_lock);
177
178 PyThread_free_lock(self->rlock_lock);
179 Py_TYPE(self)->tp_free(self);
180}
181
182static PyObject *
183rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
184{
185 char *kwlist[] = {"blocking", NULL};
186 int blocking = 1;
187 long tid;
188 int r = 1;
189
190 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:acquire", kwlist,
191 &blocking))
192 return NULL;
193
194 tid = PyThread_get_thread_ident();
195 if (self->rlock_count > 0 && tid == self->rlock_owner) {
196 unsigned long count = self->rlock_count + 1;
197 if (count <= self->rlock_count) {
198 PyErr_SetString(PyExc_OverflowError,
199 "Internal lock count overflowed");
200 return NULL;
201 }
202 self->rlock_count = count;
203 Py_RETURN_TRUE;
204 }
205
206 if (self->rlock_count > 0 ||
207 !PyThread_acquire_lock(self->rlock_lock, 0)) {
208 if (!blocking) {
209 Py_RETURN_FALSE;
210 }
211 Py_BEGIN_ALLOW_THREADS
212 r = PyThread_acquire_lock(self->rlock_lock, blocking);
213 Py_END_ALLOW_THREADS
214 }
215 if (r) {
216 assert(self->rlock_count == 0);
217 self->rlock_owner = tid;
218 self->rlock_count = 1;
219 }
220
221 return PyBool_FromLong(r);
222}
223
224PyDoc_STRVAR(rlock_acquire_doc,
225"acquire(blocking=True) -> bool\n\
226\n\
227Lock the lock. `blocking` indicates whether we should wait\n\
228for the lock to be available or not. If `blocking` is False\n\
229and another thread holds the lock, the method will return False\n\
230immediately. If `blocking` is True and another thread holds\n\
231the lock, the method will wait for the lock to be released,\n\
232take it and then return True.\n\
233(note: the blocking operation is not interruptible.)\n\
234\n\
235In all other cases, the method will return True immediately.\n\
236Precisely, if the current thread already holds the lock, its\n\
237internal counter is simply incremented. If nobody holds the lock,\n\
238the lock is taken and its internal counter initialized to 1.");
239
240static PyObject *
241rlock_release(rlockobject *self)
242{
243 long tid = PyThread_get_thread_ident();
244
245 if (self->rlock_count == 0 || self->rlock_owner != tid) {
246 PyErr_SetString(PyExc_RuntimeError,
247 "cannot release un-acquired lock");
248 return NULL;
249 }
250 if (--self->rlock_count == 0) {
251 self->rlock_owner = 0;
252 PyThread_release_lock(self->rlock_lock);
253 }
254 Py_RETURN_NONE;
255}
256
257PyDoc_STRVAR(rlock_release_doc,
258"release()\n\
259\n\
260Release the lock, allowing another thread that is blocked waiting for\n\
261the lock to acquire the lock. The lock must be in the locked state,\n\
262and must be locked by the same thread that unlocks it; otherwise a\n\
263`RuntimeError` is raised.\n\
264\n\
265Do note that if the lock was acquire()d several times in a row by the\n\
266current thread, release() needs to be called as many times for the lock\n\
267to be available for other threads.");
268
269static PyObject *
270rlock_acquire_restore(rlockobject *self, PyObject *arg)
271{
272 long owner;
273 unsigned long count;
274 int r = 1;
275
276 if (!PyArg_ParseTuple(arg, "kl:_acquire_restore", &count, &owner))
277 return NULL;
278
279 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
280 Py_BEGIN_ALLOW_THREADS
281 r = PyThread_acquire_lock(self->rlock_lock, 1);
282 Py_END_ALLOW_THREADS
283 }
284 if (!r) {
285 PyErr_SetString(ThreadError, "couldn't acquire lock");
286 return NULL;
287 }
288 assert(self->rlock_count == 0);
289 self->rlock_owner = owner;
290 self->rlock_count = count;
291 Py_RETURN_NONE;
292}
293
294PyDoc_STRVAR(rlock_acquire_restore_doc,
295"_acquire_restore(state) -> None\n\
296\n\
297For internal use by `threading.Condition`.");
298
299static PyObject *
300rlock_release_save(rlockobject *self)
301{
302 long owner;
303 unsigned long count;
304
305 owner = self->rlock_owner;
306 count = self->rlock_count;
307 self->rlock_count = 0;
308 self->rlock_owner = 0;
309 PyThread_release_lock(self->rlock_lock);
310 return Py_BuildValue("kl", count, owner);
311}
312
313PyDoc_STRVAR(rlock_release_save_doc,
314"_release_save() -> tuple\n\
315\n\
316For internal use by `threading.Condition`.");
317
318
319static PyObject *
320rlock_is_owned(rlockobject *self)
321{
322 long tid = PyThread_get_thread_ident();
323
324 if (self->rlock_count > 0 && self->rlock_owner == tid) {
325 Py_RETURN_TRUE;
326 }
327 Py_RETURN_FALSE;
328}
329
330PyDoc_STRVAR(rlock_is_owned_doc,
331"_is_owned() -> bool\n\
332\n\
333For internal use by `threading.Condition`.");
334
335static PyObject *
336rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
337{
338 rlockobject *self;
339
340 self = (rlockobject *) type->tp_alloc(type, 0);
341 if (self != NULL) {
342 self->rlock_lock = PyThread_allocate_lock();
343 if (self->rlock_lock == NULL) {
344 type->tp_free(self);
345 PyErr_SetString(ThreadError, "can't allocate lock");
346 return NULL;
347 }
348 self->in_weakreflist = NULL;
349 self->rlock_owner = 0;
350 self->rlock_count = 0;
351 }
352
353 return (PyObject *) self;
354}
355
356static PyObject *
357rlock_repr(rlockobject *self)
358{
359 return PyUnicode_FromFormat("<%s owner=%ld count=%lu>",
360 Py_TYPE(self)->tp_name, self->rlock_owner, self->rlock_count);
361}
362
363
364static PyMethodDef rlock_methods[] = {
365 {"acquire", (PyCFunction)rlock_acquire,
366 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
367 {"release", (PyCFunction)rlock_release,
368 METH_NOARGS, rlock_release_doc},
369 {"_is_owned", (PyCFunction)rlock_is_owned,
370 METH_NOARGS, rlock_is_owned_doc},
371 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
372 METH_O, rlock_acquire_restore_doc},
373 {"_release_save", (PyCFunction)rlock_release_save,
374 METH_NOARGS, rlock_release_save_doc},
375 {"__enter__", (PyCFunction)rlock_acquire,
376 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
377 {"__exit__", (PyCFunction)rlock_release,
378 METH_VARARGS, rlock_release_doc},
379 {NULL, NULL} /* sentinel */
380};
381
382
383static PyTypeObject RLocktype = {
384 PyVarObject_HEAD_INIT(&PyType_Type, 0)
385 "_thread.RLock", /*tp_name*/
386 sizeof(rlockobject), /*tp_size*/
387 0, /*tp_itemsize*/
388 /* methods */
389 (destructor)rlock_dealloc, /*tp_dealloc*/
390 0, /*tp_print*/
391 0, /*tp_getattr*/
392 0, /*tp_setattr*/
393 0, /*tp_reserved*/
394 (reprfunc)rlock_repr, /*tp_repr*/
395 0, /*tp_as_number*/
396 0, /*tp_as_sequence*/
397 0, /*tp_as_mapping*/
398 0, /*tp_hash*/
399 0, /*tp_call*/
400 0, /*tp_str*/
401 0, /*tp_getattro*/
402 0, /*tp_setattro*/
403 0, /*tp_as_buffer*/
404 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
405 0, /*tp_doc*/
406 0, /*tp_traverse*/
407 0, /*tp_clear*/
408 0, /*tp_richcompare*/
409 offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
410 0, /*tp_iter*/
411 0, /*tp_iternext*/
412 rlock_methods, /*tp_methods*/
413 0, /* tp_members */
414 0, /* tp_getset */
415 0, /* tp_base */
416 0, /* tp_dict */
417 0, /* tp_descr_get */
418 0, /* tp_descr_set */
419 0, /* tp_dictoffset */
420 0, /* tp_init */
421 PyType_GenericAlloc, /* tp_alloc */
422 rlock_new /* tp_new */
423};
424
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000425static lockobject *
426newlockobject(void)
427{
428 lockobject *self;
429 self = PyObject_New(lockobject, &Locktype);
430 if (self == NULL)
431 return NULL;
432 self->lock_lock = PyThread_allocate_lock();
Benjamin Petersonbec4d572009-10-10 01:16:07 +0000433 self->in_weakreflist = NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000434 if (self->lock_lock == NULL) {
435 PyObject_Del(self);
436 self = NULL;
437 PyErr_SetString(ThreadError, "can't allocate lock");
438 }
439 return self;
440}
441
Jim Fultond15dc062004-07-14 19:11:50 +0000442/* Thread-local objects */
443
444#include "structmember.h"
445
446typedef struct {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000447 PyObject_HEAD
448 PyObject *key;
449 PyObject *args;
450 PyObject *kw;
451 PyObject *dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000452} localobject;
453
Jim Fultond15dc062004-07-14 19:11:50 +0000454static PyObject *
455local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
456{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000457 localobject *self;
458 PyObject *tdict;
Jim Fultond15dc062004-07-14 19:11:50 +0000459
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000460 if (type->tp_init == PyBaseObject_Type.tp_init
461 && ((args && PyObject_IsTrue(args))
462 || (kw && PyObject_IsTrue(kw)))) {
463 PyErr_SetString(PyExc_TypeError,
464 "Initialization arguments are not supported");
465 return NULL;
466 }
Jim Fultond15dc062004-07-14 19:11:50 +0000467
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000468 self = (localobject *)type->tp_alloc(type, 0);
469 if (self == NULL)
470 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000471
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000472 Py_XINCREF(args);
473 self->args = args;
474 Py_XINCREF(kw);
475 self->kw = kw;
476 self->dict = NULL; /* making sure */
Walter Dörwald4ee631e2007-06-20 14:55:01 +0000477 self->key = PyUnicode_FromFormat("thread.local.%p", self);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000478 if (self->key == NULL)
479 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000480
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000481 self->dict = PyDict_New();
482 if (self->dict == NULL)
483 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000484
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000485 tdict = PyThreadState_GetDict();
486 if (tdict == NULL) {
487 PyErr_SetString(PyExc_SystemError,
488 "Couldn't get thread-state dictionary");
489 goto err;
490 }
Jim Fultond15dc062004-07-14 19:11:50 +0000491
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000492 if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
493 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000494
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000495 return (PyObject *)self;
496
497 err:
498 Py_DECREF(self);
499 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000500}
501
502static int
503local_traverse(localobject *self, visitproc visit, void *arg)
504{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000505 Py_VISIT(self->args);
506 Py_VISIT(self->kw);
507 Py_VISIT(self->dict);
Jim Fultond15dc062004-07-14 19:11:50 +0000508 return 0;
509}
510
511static int
512local_clear(localobject *self)
513{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000514 Py_CLEAR(self->args);
515 Py_CLEAR(self->kw);
516 Py_CLEAR(self->dict);
517 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000518}
519
520static void
521local_dealloc(localobject *self)
522{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000523 PyThreadState *tstate;
524 if (self->key
525 && (tstate = PyThreadState_Get())
526 && tstate->interp) {
527 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
528 tstate;
529 tstate = PyThreadState_Next(tstate))
530 if (tstate->dict &&
531 PyDict_GetItem(tstate->dict, self->key))
532 PyDict_DelItem(tstate->dict, self->key);
533 }
Jim Fultond15dc062004-07-14 19:11:50 +0000534
Philip Jenvey26713ca2009-09-29 04:57:18 +0000535 Py_XDECREF(self->key);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000536 local_clear(self);
Christian Heimes90aa7642007-12-19 02:45:37 +0000537 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000538}
539
540static PyObject *
541_ldict(localobject *self)
542{
543 PyObject *tdict, *ldict;
544
545 tdict = PyThreadState_GetDict();
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000546 if (tdict == NULL) {
547 PyErr_SetString(PyExc_SystemError,
548 "Couldn't get thread-state dictionary");
549 return NULL;
550 }
Jim Fultond15dc062004-07-14 19:11:50 +0000551
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000552 ldict = PyDict_GetItem(tdict, self->key);
553 if (ldict == NULL) {
554 ldict = PyDict_New(); /* we own ldict */
Jim Fultond15dc062004-07-14 19:11:50 +0000555
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000556 if (ldict == NULL)
557 return NULL;
558 else {
559 int i = PyDict_SetItem(tdict, self->key, ldict);
Georg Brandlf3c4ad12006-03-08 12:24:33 +0000560 Py_DECREF(ldict); /* now ldict is borrowed */
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000561 if (i < 0)
562 return NULL;
563 }
Jim Fultond15dc062004-07-14 19:11:50 +0000564
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000565 Py_CLEAR(self->dict);
566 Py_INCREF(ldict);
567 self->dict = ldict; /* still borrowed */
Jim Fultond15dc062004-07-14 19:11:50 +0000568
Christian Heimes90aa7642007-12-19 02:45:37 +0000569 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
570 Py_TYPE(self)->tp_init((PyObject*)self,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000571 self->args, self->kw) < 0) {
572 /* we need to get rid of ldict from thread so
573 we create a new one the next time we do an attr
574 acces */
575 PyDict_DelItem(tdict, self->key);
576 return NULL;
577 }
578
579 }
Benjamin Peterson8a250ae2008-06-30 23:30:24 +0000580
581 /* The call to tp_init above may have caused another thread to run.
582 Install our ldict again. */
583 if (self->dict != ldict) {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000584 Py_CLEAR(self->dict);
585 Py_INCREF(ldict);
586 self->dict = ldict;
587 }
Jim Fultond15dc062004-07-14 19:11:50 +0000588
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000589 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000590}
591
Jim Fultond15dc062004-07-14 19:11:50 +0000592static int
593local_setattro(localobject *self, PyObject *name, PyObject *v)
594{
595 PyObject *ldict;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000596
597 ldict = _ldict(self);
598 if (ldict == NULL)
599 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000600
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000601 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000602}
603
604static PyObject *
605local_getdict(localobject *self, void *closure)
606{
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000607 if (self->dict == NULL) {
608 PyErr_SetString(PyExc_AttributeError, "__dict__");
609 return NULL;
610 }
Jim Fultond15dc062004-07-14 19:11:50 +0000611
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000612 Py_INCREF(self->dict);
613 return self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000614}
615
616static PyGetSetDef local_getset[] = {
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000617 {"__dict__", (getter)local_getdict, (setter)NULL,
618 "Local-data dictionary", NULL},
619 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000620};
621
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000622static PyObject *local_getattro(localobject *, PyObject *);
623
Jim Fultond15dc062004-07-14 19:11:50 +0000624static PyTypeObject localtype = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000625 PyVarObject_HEAD_INIT(NULL, 0)
Georg Brandl0a7ac7d2008-05-26 10:29:35 +0000626 /* tp_name */ "_thread._local",
Jim Fultond15dc062004-07-14 19:11:50 +0000627 /* tp_basicsize */ sizeof(localobject),
628 /* tp_itemsize */ 0,
629 /* tp_dealloc */ (destructor)local_dealloc,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000630 /* tp_print */ 0,
631 /* tp_getattr */ 0,
632 /* tp_setattr */ 0,
Mark Dickinsone94c6792009-02-02 20:36:42 +0000633 /* tp_reserved */ 0,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000634 /* tp_repr */ 0,
Jim Fultond15dc062004-07-14 19:11:50 +0000635 /* tp_as_number */ 0,
636 /* tp_as_sequence */ 0,
637 /* tp_as_mapping */ 0,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000638 /* tp_hash */ 0,
639 /* tp_call */ 0,
640 /* tp_str */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000641 /* tp_getattro */ (getattrofunc)local_getattro,
642 /* tp_setattro */ (setattrofunc)local_setattro,
643 /* tp_as_buffer */ 0,
644 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Jim Fultond15dc062004-07-14 19:11:50 +0000645 /* tp_doc */ "Thread-local data",
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000646 /* tp_traverse */ (traverseproc)local_traverse,
647 /* tp_clear */ (inquiry)local_clear,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000648 /* tp_richcompare */ 0,
649 /* tp_weaklistoffset */ 0,
650 /* tp_iter */ 0,
651 /* tp_iternext */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000652 /* tp_methods */ 0,
653 /* tp_members */ 0,
654 /* tp_getset */ local_getset,
655 /* tp_base */ 0,
656 /* tp_dict */ 0, /* internal use */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000657 /* tp_descr_get */ 0,
658 /* tp_descr_set */ 0,
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000659 /* tp_dictoffset */ offsetof(localobject, dict),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000660 /* tp_init */ 0,
661 /* tp_alloc */ 0,
662 /* tp_new */ local_new,
Jim Fultond15dc062004-07-14 19:11:50 +0000663 /* tp_free */ 0, /* Low-level free-mem routine */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000664 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000665};
666
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000667static PyObject *
668local_getattro(localobject *self, PyObject *name)
669{
670 PyObject *ldict, *value;
671
672 ldict = _ldict(self);
673 if (ldict == NULL)
674 return NULL;
675
Christian Heimes90aa7642007-12-19 02:45:37 +0000676 if (Py_TYPE(self) != &localtype)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000677 /* use generic lookup for subtypes */
678 return PyObject_GenericGetAttr((PyObject *)self, name);
679
680 /* Optimization: just look in dict ourselves */
681 value = PyDict_GetItem(ldict, name);
682 if (value == NULL)
683 /* Fall back on generic to get __class__ and __dict__ */
684 return PyObject_GenericGetAttr((PyObject *)self, name);
685
686 Py_INCREF(value);
687 return value;
688}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000689
690/* Module functions */
691
Guido van Rossuma027efa1997-05-05 20:56:21 +0000692struct bootstate {
693 PyInterpreterState *interp;
694 PyObject *func;
695 PyObject *args;
696 PyObject *keyw;
697};
698
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000699static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000700t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000701{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000702 struct bootstate *boot = (struct bootstate *) boot_raw;
Michael W. Hudson188d4362005-06-20 16:52:57 +0000703 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000704 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000705
Michael W. Hudson188d4362005-06-20 16:52:57 +0000706 tstate = PyThreadState_New(boot->interp);
707
708 PyEval_AcquireThread(tstate);
Antoine Pitrou65c9c642009-10-30 17:25:12 +0000709 nb_threads++;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000710 res = PyEval_CallObjectWithKeywords(
711 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000712 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000713 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000714 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000715 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000716 PyObject *file;
717 PySys_WriteStderr(
718 "Unhandled exception in thread started by ");
719 file = PySys_GetObject("stderr");
Christian Heimes2be03732007-11-15 02:26:46 +0000720 if (file != NULL && file != Py_None)
Guido van Rossum24ccca12003-04-29 19:44:05 +0000721 PyFile_WriteObject(boot->func, file, 0);
722 else
723 PyObject_Print(boot->func, stderr, 0);
724 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000725 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000726 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000727 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000728 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000729 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000730 Py_DECREF(boot->func);
731 Py_DECREF(boot->args);
732 Py_XDECREF(boot->keyw);
733 PyMem_DEL(boot_raw);
Antoine Pitrou65c9c642009-10-30 17:25:12 +0000734 nb_threads--;
Michael W. Hudson188d4362005-06-20 16:52:57 +0000735 PyThreadState_Clear(tstate);
736 PyThreadState_DeleteCurrent();
Guido van Rossumbcc20741998-08-04 22:53:56 +0000737 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000738}
739
Barry Warsawd0c10421996-12-17 00:05:22 +0000740static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000741thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000742{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000743 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000744 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000745 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000746
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000747 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
748 &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000749 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000750 if (!PyCallable_Check(func)) {
751 PyErr_SetString(PyExc_TypeError,
752 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000753 return NULL;
754 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000755 if (!PyTuple_Check(args)) {
756 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000757 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000758 return NULL;
759 }
760 if (keyw != NULL && !PyDict_Check(keyw)) {
761 PyErr_SetString(PyExc_TypeError,
762 "optional 3rd arg must be a dictionary");
763 return NULL;
764 }
765 boot = PyMem_NEW(struct bootstate, 1);
766 if (boot == NULL)
767 return PyErr_NoMemory();
Nicholas Bastine5662ae2004-03-24 22:22:12 +0000768 boot->interp = PyThreadState_GET()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000769 boot->func = func;
770 boot->args = args;
771 boot->keyw = keyw;
772 Py_INCREF(func);
773 Py_INCREF(args);
774 Py_XINCREF(keyw);
775 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000776 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
777 if (ident == -1) {
Guido van Rossum54c273c2005-02-20 03:02:16 +0000778 PyErr_SetString(ThreadError, "can't start new thread");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000779 Py_DECREF(func);
780 Py_DECREF(args);
781 Py_XDECREF(keyw);
782 PyMem_DEL(boot);
783 return NULL;
784 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000785 return PyLong_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000786}
787
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000788PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000789"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000790(start_new() is an obsolete synonym)\n\
791\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000792Start a new thread and return its identifier. The thread will call the\n\
793function with positional arguments from the tuple args and keyword arguments\n\
794taken from the optional dictionary kwargs. The thread exits when the\n\
795function returns; the return value is ignored. The thread will also exit\n\
796when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000797printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000798
Barry Warsawd0c10421996-12-17 00:05:22 +0000799static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000800thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000801{
Barry Warsawd0c10421996-12-17 00:05:22 +0000802 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000803 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000804}
805
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000806PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000807"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000808(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000809\n\
810This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000811thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000812
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000813static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000814thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000815{
816 PyErr_SetInterrupt();
817 Py_INCREF(Py_None);
818 return Py_None;
819}
820
821PyDoc_STRVAR(interrupt_doc,
822"interrupt_main()\n\
823\n\
824Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000825A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000826);
827
Guido van Rossumb6775db1994-08-01 11:34:53 +0000828#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000829static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000830thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000831{
832 int sts;
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000833 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000834 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000835 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000836 for (;;) { } /* Should not be reached */
837}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000838#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000839
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000840static lockobject *newlockobject(void);
841
Barry Warsawd0c10421996-12-17 00:05:22 +0000842static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000843thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000844{
Barry Warsawd0c10421996-12-17 00:05:22 +0000845 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000846}
847
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000848PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000849"allocate_lock() -> lock object\n\
850(allocate() is an obsolete synonym)\n\
851\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000852Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000853
Barry Warsawd0c10421996-12-17 00:05:22 +0000854static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000855thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000856{
857 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000858 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000859 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000860 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000861 return NULL;
862 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000863 return PyLong_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000864}
865
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000866PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000867"get_ident() -> integer\n\
868\n\
869Return a non-zero integer that uniquely identifies the current thread\n\
870amongst other threads that exist simultaneously.\n\
871This may be used to identify per-thread resources.\n\
872Even though on some platforms threads identities may appear to be\n\
873allocated consecutive numbers starting at 1, this behavior should not\n\
874be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000875A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000876
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000877static PyObject *
Antoine Pitrou65c9c642009-10-30 17:25:12 +0000878thread__count(PyObject *self)
879{
880 return PyLong_FromLong(nb_threads);
881}
882
883PyDoc_STRVAR(_count_doc,
884"_count() -> integer\n\
885\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +0000886\
887Return the number of currently running Python threads, excluding \n\
888the main thread. The returned number comprises all threads created\n\
889through `start_new_thread()` as well as `threading.Thread`, and not\n\
890yet finished.\n\
891\n\
892This function is meant for internal and specialized purposes only.\n\
893In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +0000894
895static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000896thread_stack_size(PyObject *self, PyObject *args)
897{
898 size_t old_size;
899 Py_ssize_t new_size = 0;
900 int rc;
901
902 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
903 return NULL;
904
905 if (new_size < 0) {
906 PyErr_SetString(PyExc_ValueError,
907 "size must be 0 or a positive value");
908 return NULL;
909 }
910
911 old_size = PyThread_get_stacksize();
912
913 rc = PyThread_set_stacksize((size_t) new_size);
914 if (rc == -1) {
915 PyErr_Format(PyExc_ValueError,
916 "size not valid: %zd bytes",
917 new_size);
918 return NULL;
919 }
920 if (rc == -2) {
921 PyErr_SetString(ThreadError,
922 "setting stack size not supported");
923 return NULL;
924 }
925
Christian Heimes217cfd12007-12-02 14:31:20 +0000926 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000927}
928
929PyDoc_STRVAR(stack_size_doc,
930"stack_size([size]) -> size\n\
931\n\
932Return the thread stack size used when creating new threads. The\n\
933optional size argument specifies the stack size (in bytes) to be used\n\
934for subsequently created threads, and must be 0 (use platform or\n\
935configured default) or a positive integer value of at least 32,768 (32k).\n\
936If changing the thread stack size is unsupported, a ThreadError\n\
937exception is raised. If the specified size is invalid, a ValueError\n\
938exception is raised, and the stack size is unmodified. 32k bytes\n\
939 currently the minimum supported stack size value to guarantee\n\
940sufficient stack space for the interpreter itself.\n\
941\n\
942Note that some platforms may have particular restrictions on values for\n\
943the stack size, such as requiring a minimum stack size larger than 32kB or\n\
944requiring allocation in multiples of the system memory page size\n\
945- platform documentation should be referred to for more information\n\
946(4kB pages are common; using multiples of 4096 for the stack size is\n\
947the suggested approach in the absence of more specific information).");
948
Barry Warsawd0c10421996-12-17 00:05:22 +0000949static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000950 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
951 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000952 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000953 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
954 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000955 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000956 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000957 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000958 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000959 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000960 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000961 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000962 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000963 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000964 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000965 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000966 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000967 METH_NOARGS, get_ident_doc},
Antoine Pitrou65c9c642009-10-30 17:25:12 +0000968 {"_count", (PyCFunction)thread__count,
969 METH_NOARGS, _count_doc},
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000970 {"stack_size", (PyCFunction)thread_stack_size,
971 METH_VARARGS,
972 stack_size_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000973#ifndef NO_EXIT_PROG
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000974 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
975 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000976#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000977 {NULL, NULL} /* sentinel */
978};
979
980
981/* Initialization function */
982
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000983PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000984"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000985The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000986
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000987PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000988"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000989call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000990\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000991acquire() -- lock the lock, possibly blocking until it can be obtained\n\
992release() -- unlock of the lock\n\
993locked() -- test whether the lock is currently locked\n\
994\n\
995A lock is not owned by the thread that locked it; another thread may\n\
996unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000997will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000998
Martin v. Löwis1a214512008-06-11 05:26:20 +0000999static struct PyModuleDef threadmodule = {
1000 PyModuleDef_HEAD_INIT,
1001 "_thread",
1002 thread_doc,
1003 -1,
1004 thread_methods,
1005 NULL,
1006 NULL,
1007 NULL,
1008 NULL
1009};
1010
1011
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001012PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001013PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001014{
Barry Warsawd0c10421996-12-17 00:05:22 +00001015 PyObject *m, *d;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +00001016
1017 /* Initialize types: */
1018 if (PyType_Ready(&localtype) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001019 return NULL;
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001020 if (PyType_Ready(&Locktype) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001021 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +00001022 if (PyType_Ready(&RLocktype) < 0)
1023 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001024
1025 /* Create the module and add the functions */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001026 m = PyModule_Create(&threadmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001027 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001028 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001029
1030 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +00001031 d = PyModule_GetDict(m);
Georg Brandl2067bfd2008-05-25 13:05:15 +00001032 ThreadError = PyErr_NewException("_thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +00001033 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001034 Locktype.tp_doc = lock_doc;
1035 Py_INCREF(&Locktype);
1036 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001037
Antoine Pitrou434736a2009-11-10 18:46:01 +00001038 Py_INCREF(&RLocktype);
1039 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1040 return NULL;
1041
Michael W. Hudson64e08142005-06-15 12:25:20 +00001042 Py_INCREF(&localtype);
Michael W. Hudson2368b3c2005-06-15 12:48:40 +00001043 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001044 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001045
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001046 nb_threads = 0;
1047
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001048 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +00001049 PyThread_init_thread();
Martin v. Löwis1a214512008-06-11 05:26:20 +00001050 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001051}