blob: b68c177f039ed0fd01bb77245a68b433233e15a3 [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;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +000018static PyObject *str_dict;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000019
Victor Stinnerbd303c12013-11-07 23:07:29 +010020_Py_IDENTIFIER(stderr);
21
Guido van Rossum1984f1e1992-08-04 12:41:02 +000022/* Lock objects */
23
24typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000025 PyObject_HEAD
26 PyThread_type_lock lock_lock;
27 PyObject *in_weakreflist;
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000028 char locked; /* for sanity checking */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000029} lockobject;
30
Guido van Rossum1984f1e1992-08-04 12:41:02 +000031static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000032lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000034 if (self->in_weakreflist != NULL)
35 PyObject_ClearWeakRefs((PyObject *) self);
36 if (self->lock_lock != NULL) {
37 /* Unlock the lock so it's safe to free it */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000038 if (self->locked)
39 PyThread_release_lock(self->lock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000040 PyThread_free_lock(self->lock_lock);
41 }
42 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000043}
44
Antoine Pitrou810023d2010-12-15 22:59:16 +000045/* Helper to acquire an interruptible lock with a timeout. If the lock acquire
46 * is interrupted, signal handlers are run, and if they raise an exception,
47 * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE
48 * are returned, depending on whether the lock can be acquired withing the
49 * timeout.
50 */
51static PyLockStatus
52acquire_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds)
53{
54 PyLockStatus r;
55 _PyTime_timeval curtime;
56 _PyTime_timeval endtime;
57
Brett Cannonb94767f2011-02-22 20:15:44 +000058
Antoine Pitrou810023d2010-12-15 22:59:16 +000059 if (microseconds > 0) {
Antoine Pitrou125d5c82011-03-06 08:40:35 +010060 _PyTime_gettimeofday(&endtime);
Antoine Pitrou810023d2010-12-15 22:59:16 +000061 endtime.tv_sec += microseconds / (1000 * 1000);
62 endtime.tv_usec += microseconds % (1000 * 1000);
63 }
64
65
66 do {
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +000067 /* first a simple non-blocking try without releasing the GIL */
68 r = PyThread_acquire_lock_timed(lock, 0, 0);
69 if (r == PY_LOCK_FAILURE && microseconds != 0) {
70 Py_BEGIN_ALLOW_THREADS
71 r = PyThread_acquire_lock_timed(lock, microseconds, 1);
72 Py_END_ALLOW_THREADS
Victor Stinner357f5152013-11-05 15:10:19 +010073 }
Antoine Pitrou810023d2010-12-15 22:59:16 +000074
75 if (r == PY_LOCK_INTR) {
76 /* Run signal handlers if we were interrupted. Propagate
77 * exceptions from signal handlers, such as KeyboardInterrupt, by
78 * passing up PY_LOCK_INTR. */
79 if (Py_MakePendingCalls() < 0) {
80 return PY_LOCK_INTR;
81 }
82
83 /* If we're using a timeout, recompute the timeout after processing
84 * signals, since those can take time. */
Antoine Pitrou125d5c82011-03-06 08:40:35 +010085 if (microseconds > 0) {
Antoine Pitrou810023d2010-12-15 22:59:16 +000086 _PyTime_gettimeofday(&curtime);
87 microseconds = ((endtime.tv_sec - curtime.tv_sec) * 1000000 +
88 (endtime.tv_usec - curtime.tv_usec));
89
90 /* Check for negative values, since those mean block forever.
91 */
92 if (microseconds <= 0) {
93 r = PY_LOCK_FAILURE;
94 }
95 }
96 }
97 } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */
98
99 return r;
100}
101
Barry Warsawd0c10421996-12-17 00:05:22 +0000102static PyObject *
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000103lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000104{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 char *kwlist[] = {"blocking", "timeout", NULL};
106 int blocking = 1;
107 double timeout = -1;
108 PY_TIMEOUT_T microseconds;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000109 PyLockStatus r;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist,
112 &blocking, &timeout))
113 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 if (!blocking && timeout != -1) {
116 PyErr_SetString(PyExc_ValueError, "can't specify a timeout "
117 "for a non-blocking call");
118 return NULL;
119 }
120 if (timeout < 0 && timeout != -1) {
121 PyErr_SetString(PyExc_ValueError, "timeout value must be "
122 "strictly positive");
123 return NULL;
124 }
125 if (!blocking)
126 microseconds = 0;
127 else if (timeout == -1)
128 microseconds = -1;
129 else {
130 timeout *= 1e6;
131 if (timeout >= (double) PY_TIMEOUT_MAX) {
132 PyErr_SetString(PyExc_OverflowError,
133 "timeout value is too large");
134 return NULL;
135 }
136 microseconds = (PY_TIMEOUT_T) timeout;
137 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000138
Antoine Pitrou810023d2010-12-15 22:59:16 +0000139 r = acquire_timed(self->lock_lock, microseconds);
140 if (r == PY_LOCK_INTR) {
141 return NULL;
142 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000143
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000144 if (r == PY_LOCK_ACQUIRED)
145 self->locked = 1;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000146 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000147}
148
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000149PyDoc_STRVAR(acquire_doc,
R David Murray95b71102013-02-04 10:15:58 -0500150"acquire([wait]) -> bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000151(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000152\n\
153Lock the lock. Without argument, this blocks if the lock is already\n\
154locked (even by the same thread), waiting for another thread to release\n\
R David Murray95b71102013-02-04 10:15:58 -0500155the lock, and return True once the lock is acquired.\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000156With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000157and the return value reflects whether the lock is acquired.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000158The blocking operation is interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000159
Barry Warsawd0c10421996-12-17 00:05:22 +0000160static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000161lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000162{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 /* Sanity check: the lock must be locked */
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000164 if (!self->locked) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 PyErr_SetString(ThreadError, "release unlocked lock");
166 return NULL;
167 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 PyThread_release_lock(self->lock_lock);
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000170 self->locked = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 Py_INCREF(Py_None);
172 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000173}
174
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000175PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000176"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +0000177(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000178\n\
179Release the lock, allowing another thread that is blocked waiting for\n\
180the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000181but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000182
Barry Warsawd0c10421996-12-17 00:05:22 +0000183static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000184lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000185{
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000186 return PyBool_FromLong((long)self->locked);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000187}
188
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000189PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000190"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000191(locked_lock() is an obsolete synonym)\n\
192\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000193Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000194
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700195static PyObject *
196lock_repr(lockobject *self)
197{
198 return PyUnicode_FromFormat("<%s %s object at %p>",
199 self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
200}
201
Barry Warsawd0c10421996-12-17 00:05:22 +0000202static PyMethodDef lock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
204 METH_VARARGS | METH_KEYWORDS, acquire_doc},
205 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
206 METH_VARARGS | METH_KEYWORDS, acquire_doc},
207 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
208 METH_NOARGS, release_doc},
209 {"release", (PyCFunction)lock_PyThread_release_lock,
210 METH_NOARGS, release_doc},
211 {"locked_lock", (PyCFunction)lock_locked_lock,
212 METH_NOARGS, locked_doc},
213 {"locked", (PyCFunction)lock_locked_lock,
214 METH_NOARGS, locked_doc},
215 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
216 METH_VARARGS | METH_KEYWORDS, acquire_doc},
217 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
218 METH_VARARGS, release_doc},
219 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000220};
221
Barry Warsawd0c10421996-12-17 00:05:22 +0000222static PyTypeObject Locktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000223 PyVarObject_HEAD_INIT(&PyType_Type, 0)
224 "_thread.lock", /*tp_name*/
225 sizeof(lockobject), /*tp_size*/
226 0, /*tp_itemsize*/
227 /* methods */
228 (destructor)lock_dealloc, /*tp_dealloc*/
229 0, /*tp_print*/
230 0, /*tp_getattr*/
231 0, /*tp_setattr*/
232 0, /*tp_reserved*/
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700233 (reprfunc)lock_repr, /*tp_repr*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 0, /*tp_as_number*/
235 0, /*tp_as_sequence*/
236 0, /*tp_as_mapping*/
237 0, /*tp_hash*/
238 0, /*tp_call*/
239 0, /*tp_str*/
240 0, /*tp_getattro*/
241 0, /*tp_setattro*/
242 0, /*tp_as_buffer*/
243 Py_TPFLAGS_DEFAULT, /*tp_flags*/
244 0, /*tp_doc*/
245 0, /*tp_traverse*/
246 0, /*tp_clear*/
247 0, /*tp_richcompare*/
248 offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
249 0, /*tp_iter*/
250 0, /*tp_iternext*/
251 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000252};
253
Antoine Pitrou434736a2009-11-10 18:46:01 +0000254/* Recursive lock objects */
255
256typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 PyObject_HEAD
258 PyThread_type_lock rlock_lock;
259 long rlock_owner;
260 unsigned long rlock_count;
261 PyObject *in_weakreflist;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000262} rlockobject;
263
264static void
265rlock_dealloc(rlockobject *self)
266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 if (self->in_weakreflist != NULL)
268 PyObject_ClearWeakRefs((PyObject *) self);
Victor Stinner357f5152013-11-05 15:10:19 +0100269 /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed
270 in rlock_new() */
271 if (self->rlock_lock != NULL) {
272 /* Unlock the lock so it's safe to free it */
273 if (self->rlock_count > 0)
274 PyThread_release_lock(self->rlock_lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275
Victor Stinner357f5152013-11-05 15:10:19 +0100276 PyThread_free_lock(self->rlock_lock);
277 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278 Py_TYPE(self)->tp_free(self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000279}
280
281static PyObject *
282rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 char *kwlist[] = {"blocking", "timeout", NULL};
285 int blocking = 1;
286 double timeout = -1;
287 PY_TIMEOUT_T microseconds;
288 long tid;
Antoine Pitrou810023d2010-12-15 22:59:16 +0000289 PyLockStatus r = PY_LOCK_ACQUIRED;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist,
292 &blocking, &timeout))
293 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 if (!blocking && timeout != -1) {
296 PyErr_SetString(PyExc_ValueError, "can't specify a timeout "
297 "for a non-blocking call");
298 return NULL;
299 }
300 if (timeout < 0 && timeout != -1) {
301 PyErr_SetString(PyExc_ValueError, "timeout value must be "
302 "strictly positive");
303 return NULL;
304 }
305 if (!blocking)
306 microseconds = 0;
307 else if (timeout == -1)
308 microseconds = -1;
309 else {
310 timeout *= 1e6;
311 if (timeout >= (double) PY_TIMEOUT_MAX) {
312 PyErr_SetString(PyExc_OverflowError,
313 "timeout value is too large");
314 return NULL;
315 }
316 microseconds = (PY_TIMEOUT_T) timeout;
317 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 tid = PyThread_get_thread_ident();
320 if (self->rlock_count > 0 && tid == self->rlock_owner) {
321 unsigned long count = self->rlock_count + 1;
322 if (count <= self->rlock_count) {
323 PyErr_SetString(PyExc_OverflowError,
324 "Internal lock count overflowed");
325 return NULL;
326 }
327 self->rlock_count = count;
328 Py_RETURN_TRUE;
329 }
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000330 r = acquire_timed(self->rlock_lock, microseconds);
Antoine Pitrou810023d2010-12-15 22:59:16 +0000331 if (r == PY_LOCK_ACQUIRED) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 assert(self->rlock_count == 0);
333 self->rlock_owner = tid;
334 self->rlock_count = 1;
335 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000336 else if (r == PY_LOCK_INTR) {
337 return NULL;
338 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339
Antoine Pitrou810023d2010-12-15 22:59:16 +0000340 return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000341}
342
343PyDoc_STRVAR(rlock_acquire_doc,
344"acquire(blocking=True) -> bool\n\
345\n\
346Lock the lock. `blocking` indicates whether we should wait\n\
347for the lock to be available or not. If `blocking` is False\n\
348and another thread holds the lock, the method will return False\n\
349immediately. If `blocking` is True and another thread holds\n\
350the lock, the method will wait for the lock to be released,\n\
351take it and then return True.\n\
Antoine Pitrou810023d2010-12-15 22:59:16 +0000352(note: the blocking operation is interruptible.)\n\
Antoine Pitrou434736a2009-11-10 18:46:01 +0000353\n\
354In all other cases, the method will return True immediately.\n\
355Precisely, if the current thread already holds the lock, its\n\
356internal counter is simply incremented. If nobody holds the lock,\n\
357the lock is taken and its internal counter initialized to 1.");
358
359static PyObject *
360rlock_release(rlockobject *self)
361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 long tid = PyThread_get_thread_ident();
Antoine Pitrou434736a2009-11-10 18:46:01 +0000363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 if (self->rlock_count == 0 || self->rlock_owner != tid) {
365 PyErr_SetString(PyExc_RuntimeError,
366 "cannot release un-acquired lock");
367 return NULL;
368 }
369 if (--self->rlock_count == 0) {
370 self->rlock_owner = 0;
371 PyThread_release_lock(self->rlock_lock);
372 }
373 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000374}
375
376PyDoc_STRVAR(rlock_release_doc,
377"release()\n\
378\n\
379Release the lock, allowing another thread that is blocked waiting for\n\
380the lock to acquire the lock. The lock must be in the locked state,\n\
381and must be locked by the same thread that unlocks it; otherwise a\n\
382`RuntimeError` is raised.\n\
383\n\
384Do note that if the lock was acquire()d several times in a row by the\n\
385current thread, release() needs to be called as many times for the lock\n\
386to be available for other threads.");
387
388static PyObject *
Victor Stinnere8794522014-01-02 12:47:24 +0100389rlock_acquire_restore(rlockobject *self, PyObject *args)
Antoine Pitrou434736a2009-11-10 18:46:01 +0000390{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 long owner;
392 unsigned long count;
393 int r = 1;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000394
Victor Stinnere8794522014-01-02 12:47:24 +0100395 if (!PyArg_ParseTuple(args, "(kl):_acquire_restore", &count, &owner))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 return NULL;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
399 Py_BEGIN_ALLOW_THREADS
400 r = PyThread_acquire_lock(self->rlock_lock, 1);
401 Py_END_ALLOW_THREADS
402 }
403 if (!r) {
404 PyErr_SetString(ThreadError, "couldn't acquire lock");
405 return NULL;
406 }
407 assert(self->rlock_count == 0);
408 self->rlock_owner = owner;
409 self->rlock_count = count;
410 Py_RETURN_NONE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000411}
412
413PyDoc_STRVAR(rlock_acquire_restore_doc,
414"_acquire_restore(state) -> None\n\
415\n\
416For internal use by `threading.Condition`.");
417
418static PyObject *
419rlock_release_save(rlockobject *self)
420{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 long owner;
422 unsigned long count;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000423
Victor Stinnerc2824d42011-04-24 23:41:33 +0200424 if (self->rlock_count == 0) {
425 PyErr_SetString(PyExc_RuntimeError,
426 "cannot release un-acquired lock");
427 return NULL;
428 }
429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000430 owner = self->rlock_owner;
431 count = self->rlock_count;
432 self->rlock_count = 0;
433 self->rlock_owner = 0;
434 PyThread_release_lock(self->rlock_lock);
435 return Py_BuildValue("kl", count, owner);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000436}
437
438PyDoc_STRVAR(rlock_release_save_doc,
439"_release_save() -> tuple\n\
440\n\
441For internal use by `threading.Condition`.");
442
443
444static PyObject *
445rlock_is_owned(rlockobject *self)
446{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 long tid = PyThread_get_thread_ident();
448
449 if (self->rlock_count > 0 && self->rlock_owner == tid) {
450 Py_RETURN_TRUE;
451 }
452 Py_RETURN_FALSE;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000453}
454
455PyDoc_STRVAR(rlock_is_owned_doc,
456"_is_owned() -> bool\n\
457\n\
458For internal use by `threading.Condition`.");
459
460static PyObject *
461rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 rlockobject *self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 self = (rlockobject *) type->tp_alloc(type, 0);
466 if (self != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 self->in_weakreflist = NULL;
468 self->rlock_owner = 0;
469 self->rlock_count = 0;
Victor Stinner357f5152013-11-05 15:10:19 +0100470
471 self->rlock_lock = PyThread_allocate_lock();
472 if (self->rlock_lock == NULL) {
473 Py_DECREF(self);
474 PyErr_SetString(ThreadError, "can't allocate lock");
475 return NULL;
476 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 }
Antoine Pitrou434736a2009-11-10 18:46:01 +0000478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 return (PyObject *) self;
Antoine Pitrou434736a2009-11-10 18:46:01 +0000480}
481
482static PyObject *
483rlock_repr(rlockobject *self)
484{
Raymond Hettinger62f4dad2014-05-25 18:22:35 -0700485 return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>",
486 self->rlock_count ? "locked" : "unlocked",
487 Py_TYPE(self)->tp_name, self->rlock_owner,
488 self->rlock_count, self);
Antoine Pitrou434736a2009-11-10 18:46:01 +0000489}
490
491
492static PyMethodDef rlock_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493 {"acquire", (PyCFunction)rlock_acquire,
494 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
495 {"release", (PyCFunction)rlock_release,
496 METH_NOARGS, rlock_release_doc},
497 {"_is_owned", (PyCFunction)rlock_is_owned,
498 METH_NOARGS, rlock_is_owned_doc},
499 {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
Victor Stinnere8794522014-01-02 12:47:24 +0100500 METH_VARARGS, rlock_acquire_restore_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 {"_release_save", (PyCFunction)rlock_release_save,
502 METH_NOARGS, rlock_release_save_doc},
503 {"__enter__", (PyCFunction)rlock_acquire,
504 METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
505 {"__exit__", (PyCFunction)rlock_release,
506 METH_VARARGS, rlock_release_doc},
507 {NULL, NULL} /* sentinel */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000508};
509
510
511static PyTypeObject RLocktype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 PyVarObject_HEAD_INIT(&PyType_Type, 0)
513 "_thread.RLock", /*tp_name*/
514 sizeof(rlockobject), /*tp_size*/
515 0, /*tp_itemsize*/
516 /* methods */
517 (destructor)rlock_dealloc, /*tp_dealloc*/
518 0, /*tp_print*/
519 0, /*tp_getattr*/
520 0, /*tp_setattr*/
521 0, /*tp_reserved*/
522 (reprfunc)rlock_repr, /*tp_repr*/
523 0, /*tp_as_number*/
524 0, /*tp_as_sequence*/
525 0, /*tp_as_mapping*/
526 0, /*tp_hash*/
527 0, /*tp_call*/
528 0, /*tp_str*/
529 0, /*tp_getattro*/
530 0, /*tp_setattro*/
531 0, /*tp_as_buffer*/
532 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
533 0, /*tp_doc*/
534 0, /*tp_traverse*/
535 0, /*tp_clear*/
536 0, /*tp_richcompare*/
537 offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
538 0, /*tp_iter*/
539 0, /*tp_iternext*/
540 rlock_methods, /*tp_methods*/
541 0, /* tp_members */
542 0, /* tp_getset */
543 0, /* tp_base */
544 0, /* tp_dict */
545 0, /* tp_descr_get */
546 0, /* tp_descr_set */
547 0, /* tp_dictoffset */
548 0, /* tp_init */
549 PyType_GenericAlloc, /* tp_alloc */
550 rlock_new /* tp_new */
Antoine Pitrou434736a2009-11-10 18:46:01 +0000551};
552
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000553static lockobject *
554newlockobject(void)
555{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 lockobject *self;
557 self = PyObject_New(lockobject, &Locktype);
558 if (self == NULL)
559 return NULL;
560 self->lock_lock = PyThread_allocate_lock();
Kristjan Valur Jonsson69cf9132012-06-22 18:40:02 +0000561 self->locked = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 self->in_weakreflist = NULL;
563 if (self->lock_lock == NULL) {
564 Py_DECREF(self);
565 PyErr_SetString(ThreadError, "can't allocate lock");
566 return NULL;
567 }
568 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000569}
570
Jim Fultond15dc062004-07-14 19:11:50 +0000571/* Thread-local objects */
572
573#include "structmember.h"
574
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000575/* Quick overview:
576
577 We need to be able to reclaim reference cycles as soon as possible
578 (both when a thread is being terminated, or a thread-local object
579 becomes unreachable from user data). Constraints:
580 - it must not be possible for thread-state dicts to be involved in
581 reference cycles (otherwise the cyclic GC will refuse to consider
582 objects referenced from a reachable thread-state dict, even though
583 local_dealloc would clear them)
584 - the death of a thread-state dict must still imply destruction of the
585 corresponding local dicts in all thread-local objects.
586
587 Our implementation uses small "localdummy" objects in order to break
588 the reference chain. These trivial objects are hashable (using the
589 default scheme of identity hashing) and weakrefable.
590 Each thread-state holds a separate localdummy for each local object
591 (as a /strong reference/),
592 and each thread-local object holds a dict mapping /weak references/
593 of localdummies to local dicts.
594
595 Therefore:
596 - only the thread-state dict holds a strong reference to the dummies
597 - only the thread-local object holds a strong reference to the local dicts
598 - only outside objects (application- or library-level) hold strong
599 references to the thread-local objects
600 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
601 dummies attached to that thread are called, and destroy the corresponding
602 local dicts from thread-local objects
603 - as soon as a thread-local object is destroyed, its local dicts are
604 destroyed and its dummies are manually removed from all thread states
605 - the GC can do its work correctly when a thread-local object is dangling,
606 without any interference from the thread-state dicts
607
608 As an additional optimization, each localdummy holds a borrowed reference
609 to the corresponding localdict. This borrowed reference is only used
610 by the thread-local object which has created the localdummy, which should
611 guarantee that the localdict still exists when accessed.
612*/
613
614typedef struct {
615 PyObject_HEAD
616 PyObject *localdict; /* Borrowed reference! */
617 PyObject *weakreflist; /* List of weak references to self */
618} localdummyobject;
619
620static void
621localdummy_dealloc(localdummyobject *self)
622{
623 if (self->weakreflist != NULL)
624 PyObject_ClearWeakRefs((PyObject *) self);
625 Py_TYPE(self)->tp_free((PyObject*)self);
626}
627
628static PyTypeObject localdummytype = {
629 PyVarObject_HEAD_INIT(NULL, 0)
630 /* tp_name */ "_thread._localdummy",
631 /* tp_basicsize */ sizeof(localdummyobject),
632 /* tp_itemsize */ 0,
633 /* tp_dealloc */ (destructor)localdummy_dealloc,
634 /* tp_print */ 0,
635 /* tp_getattr */ 0,
636 /* tp_setattr */ 0,
637 /* tp_reserved */ 0,
638 /* tp_repr */ 0,
639 /* tp_as_number */ 0,
640 /* tp_as_sequence */ 0,
641 /* tp_as_mapping */ 0,
642 /* tp_hash */ 0,
643 /* tp_call */ 0,
644 /* tp_str */ 0,
645 /* tp_getattro */ 0,
646 /* tp_setattro */ 0,
647 /* tp_as_buffer */ 0,
648 /* tp_flags */ Py_TPFLAGS_DEFAULT,
649 /* tp_doc */ "Thread-local dummy",
650 /* tp_traverse */ 0,
651 /* tp_clear */ 0,
652 /* tp_richcompare */ 0,
653 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
654};
655
656
Jim Fultond15dc062004-07-14 19:11:50 +0000657typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 PyObject_HEAD
659 PyObject *key;
660 PyObject *args;
661 PyObject *kw;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000662 PyObject *weakreflist; /* List of weak references to self */
663 /* A {localdummy weakref -> localdict} dict */
664 PyObject *dummies;
665 /* The callback for weakrefs to localdummies */
666 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000667} localobject;
668
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000669/* Forward declaration */
670static PyObject *_ldict(localobject *self);
671static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
672
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000673/* Create and register the dummy for the current thread.
674 Returns a borrowed reference of the corresponding local dict */
675static PyObject *
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000676_local_create_dummy(localobject *self)
677{
678 PyObject *tdict, *ldict = NULL, *wr = NULL;
679 localdummyobject *dummy = NULL;
680 int r;
681
682 tdict = PyThreadState_GetDict();
683 if (tdict == NULL) {
684 PyErr_SetString(PyExc_SystemError,
685 "Couldn't get thread-state dictionary");
686 goto err;
687 }
688
689 ldict = PyDict_New();
690 if (ldict == NULL)
691 goto err;
692 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
693 if (dummy == NULL)
694 goto err;
695 dummy->localdict = ldict;
696 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
697 if (wr == NULL)
698 goto err;
699
700 /* As a side-effect, this will cache the weakref's hash before the
701 dummy gets deleted */
702 r = PyDict_SetItem(self->dummies, wr, ldict);
703 if (r < 0)
704 goto err;
705 Py_CLEAR(wr);
706 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
707 if (r < 0)
708 goto err;
709 Py_CLEAR(dummy);
710
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000711 Py_DECREF(ldict);
712 return ldict;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000713
714err:
715 Py_XDECREF(ldict);
716 Py_XDECREF(wr);
717 Py_XDECREF(dummy);
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000718 return NULL;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000719}
720
Jim Fultond15dc062004-07-14 19:11:50 +0000721static PyObject *
722local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
723{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 localobject *self;
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000725 PyObject *wr;
726 static PyMethodDef wr_callback_def = {
727 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
728 };
Jim Fultond15dc062004-07-14 19:11:50 +0000729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 if (type->tp_init == PyBaseObject_Type.tp_init
731 && ((args && PyObject_IsTrue(args))
732 || (kw && PyObject_IsTrue(kw)))) {
733 PyErr_SetString(PyExc_TypeError,
734 "Initialization arguments are not supported");
735 return NULL;
736 }
Jim Fultond15dc062004-07-14 19:11:50 +0000737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 self = (localobject *)type->tp_alloc(type, 0);
739 if (self == NULL)
740 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 Py_XINCREF(args);
743 self->args = args;
744 Py_XINCREF(kw);
745 self->kw = kw;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 self->key = PyUnicode_FromFormat("thread.local.%p", self);
747 if (self->key == NULL)
748 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000749
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000750 self->dummies = PyDict_New();
751 if (self->dummies == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000752 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000753
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000754 /* We use a weak reference to self in the callback closure
755 in order to avoid spurious reference cycles */
756 wr = PyWeakref_NewRef((PyObject *) self, NULL);
757 if (wr == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 goto err;
Andrew Svetlov3ba3a3e2012-12-25 13:32:35 +0200759 self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000760 Py_DECREF(wr);
761 if (self->wr_callback == NULL)
762 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000763
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000764 if (_local_create_dummy(self) == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000766
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000767 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000768
769 err:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000770 Py_DECREF(self);
771 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000772}
773
774static int
775local_traverse(localobject *self, visitproc visit, void *arg)
776{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000777 Py_VISIT(self->args);
778 Py_VISIT(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000779 Py_VISIT(self->dummies);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000780 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000781}
782
783static int
784local_clear(localobject *self)
785{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000786 PyThreadState *tstate;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 Py_CLEAR(self->args);
788 Py_CLEAR(self->kw);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000789 Py_CLEAR(self->dummies);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000790 Py_CLEAR(self->wr_callback);
791 /* Remove all strong references to dummies from the thread states */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000792 if (self->key
793 && (tstate = PyThreadState_Get())
794 && tstate->interp) {
795 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
796 tstate;
797 tstate = PyThreadState_Next(tstate))
798 if (tstate->dict &&
799 PyDict_GetItem(tstate->dict, self->key))
800 PyDict_DelItem(tstate->dict, self->key);
801 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000802 return 0;
803}
Jim Fultond15dc062004-07-14 19:11:50 +0000804
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000805static void
806local_dealloc(localobject *self)
807{
808 /* Weakrefs must be invalidated right now, otherwise they can be used
809 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
810 if (self->weakreflist != NULL)
811 PyObject_ClearWeakRefs((PyObject *) self);
812
813 PyObject_GC_UnTrack(self);
814
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000815 local_clear(self);
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000816 Py_XDECREF(self->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000817 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000818}
819
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000820/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000821static PyObject *
822_ldict(localobject *self)
823{
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000824 PyObject *tdict, *ldict, *dummy;
Jim Fultond15dc062004-07-14 19:11:50 +0000825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 tdict = PyThreadState_GetDict();
827 if (tdict == NULL) {
828 PyErr_SetString(PyExc_SystemError,
829 "Couldn't get thread-state dictionary");
830 return NULL;
831 }
Jim Fultond15dc062004-07-14 19:11:50 +0000832
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000833 dummy = PyDict_GetItem(tdict, self->key);
834 if (dummy == NULL) {
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000835 ldict = _local_create_dummy(self);
836 if (ldict == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000837 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000839 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
840 Py_TYPE(self)->tp_init((PyObject*)self,
841 self->args, self->kw) < 0) {
842 /* we need to get rid of ldict from thread so
843 we create a new one the next time we do an attr
Ezio Melotti42da6632011-03-15 05:18:48 +0200844 access */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000845 PyDict_DelItem(tdict, self->key);
846 return NULL;
847 }
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000848 }
849 else {
850 assert(Py_TYPE(dummy) == &localdummytype);
851 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000852 }
Jim Fultond15dc062004-07-14 19:11:50 +0000853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000855}
856
Jim Fultond15dc062004-07-14 19:11:50 +0000857static int
858local_setattro(localobject *self, PyObject *name, PyObject *v)
859{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 PyObject *ldict;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000861 int r;
Jim Fultond15dc062004-07-14 19:11:50 +0000862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 ldict = _ldict(self);
864 if (ldict == NULL)
865 return -1;
866
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000867 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
868 if (r == 1) {
869 PyErr_Format(PyExc_AttributeError,
870 "'%.50s' object attribute '%U' is read-only",
871 Py_TYPE(self)->tp_name, name);
872 return -1;
873 }
874 if (r == -1)
875 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000876
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000877 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000878}
879
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000880static PyObject *local_getattro(localobject *, PyObject *);
881
Jim Fultond15dc062004-07-14 19:11:50 +0000882static PyTypeObject localtype = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000883 PyVarObject_HEAD_INIT(NULL, 0)
884 /* tp_name */ "_thread._local",
885 /* tp_basicsize */ sizeof(localobject),
886 /* tp_itemsize */ 0,
887 /* tp_dealloc */ (destructor)local_dealloc,
888 /* tp_print */ 0,
889 /* tp_getattr */ 0,
890 /* tp_setattr */ 0,
891 /* tp_reserved */ 0,
892 /* tp_repr */ 0,
893 /* tp_as_number */ 0,
894 /* tp_as_sequence */ 0,
895 /* tp_as_mapping */ 0,
896 /* tp_hash */ 0,
897 /* tp_call */ 0,
898 /* tp_str */ 0,
899 /* tp_getattro */ (getattrofunc)local_getattro,
900 /* tp_setattro */ (setattrofunc)local_setattro,
901 /* tp_as_buffer */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000902 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
903 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000904 /* tp_doc */ "Thread-local data",
905 /* tp_traverse */ (traverseproc)local_traverse,
906 /* tp_clear */ (inquiry)local_clear,
907 /* tp_richcompare */ 0,
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000908 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000909 /* tp_iter */ 0,
910 /* tp_iternext */ 0,
911 /* tp_methods */ 0,
912 /* tp_members */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000913 /* tp_getset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000914 /* tp_base */ 0,
915 /* tp_dict */ 0, /* internal use */
916 /* tp_descr_get */ 0,
917 /* tp_descr_set */ 0,
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000918 /* tp_dictoffset */ 0,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000919 /* tp_init */ 0,
920 /* tp_alloc */ 0,
921 /* tp_new */ local_new,
922 /* tp_free */ 0, /* Low-level free-mem routine */
923 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000924};
925
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000926static PyObject *
927local_getattro(localobject *self, PyObject *name)
928{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000929 PyObject *ldict, *value;
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000930 int r;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000932 ldict = _ldict(self);
933 if (ldict == NULL)
934 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000935
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000936 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
937 if (r == 1) {
938 Py_INCREF(ldict);
939 return ldict;
940 }
941 if (r == -1)
942 return NULL;
943
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000944 if (Py_TYPE(self) != &localtype)
945 /* use generic lookup for subtypes */
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000946 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 /* Optimization: just look in dict ourselves */
949 value = PyDict_GetItem(ldict, name);
950 if (value == NULL)
951 /* Fall back on generic to get __class__ and __dict__ */
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +0000952 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 Py_INCREF(value);
955 return value;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000956}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000957
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000958/* Called when a dummy is destroyed. */
959static PyObject *
960_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
961{
962 PyObject *obj;
963 localobject *self;
964 assert(PyWeakref_CheckRef(localweakref));
965 obj = PyWeakref_GET_OBJECT(localweakref);
966 if (obj == Py_None)
967 Py_RETURN_NONE;
968 Py_INCREF(obj);
969 assert(PyObject_TypeCheck(obj, &localtype));
970 /* If the thread-local object is still alive and not being cleared,
971 remove the corresponding local dict */
972 self = (localobject *) obj;
973 if (self->dummies != NULL) {
974 PyObject *ldict;
975 ldict = PyDict_GetItem(self->dummies, dummyweakref);
976 if (ldict != NULL) {
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +0000977 PyDict_DelItem(self->dummies, dummyweakref);
978 }
979 if (PyErr_Occurred())
980 PyErr_WriteUnraisable(obj);
981 }
982 Py_DECREF(obj);
983 Py_RETURN_NONE;
984}
985
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000986/* Module functions */
987
Guido van Rossuma027efa1997-05-05 20:56:21 +0000988struct bootstate {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 PyInterpreterState *interp;
990 PyObject *func;
991 PyObject *args;
992 PyObject *keyw;
993 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000994};
995
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000996static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000997t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000998{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 struct bootstate *boot = (struct bootstate *) boot_raw;
1000 PyThreadState *tstate;
1001 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 tstate = boot->tstate;
1004 tstate->thread_id = PyThread_get_thread_ident();
1005 _PyThreadState_Init(tstate);
1006 PyEval_AcquireThread(tstate);
1007 nb_threads++;
1008 res = PyEval_CallObjectWithKeywords(
1009 boot->func, boot->args, boot->keyw);
1010 if (res == NULL) {
1011 if (PyErr_ExceptionMatches(PyExc_SystemExit))
1012 PyErr_Clear();
1013 else {
1014 PyObject *file;
Benjamin Petersone9000962012-04-02 11:15:17 -04001015 PyObject *exc, *value, *tb;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 PySys_WriteStderr(
1017 "Unhandled exception in thread started by ");
Benjamin Petersone9000962012-04-02 11:15:17 -04001018 PyErr_Fetch(&exc, &value, &tb);
Victor Stinnerbd303c12013-11-07 23:07:29 +01001019 file = _PySys_GetObjectId(&PyId_stderr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 if (file != NULL && file != Py_None)
1021 PyFile_WriteObject(boot->func, file, 0);
1022 else
1023 PyObject_Print(boot->func, stderr, 0);
1024 PySys_WriteStderr("\n");
Benjamin Petersone9000962012-04-02 11:15:17 -04001025 PyErr_Restore(exc, value, tb);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 PyErr_PrintEx(0);
1027 }
1028 }
1029 else
1030 Py_DECREF(res);
1031 Py_DECREF(boot->func);
1032 Py_DECREF(boot->args);
1033 Py_XDECREF(boot->keyw);
1034 PyMem_DEL(boot_raw);
1035 nb_threads--;
1036 PyThreadState_Clear(tstate);
1037 PyThreadState_DeleteCurrent();
1038 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001039}
1040
Barry Warsawd0c10421996-12-17 00:05:22 +00001041static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +00001042thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001043{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 PyObject *func, *args, *keyw = NULL;
1045 struct bootstate *boot;
1046 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
1049 &func, &args, &keyw))
1050 return NULL;
1051 if (!PyCallable_Check(func)) {
1052 PyErr_SetString(PyExc_TypeError,
1053 "first arg must be callable");
1054 return NULL;
1055 }
1056 if (!PyTuple_Check(args)) {
1057 PyErr_SetString(PyExc_TypeError,
1058 "2nd arg must be a tuple");
1059 return NULL;
1060 }
1061 if (keyw != NULL && !PyDict_Check(keyw)) {
1062 PyErr_SetString(PyExc_TypeError,
1063 "optional 3rd arg must be a dictionary");
1064 return NULL;
1065 }
1066 boot = PyMem_NEW(struct bootstate, 1);
1067 if (boot == NULL)
1068 return PyErr_NoMemory();
1069 boot->interp = PyThreadState_GET()->interp;
1070 boot->func = func;
1071 boot->args = args;
1072 boot->keyw = keyw;
1073 boot->tstate = _PyThreadState_Prealloc(boot->interp);
1074 if (boot->tstate == NULL) {
1075 PyMem_DEL(boot);
1076 return PyErr_NoMemory();
1077 }
1078 Py_INCREF(func);
1079 Py_INCREF(args);
1080 Py_XINCREF(keyw);
1081 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
1082 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
1083 if (ident == -1) {
1084 PyErr_SetString(ThreadError, "can't start new thread");
1085 Py_DECREF(func);
1086 Py_DECREF(args);
1087 Py_XDECREF(keyw);
1088 PyThreadState_Clear(boot->tstate);
1089 PyMem_DEL(boot);
1090 return NULL;
1091 }
1092 return PyLong_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001093}
1094
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001095PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +00001096"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001097(start_new() is an obsolete synonym)\n\
1098\n\
Guido van Rossum3c288632001-10-16 21:13:49 +00001099Start a new thread and return its identifier. The thread will call the\n\
1100function with positional arguments from the tuple args and keyword arguments\n\
1101taken from the optional dictionary kwargs. The thread exits when the\n\
1102function returns; the return value is ignored. The thread will also exit\n\
1103when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001104printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001105
Barry Warsawd0c10421996-12-17 00:05:22 +00001106static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001107thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001108{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001109 PyErr_SetNone(PyExc_SystemExit);
1110 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001111}
1112
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001113PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001114"exit()\n\
Éric Araujo9bcf8bf2011-05-31 14:08:26 +02001115(exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001116\n\
1117This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001118thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001119
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001120static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001121thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001122{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 PyErr_SetInterrupt();
1124 Py_INCREF(Py_None);
1125 return Py_None;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001126}
1127
1128PyDoc_STRVAR(interrupt_doc,
1129"interrupt_main()\n\
1130\n\
1131Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +00001132A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +00001133);
1134
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001135static lockobject *newlockobject(void);
1136
Barry Warsawd0c10421996-12-17 00:05:22 +00001137static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001138thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001139{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001141}
1142
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001143PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001144"allocate_lock() -> lock object\n\
1145(allocate() is an obsolete synonym)\n\
1146\n\
Alexander Belopolsky977a6842010-08-16 20:17:07 +00001147Create a new lock object. See help(LockType) for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001148
Barry Warsawd0c10421996-12-17 00:05:22 +00001149static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +00001150thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 long ident;
1153 ident = PyThread_get_thread_ident();
1154 if (ident == -1) {
1155 PyErr_SetString(ThreadError, "no current thread ident");
1156 return NULL;
1157 }
1158 return PyLong_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001159}
1160
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001161PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001162"get_ident() -> integer\n\
1163\n\
1164Return a non-zero integer that uniquely identifies the current thread\n\
1165amongst other threads that exist simultaneously.\n\
1166This may be used to identify per-thread resources.\n\
1167Even though on some platforms threads identities may appear to be\n\
1168allocated consecutive numbers starting at 1, this behavior should not\n\
1169be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001170A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001171
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001172static PyObject *
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001173thread__count(PyObject *self)
1174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 return PyLong_FromLong(nb_threads);
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001176}
1177
1178PyDoc_STRVAR(_count_doc,
1179"_count() -> integer\n\
1180\n\
Antoine Pitrou9257f5e2009-10-30 22:23:02 +00001181\
1182Return the number of currently running Python threads, excluding \n\
1183the main thread. The returned number comprises all threads created\n\
1184through `start_new_thread()` as well as `threading.Thread`, and not\n\
1185yet finished.\n\
1186\n\
1187This function is meant for internal and specialized purposes only.\n\
1188In most applications `threading.enumerate()` should be used instead.");
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001189
Antoine Pitrou7b476992013-09-07 23:38:37 +02001190static void
1191release_sentinel(void *wr)
1192{
1193 /* Tricky: this function is called when the current thread state
1194 is being deleted. Therefore, only simple C code can safely
1195 execute here. */
1196 PyObject *obj = PyWeakref_GET_OBJECT(wr);
1197 lockobject *lock;
1198 if (obj != Py_None) {
1199 assert(Py_TYPE(obj) == &Locktype);
1200 lock = (lockobject *) obj;
1201 if (lock->locked) {
1202 PyThread_release_lock(lock->lock_lock);
1203 lock->locked = 0;
1204 }
1205 }
1206 /* Deallocating a weakref with a NULL callback only calls
1207 PyObject_GC_Del(), which can't call any Python code. */
1208 Py_DECREF(wr);
1209}
1210
1211static PyObject *
1212thread__set_sentinel(PyObject *self)
1213{
1214 PyObject *wr;
1215 PyThreadState *tstate = PyThreadState_Get();
1216 lockobject *lock;
1217
1218 if (tstate->on_delete_data != NULL) {
1219 /* We must support the re-creation of the lock from a
1220 fork()ed child. */
1221 assert(tstate->on_delete == &release_sentinel);
1222 wr = (PyObject *) tstate->on_delete_data;
1223 tstate->on_delete = NULL;
1224 tstate->on_delete_data = NULL;
1225 Py_DECREF(wr);
1226 }
1227 lock = newlockobject();
1228 if (lock == NULL)
1229 return NULL;
1230 /* The lock is owned by whoever called _set_sentinel(), but the weakref
1231 hangs to the thread state. */
1232 wr = PyWeakref_NewRef((PyObject *) lock, NULL);
1233 if (wr == NULL) {
1234 Py_DECREF(lock);
1235 return NULL;
1236 }
1237 tstate->on_delete_data = (void *) wr;
1238 tstate->on_delete = &release_sentinel;
1239 return (PyObject *) lock;
1240}
1241
1242PyDoc_STRVAR(_set_sentinel_doc,
1243"_set_sentinel() -> lock\n\
1244\n\
1245Set a sentinel lock that will be released when the current thread\n\
1246state is finalized (after it is untied from the interpreter).\n\
1247\n\
1248This is a private API for the threading module.");
1249
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001250static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001251thread_stack_size(PyObject *self, PyObject *args)
1252{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 size_t old_size;
1254 Py_ssize_t new_size = 0;
1255 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
1258 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 if (new_size < 0) {
1261 PyErr_SetString(PyExc_ValueError,
1262 "size must be 0 or a positive value");
1263 return NULL;
1264 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 rc = PyThread_set_stacksize((size_t) new_size);
1269 if (rc == -1) {
1270 PyErr_Format(PyExc_ValueError,
1271 "size not valid: %zd bytes",
1272 new_size);
1273 return NULL;
1274 }
1275 if (rc == -2) {
1276 PyErr_SetString(ThreadError,
1277 "setting stack size not supported");
1278 return NULL;
1279 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001282}
1283
1284PyDoc_STRVAR(stack_size_doc,
1285"stack_size([size]) -> size\n\
1286\n\
1287Return the thread stack size used when creating new threads. The\n\
1288optional size argument specifies the stack size (in bytes) to be used\n\
1289for subsequently created threads, and must be 0 (use platform or\n\
1290configured default) or a positive integer value of at least 32,768 (32k).\n\
1291If changing the thread stack size is unsupported, a ThreadError\n\
1292exception is raised. If the specified size is invalid, a ValueError\n\
1293exception is raised, and the stack size is unmodified. 32k bytes\n\
1294 currently the minimum supported stack size value to guarantee\n\
1295sufficient stack space for the interpreter itself.\n\
1296\n\
1297Note that some platforms may have particular restrictions on values for\n\
1298the stack size, such as requiring a minimum stack size larger than 32kB or\n\
1299requiring allocation in multiples of the system memory page size\n\
1300- platform documentation should be referred to for more information\n\
1301(4kB pages are common; using multiples of 4096 for the stack size is\n\
1302the suggested approach in the absence of more specific information).");
1303
Barry Warsawd0c10421996-12-17 00:05:22 +00001304static PyMethodDef thread_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001306 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
Victor Stinner754851f2011-04-19 23:58:51 +02001308 METH_VARARGS, start_new_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
1310 METH_NOARGS, allocate_doc},
1311 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
1312 METH_NOARGS, allocate_doc},
1313 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
1314 METH_NOARGS, exit_doc},
1315 {"exit", (PyCFunction)thread_PyThread_exit_thread,
1316 METH_NOARGS, exit_doc},
1317 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
1318 METH_NOARGS, interrupt_doc},
1319 {"get_ident", (PyCFunction)thread_get_ident,
1320 METH_NOARGS, get_ident_doc},
1321 {"_count", (PyCFunction)thread__count,
1322 METH_NOARGS, _count_doc},
1323 {"stack_size", (PyCFunction)thread_stack_size,
Victor Stinner754851f2011-04-19 23:58:51 +02001324 METH_VARARGS, stack_size_doc},
Antoine Pitrou7b476992013-09-07 23:38:37 +02001325 {"_set_sentinel", (PyCFunction)thread__set_sentinel,
1326 METH_NOARGS, _set_sentinel_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001328};
1329
1330
1331/* Initialization function */
1332
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001333PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001334"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001335The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001336
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001337PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001338"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +00001339call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001340\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001341acquire() -- lock the lock, possibly blocking until it can be obtained\n\
1342release() -- unlock of the lock\n\
1343locked() -- test whether the lock is currently locked\n\
1344\n\
1345A lock is not owned by the thread that locked it; another thread may\n\
1346unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001347will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +00001348
Martin v. Löwis1a214512008-06-11 05:26:20 +00001349static struct PyModuleDef threadmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350 PyModuleDef_HEAD_INIT,
1351 "_thread",
1352 thread_doc,
1353 -1,
1354 thread_methods,
1355 NULL,
1356 NULL,
1357 NULL,
1358 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001359};
1360
1361
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001362PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001363PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001364{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 PyObject *m, *d, *timeout_max;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 /* Initialize types: */
Antoine Pitrou5af4f4b2010-08-09 22:38:19 +00001368 if (PyType_Ready(&localdummytype) < 0)
1369 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 if (PyType_Ready(&localtype) < 0)
1371 return NULL;
1372 if (PyType_Ready(&Locktype) < 0)
1373 return NULL;
1374 if (PyType_Ready(&RLocktype) < 0)
1375 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 /* Create the module and add the functions */
1378 m = PyModule_Create(&threadmodule);
1379 if (m == NULL)
1380 return NULL;
Antoine Pitrou7c3e5772010-04-14 15:44:10 +00001381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 timeout_max = PyFloat_FromDouble(PY_TIMEOUT_MAX / 1000000);
1383 if (!timeout_max)
1384 return NULL;
1385 if (PyModule_AddObject(m, "TIMEOUT_MAX", timeout_max) < 0)
1386 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 /* Add a symbolic constant */
1389 d = PyModule_GetDict(m);
Antoine Pitroufcf81fd2011-02-28 22:03:34 +00001390 ThreadError = PyExc_RuntimeError;
1391 Py_INCREF(ThreadError);
Victor Stinner754851f2011-04-19 23:58:51 +02001392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 PyDict_SetItemString(d, "error", ThreadError);
1394 Locktype.tp_doc = lock_doc;
1395 Py_INCREF(&Locktype);
1396 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Antoine Pitrou434736a2009-11-10 18:46:01 +00001397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001398 Py_INCREF(&RLocktype);
1399 if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
1400 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +00001401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 Py_INCREF(&localtype);
1403 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
1404 return NULL;
Antoine Pitrou65c9c642009-10-30 17:25:12 +00001405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 nb_threads = 0;
1407
Antoine Pitrou1a9a9d52010-08-28 18:17:03 +00001408 str_dict = PyUnicode_InternFromString("__dict__");
1409 if (str_dict == NULL)
1410 return NULL;
1411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 /* Initialize the C thread library */
1413 PyThread_init_thread();
1414 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001415}