blob: d4a74c8afab2b21f5f92c0fa42f0c8466710595c [file] [log] [blame]
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001
2/* Thread module */
3/* Interface to Sjoerd's portable C thread library */
4
Barry Warsawd0c10421996-12-17 00:05:22 +00005#include "Python.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +00006
Guido van Rossumb6775db1994-08-01 11:34:53 +00007#ifndef WITH_THREAD
Guido van Rossuma027efa1997-05-05 20:56:21 +00008#error "Error! The rest of Python is not compiled with thread support."
Neal Norwitz884baa12002-09-05 21:31:04 +00009#error "Rerun configure, adding a --with-threads option."
Guido van Rossuma027efa1997-05-05 20:56:21 +000010#error "Then run `make clean' followed by `make'."
Guido van Rossumb6775db1994-08-01 11:34:53 +000011#endif
12
Guido van Rossum49b56061998-10-01 20:42:43 +000013#include "pythread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000014
Barry Warsawd0c10421996-12-17 00:05:22 +000015static PyObject *ThreadError;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000016
17
18/* Lock objects */
19
20typedef struct {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000021 PyObject_HEAD
22 PyThread_type_lock lock_lock;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000023} lockobject;
24
Guido van Rossum1984f1e1992-08-04 12:41:02 +000025static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000026lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000027{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000028 if (self->lock_lock != NULL) {
29 /* Unlock the lock so it's safe to free it */
30 PyThread_acquire_lock(self->lock_lock, 0);
31 PyThread_release_lock(self->lock_lock);
32
33 PyThread_free_lock(self->lock_lock);
34 }
35 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000036}
37
Barry Warsawd0c10421996-12-17 00:05:22 +000038static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000039lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000040{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000041 int i = 1;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000042
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000043 if (!PyArg_ParseTuple(args, "|i:acquire", &i))
44 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000045
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000046 Py_BEGIN_ALLOW_THREADS
47 i = PyThread_acquire_lock(self->lock_lock, i);
48 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +000049
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000050 return PyBool_FromLong((long)i);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000051}
52
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000053PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000054"acquire([wait]) -> None or bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000055(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000056\n\
57Lock the lock. Without argument, this blocks if the lock is already\n\
58locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000059the lock, and return None once the lock is acquired.\n\
60With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000061and the return value reflects whether the lock is acquired.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000062The blocking operation is not interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000063
Barry Warsawd0c10421996-12-17 00:05:22 +000064static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000065lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000066{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000067 /* Sanity check: the lock must be locked */
68 if (PyThread_acquire_lock(self->lock_lock, 0)) {
69 PyThread_release_lock(self->lock_lock);
70 PyErr_SetString(ThreadError, "release unlocked lock");
71 return NULL;
72 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +000073
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000074 PyThread_release_lock(self->lock_lock);
75 Py_INCREF(Py_None);
76 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000077}
78
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000079PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +000080"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000081(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000082\n\
83Release the lock, allowing another thread that is blocked waiting for\n\
84the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000085but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000086
Barry Warsawd0c10421996-12-17 00:05:22 +000087static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000088lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000089{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000090 if (PyThread_acquire_lock(self->lock_lock, 0)) {
91 PyThread_release_lock(self->lock_lock);
92 return PyBool_FromLong(0L);
93 }
94 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000095}
96
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000097PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000098"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000099(locked_lock() is an obsolete synonym)\n\
100\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000101Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000102
Barry Warsawd0c10421996-12-17 00:05:22 +0000103static PyMethodDef lock_methods[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000104 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
105 METH_VARARGS, acquire_doc},
106 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
107 METH_VARARGS, acquire_doc},
108 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
109 METH_NOARGS, release_doc},
110 {"release", (PyCFunction)lock_PyThread_release_lock,
111 METH_NOARGS, release_doc},
112 {"locked_lock", (PyCFunction)lock_locked_lock,
113 METH_NOARGS, locked_doc},
114 {"locked", (PyCFunction)lock_locked_lock,
115 METH_NOARGS, locked_doc},
116 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
117 METH_VARARGS, acquire_doc},
118 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
119 METH_VARARGS, release_doc},
120 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000121};
122
Barry Warsawd0c10421996-12-17 00:05:22 +0000123static PyTypeObject Locktype = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000124 PyVarObject_HEAD_INIT(&PyType_Type, 0)
125 "_thread.lock", /*tp_name*/
126 sizeof(lockobject), /*tp_size*/
127 0, /*tp_itemsize*/
128 /* methods */
129 (destructor)lock_dealloc, /*tp_dealloc*/
130 0, /*tp_print*/
131 0, /*tp_getattr*/
132 0, /*tp_setattr*/
133 0, /*tp_reserved*/
134 0, /*tp_repr*/
135 0, /*tp_as_number*/
136 0, /*tp_as_sequence*/
137 0, /*tp_as_mapping*/
138 0, /*tp_hash*/
139 0, /*tp_call*/
140 0, /*tp_str*/
141 0, /*tp_getattro*/
142 0, /*tp_setattro*/
143 0, /*tp_as_buffer*/
144 Py_TPFLAGS_DEFAULT, /*tp_flags*/
145 0, /*tp_doc*/
146 0, /*tp_traverse*/
147 0, /*tp_clear*/
148 0, /*tp_richcompare*/
149 0, /*tp_weaklistoffset*/
150 0, /*tp_iter*/
151 0, /*tp_iternext*/
152 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000153};
154
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000155static lockobject *
156newlockobject(void)
157{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000158 lockobject *self;
159 self = PyObject_New(lockobject, &Locktype);
160 if (self == NULL)
161 return NULL;
162 self->lock_lock = PyThread_allocate_lock();
163 if (self->lock_lock == NULL) {
164 Py_DECREF(self);
165 PyErr_SetString(ThreadError, "can't allocate lock");
166 return NULL;
167 }
168 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000169}
170
Jim Fultond15dc062004-07-14 19:11:50 +0000171/* Thread-local objects */
172
173#include "structmember.h"
174
Antoine Pitrou87d52602010-08-09 22:41:38 +0000175/* Quick overview:
176
177 We need to be able to reclaim reference cycles as soon as possible
178 (both when a thread is being terminated, or a thread-local object
179 becomes unreachable from user data). Constraints:
180 - it must not be possible for thread-state dicts to be involved in
181 reference cycles (otherwise the cyclic GC will refuse to consider
182 objects referenced from a reachable thread-state dict, even though
183 local_dealloc would clear them)
184 - the death of a thread-state dict must still imply destruction of the
185 corresponding local dicts in all thread-local objects.
186
187 Our implementation uses small "localdummy" objects in order to break
188 the reference chain. These trivial objects are hashable (using the
189 default scheme of identity hashing) and weakrefable.
190 Each thread-state holds a separate localdummy for each local object
191 (as a /strong reference/),
192 and each thread-local object holds a dict mapping /weak references/
193 of localdummies to local dicts.
194
195 Therefore:
196 - only the thread-state dict holds a strong reference to the dummies
197 - only the thread-local object holds a strong reference to the local dicts
198 - only outside objects (application- or library-level) hold strong
199 references to the thread-local objects
200 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
201 dummies attached to that thread are called, and destroy the corresponding
202 local dicts from thread-local objects
203 - as soon as a thread-local object is destroyed, its local dicts are
204 destroyed and its dummies are manually removed from all thread states
205 - the GC can do its work correctly when a thread-local object is dangling,
206 without any interference from the thread-state dicts
207
208 As an additional optimization, each localdummy holds a borrowed reference
209 to the corresponding localdict. This borrowed reference is only used
210 by the thread-local object which has created the localdummy, which should
211 guarantee that the localdict still exists when accessed.
212*/
213
214typedef struct {
215 PyObject_HEAD
216 PyObject *localdict; /* Borrowed reference! */
217 PyObject *weakreflist; /* List of weak references to self */
218} localdummyobject;
219
220static void
221localdummy_dealloc(localdummyobject *self)
222{
223 if (self->weakreflist != NULL)
224 PyObject_ClearWeakRefs((PyObject *) self);
225 Py_TYPE(self)->tp_free((PyObject*)self);
226}
227
228static PyTypeObject localdummytype = {
229 PyVarObject_HEAD_INIT(NULL, 0)
230 /* tp_name */ "_thread._localdummy",
231 /* tp_basicsize */ sizeof(localdummyobject),
232 /* tp_itemsize */ 0,
233 /* tp_dealloc */ (destructor)localdummy_dealloc,
234 /* tp_print */ 0,
235 /* tp_getattr */ 0,
236 /* tp_setattr */ 0,
237 /* tp_reserved */ 0,
238 /* tp_repr */ 0,
239 /* tp_as_number */ 0,
240 /* tp_as_sequence */ 0,
241 /* tp_as_mapping */ 0,
242 /* tp_hash */ 0,
243 /* tp_call */ 0,
244 /* tp_str */ 0,
245 /* tp_getattro */ 0,
246 /* tp_setattro */ 0,
247 /* tp_as_buffer */ 0,
248 /* tp_flags */ Py_TPFLAGS_DEFAULT,
249 /* tp_doc */ "Thread-local dummy",
250 /* tp_traverse */ 0,
251 /* tp_clear */ 0,
252 /* tp_richcompare */ 0,
253 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
254};
255
256
Jim Fultond15dc062004-07-14 19:11:50 +0000257typedef struct {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000258 PyObject_HEAD
259 PyObject *key;
260 PyObject *args;
261 PyObject *kw;
Antoine Pitrou87d52602010-08-09 22:41:38 +0000262 /* The current thread's local dict (necessary for tp_dictoffset) */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000263 PyObject *dict;
Antoine Pitrou87d52602010-08-09 22:41:38 +0000264 PyObject *weakreflist; /* List of weak references to self */
265 /* A {localdummy weakref -> localdict} dict */
266 PyObject *dummies;
267 /* The callback for weakrefs to localdummies */
268 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000269} localobject;
270
Antoine Pitrou87d52602010-08-09 22:41:38 +0000271/* Forward declaration */
272static PyObject *_ldict(localobject *self);
273static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
274
275/* Create and register the dummy for the current thread, as well as the
276 corresponding local dict */
277static int
278_local_create_dummy(localobject *self)
279{
280 PyObject *tdict, *ldict = NULL, *wr = NULL;
281 localdummyobject *dummy = NULL;
282 int r;
283
284 tdict = PyThreadState_GetDict();
285 if (tdict == NULL) {
286 PyErr_SetString(PyExc_SystemError,
287 "Couldn't get thread-state dictionary");
288 goto err;
289 }
290
291 ldict = PyDict_New();
292 if (ldict == NULL)
293 goto err;
294 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
295 if (dummy == NULL)
296 goto err;
297 dummy->localdict = ldict;
298 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
299 if (wr == NULL)
300 goto err;
301
302 /* As a side-effect, this will cache the weakref's hash before the
303 dummy gets deleted */
304 r = PyDict_SetItem(self->dummies, wr, ldict);
305 if (r < 0)
306 goto err;
307 Py_CLEAR(wr);
308 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
309 if (r < 0)
310 goto err;
311 Py_CLEAR(dummy);
312
313 Py_CLEAR(self->dict);
314 self->dict = ldict;
315 return 0;
316
317err:
318 Py_XDECREF(ldict);
319 Py_XDECREF(wr);
320 Py_XDECREF(dummy);
321 return -1;
322}
323
Jim Fultond15dc062004-07-14 19:11:50 +0000324static PyObject *
325local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
326{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000327 localobject *self;
Antoine Pitrou87d52602010-08-09 22:41:38 +0000328 PyObject *wr;
329 static PyMethodDef wr_callback_def = {
330 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
331 };
Jim Fultond15dc062004-07-14 19:11:50 +0000332
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000333 if (type->tp_init == PyBaseObject_Type.tp_init
334 && ((args && PyObject_IsTrue(args))
335 || (kw && PyObject_IsTrue(kw)))) {
336 PyErr_SetString(PyExc_TypeError,
337 "Initialization arguments are not supported");
338 return NULL;
339 }
Jim Fultond15dc062004-07-14 19:11:50 +0000340
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000341 self = (localobject *)type->tp_alloc(type, 0);
342 if (self == NULL)
343 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000344
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000345 Py_XINCREF(args);
346 self->args = args;
347 Py_XINCREF(kw);
348 self->kw = kw;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000349 self->key = PyUnicode_FromFormat("thread.local.%p", self);
350 if (self->key == NULL)
351 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000352
Antoine Pitrou87d52602010-08-09 22:41:38 +0000353 self->dummies = PyDict_New();
354 if (self->dummies == NULL)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000355 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000356
Antoine Pitrou87d52602010-08-09 22:41:38 +0000357 /* We use a weak reference to self in the callback closure
358 in order to avoid spurious reference cycles */
359 wr = PyWeakref_NewRef((PyObject *) self, NULL);
360 if (wr == NULL)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000361 goto err;
Antoine Pitrou87d52602010-08-09 22:41:38 +0000362 self->wr_callback = PyCFunction_New(&wr_callback_def, wr);
363 Py_DECREF(wr);
364 if (self->wr_callback == NULL)
365 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000366
Antoine Pitrou87d52602010-08-09 22:41:38 +0000367 if (_local_create_dummy(self) < 0)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000368 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000369
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000370 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000371
372 err:
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000373 Py_DECREF(self);
374 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000375}
376
377static int
378local_traverse(localobject *self, visitproc visit, void *arg)
379{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000380 Py_VISIT(self->args);
381 Py_VISIT(self->kw);
Antoine Pitrou87d52602010-08-09 22:41:38 +0000382 Py_VISIT(self->dummies);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000383 Py_VISIT(self->dict);
384 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000385}
386
387static int
388local_clear(localobject *self)
389{
Antoine Pitrou87d52602010-08-09 22:41:38 +0000390 PyThreadState *tstate;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000391 Py_CLEAR(self->args);
392 Py_CLEAR(self->kw);
Antoine Pitrou87d52602010-08-09 22:41:38 +0000393 Py_CLEAR(self->dummies);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000394 Py_CLEAR(self->dict);
Antoine Pitrou87d52602010-08-09 22:41:38 +0000395 Py_CLEAR(self->wr_callback);
396 /* Remove all strong references to dummies from the thread states */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000397 if (self->key
398 && (tstate = PyThreadState_Get())
399 && tstate->interp) {
400 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
401 tstate;
402 tstate = PyThreadState_Next(tstate))
403 if (tstate->dict &&
404 PyDict_GetItem(tstate->dict, self->key))
405 PyDict_DelItem(tstate->dict, self->key);
406 }
Antoine Pitrou87d52602010-08-09 22:41:38 +0000407 return 0;
408}
Jim Fultond15dc062004-07-14 19:11:50 +0000409
Antoine Pitrou87d52602010-08-09 22:41:38 +0000410static void
411local_dealloc(localobject *self)
412{
413 /* Weakrefs must be invalidated right now, otherwise they can be used
414 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
415 if (self->weakreflist != NULL)
416 PyObject_ClearWeakRefs((PyObject *) self);
417
418 PyObject_GC_UnTrack(self);
419
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000420 local_clear(self);
Antoine Pitrou87d52602010-08-09 22:41:38 +0000421 Py_XDECREF(self->key);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000422 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000423}
424
Antoine Pitrou87d52602010-08-09 22:41:38 +0000425/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000426static PyObject *
427_ldict(localobject *self)
428{
Antoine Pitrou87d52602010-08-09 22:41:38 +0000429 PyObject *tdict, *ldict, *dummy;
Jim Fultond15dc062004-07-14 19:11:50 +0000430
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000431 tdict = PyThreadState_GetDict();
432 if (tdict == NULL) {
433 PyErr_SetString(PyExc_SystemError,
434 "Couldn't get thread-state dictionary");
435 return NULL;
436 }
Jim Fultond15dc062004-07-14 19:11:50 +0000437
Antoine Pitrou87d52602010-08-09 22:41:38 +0000438 dummy = PyDict_GetItem(tdict, self->key);
439 if (dummy == NULL) {
440 if (_local_create_dummy(self) < 0)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000441 return NULL;
Antoine Pitrou87d52602010-08-09 22:41:38 +0000442 ldict = self->dict;
Jim Fultond15dc062004-07-14 19:11:50 +0000443
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000444 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
445 Py_TYPE(self)->tp_init((PyObject*)self,
446 self->args, self->kw) < 0) {
447 /* we need to get rid of ldict from thread so
448 we create a new one the next time we do an attr
449 acces */
450 PyDict_DelItem(tdict, self->key);
451 return NULL;
452 }
Antoine Pitrou87d52602010-08-09 22:41:38 +0000453 }
454 else {
455 assert(Py_TYPE(dummy) == &localdummytype);
456 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000457 }
Jim Fultond15dc062004-07-14 19:11:50 +0000458
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000459 /* The call to tp_init above may have caused another thread to run.
460 Install our ldict again. */
461 if (self->dict != ldict) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000462 Py_INCREF(ldict);
Antoine Pitrou87d52602010-08-09 22:41:38 +0000463 Py_CLEAR(self->dict);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000464 self->dict = ldict;
465 }
466
467 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000468}
469
Jim Fultond15dc062004-07-14 19:11:50 +0000470static int
471local_setattro(localobject *self, PyObject *name, PyObject *v)
472{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000473 PyObject *ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000474
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000475 ldict = _ldict(self);
476 if (ldict == NULL)
477 return -1;
478
479 return PyObject_GenericSetAttr((PyObject *)self, name, v);
Jim Fultond15dc062004-07-14 19:11:50 +0000480}
481
482static PyObject *
483local_getdict(localobject *self, void *closure)
484{
Antoine Pitrou87d52602010-08-09 22:41:38 +0000485 PyObject *ldict;
486 ldict = _ldict(self);
487 Py_XINCREF(ldict);
488 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000489}
490
491static PyGetSetDef local_getset[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000492 {"__dict__", (getter)local_getdict, (setter)NULL,
493 "Local-data dictionary", NULL},
494 {NULL} /* Sentinel */
Jim Fultond15dc062004-07-14 19:11:50 +0000495};
496
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000497static PyObject *local_getattro(localobject *, PyObject *);
498
Jim Fultond15dc062004-07-14 19:11:50 +0000499static PyTypeObject localtype = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000500 PyVarObject_HEAD_INIT(NULL, 0)
501 /* tp_name */ "_thread._local",
502 /* tp_basicsize */ sizeof(localobject),
503 /* tp_itemsize */ 0,
504 /* tp_dealloc */ (destructor)local_dealloc,
505 /* tp_print */ 0,
506 /* tp_getattr */ 0,
507 /* tp_setattr */ 0,
508 /* tp_reserved */ 0,
509 /* tp_repr */ 0,
510 /* tp_as_number */ 0,
511 /* tp_as_sequence */ 0,
512 /* tp_as_mapping */ 0,
513 /* tp_hash */ 0,
514 /* tp_call */ 0,
515 /* tp_str */ 0,
516 /* tp_getattro */ (getattrofunc)local_getattro,
517 /* tp_setattro */ (setattrofunc)local_setattro,
518 /* tp_as_buffer */ 0,
Antoine Pitrou87d52602010-08-09 22:41:38 +0000519 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
520 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000521 /* tp_doc */ "Thread-local data",
522 /* tp_traverse */ (traverseproc)local_traverse,
523 /* tp_clear */ (inquiry)local_clear,
524 /* tp_richcompare */ 0,
Antoine Pitrou87d52602010-08-09 22:41:38 +0000525 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000526 /* tp_iter */ 0,
527 /* tp_iternext */ 0,
528 /* tp_methods */ 0,
529 /* tp_members */ 0,
530 /* tp_getset */ local_getset,
531 /* tp_base */ 0,
532 /* tp_dict */ 0, /* internal use */
533 /* tp_descr_get */ 0,
534 /* tp_descr_set */ 0,
535 /* tp_dictoffset */ offsetof(localobject, dict),
536 /* tp_init */ 0,
537 /* tp_alloc */ 0,
538 /* tp_new */ local_new,
539 /* tp_free */ 0, /* Low-level free-mem routine */
540 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000541};
542
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000543static PyObject *
544local_getattro(localobject *self, PyObject *name)
545{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000546 PyObject *ldict, *value;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000547
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000548 ldict = _ldict(self);
549 if (ldict == NULL)
550 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000551
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000552 if (Py_TYPE(self) != &localtype)
553 /* use generic lookup for subtypes */
554 return PyObject_GenericGetAttr((PyObject *)self, name);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000555
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000556 /* Optimization: just look in dict ourselves */
557 value = PyDict_GetItem(ldict, name);
558 if (value == NULL)
559 /* Fall back on generic to get __class__ and __dict__ */
560 return PyObject_GenericGetAttr((PyObject *)self, name);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000561
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000562 Py_INCREF(value);
563 return value;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000564}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000565
Antoine Pitrou87d52602010-08-09 22:41:38 +0000566/* Called when a dummy is destroyed. */
567static PyObject *
568_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
569{
570 PyObject *obj;
571 localobject *self;
572 assert(PyWeakref_CheckRef(localweakref));
573 obj = PyWeakref_GET_OBJECT(localweakref);
574 if (obj == Py_None)
575 Py_RETURN_NONE;
576 Py_INCREF(obj);
577 assert(PyObject_TypeCheck(obj, &localtype));
578 /* If the thread-local object is still alive and not being cleared,
579 remove the corresponding local dict */
580 self = (localobject *) obj;
581 if (self->dummies != NULL) {
582 PyObject *ldict;
583 ldict = PyDict_GetItem(self->dummies, dummyweakref);
584 if (ldict != NULL) {
585 if (ldict == self->dict)
586 Py_CLEAR(self->dict);
587 PyDict_DelItem(self->dummies, dummyweakref);
588 }
589 if (PyErr_Occurred())
590 PyErr_WriteUnraisable(obj);
591 }
592 Py_DECREF(obj);
593 Py_RETURN_NONE;
594}
595
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000596/* Module functions */
597
Guido van Rossuma027efa1997-05-05 20:56:21 +0000598struct bootstate {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000599 PyInterpreterState *interp;
600 PyObject *func;
601 PyObject *args;
602 PyObject *keyw;
603 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000604};
605
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000606static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000607t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000608{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000609 struct bootstate *boot = (struct bootstate *) boot_raw;
610 PyThreadState *tstate;
611 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000612
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000613 tstate = boot->tstate;
614 tstate->thread_id = PyThread_get_thread_ident();
615 _PyThreadState_Init(tstate);
616 PyEval_AcquireThread(tstate);
617 res = PyEval_CallObjectWithKeywords(
618 boot->func, boot->args, boot->keyw);
619 if (res == NULL) {
620 if (PyErr_ExceptionMatches(PyExc_SystemExit))
621 PyErr_Clear();
622 else {
623 PyObject *file;
624 PySys_WriteStderr(
625 "Unhandled exception in thread started by ");
626 file = PySys_GetObject("stderr");
627 if (file != NULL && file != Py_None)
628 PyFile_WriteObject(boot->func, file, 0);
629 else
630 PyObject_Print(boot->func, stderr, 0);
631 PySys_WriteStderr("\n");
632 PyErr_PrintEx(0);
633 }
634 }
635 else
636 Py_DECREF(res);
637 Py_DECREF(boot->func);
638 Py_DECREF(boot->args);
639 Py_XDECREF(boot->keyw);
640 PyMem_DEL(boot_raw);
641 PyThreadState_Clear(tstate);
642 PyThreadState_DeleteCurrent();
643 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000644}
645
Barry Warsawd0c10421996-12-17 00:05:22 +0000646static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000647thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000648{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000649 PyObject *func, *args, *keyw = NULL;
650 struct bootstate *boot;
651 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000652
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000653 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
654 &func, &args, &keyw))
655 return NULL;
656 if (!PyCallable_Check(func)) {
657 PyErr_SetString(PyExc_TypeError,
658 "first arg must be callable");
659 return NULL;
660 }
661 if (!PyTuple_Check(args)) {
662 PyErr_SetString(PyExc_TypeError,
663 "2nd arg must be a tuple");
664 return NULL;
665 }
666 if (keyw != NULL && !PyDict_Check(keyw)) {
667 PyErr_SetString(PyExc_TypeError,
668 "optional 3rd arg must be a dictionary");
669 return NULL;
670 }
671 boot = PyMem_NEW(struct bootstate, 1);
672 if (boot == NULL)
673 return PyErr_NoMemory();
674 boot->interp = PyThreadState_GET()->interp;
675 boot->func = func;
676 boot->args = args;
677 boot->keyw = keyw;
678 boot->tstate = _PyThreadState_Prealloc(boot->interp);
679 if (boot->tstate == NULL) {
680 PyMem_DEL(boot);
681 return PyErr_NoMemory();
682 }
683 Py_INCREF(func);
684 Py_INCREF(args);
685 Py_XINCREF(keyw);
686 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
687 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
688 if (ident == -1) {
689 PyErr_SetString(ThreadError, "can't start new thread");
690 Py_DECREF(func);
691 Py_DECREF(args);
692 Py_XDECREF(keyw);
693 PyThreadState_Clear(boot->tstate);
694 PyMem_DEL(boot);
695 return NULL;
696 }
697 return PyLong_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000698}
699
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000700PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000701"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000702(start_new() is an obsolete synonym)\n\
703\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000704Start a new thread and return its identifier. The thread will call the\n\
705function with positional arguments from the tuple args and keyword arguments\n\
706taken from the optional dictionary kwargs. The thread exits when the\n\
707function returns; the return value is ignored. The thread will also exit\n\
708when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000709printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000710
Barry Warsawd0c10421996-12-17 00:05:22 +0000711static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000712thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000713{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000714 PyErr_SetNone(PyExc_SystemExit);
715 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000716}
717
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000718PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000719"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000720(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000721\n\
722This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000723thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000724
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000725static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000726thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000727{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000728 PyErr_SetInterrupt();
729 Py_INCREF(Py_None);
730 return Py_None;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000731}
732
733PyDoc_STRVAR(interrupt_doc,
734"interrupt_main()\n\
735\n\
736Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000737A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000738);
739
Guido van Rossumb6775db1994-08-01 11:34:53 +0000740#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000741static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000742thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000743{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000744 int sts;
745 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
746 return NULL;
747 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
748 for (;;) { } /* Should not be reached */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000749}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000750#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000751
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000752static lockobject *newlockobject(void);
753
Barry Warsawd0c10421996-12-17 00:05:22 +0000754static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000755thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000756{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000757 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000758}
759
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000760PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000761"allocate_lock() -> lock object\n\
762(allocate() is an obsolete synonym)\n\
763\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000764Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000765
Barry Warsawd0c10421996-12-17 00:05:22 +0000766static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000767thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000768{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000769 long ident;
770 ident = PyThread_get_thread_ident();
771 if (ident == -1) {
772 PyErr_SetString(ThreadError, "no current thread ident");
773 return NULL;
774 }
775 return PyLong_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000776}
777
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000778PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000779"get_ident() -> integer\n\
780\n\
781Return a non-zero integer that uniquely identifies the current thread\n\
782amongst other threads that exist simultaneously.\n\
783This may be used to identify per-thread resources.\n\
784Even though on some platforms threads identities may appear to be\n\
785allocated consecutive numbers starting at 1, this behavior should not\n\
786be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000787A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000788
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000789static PyObject *
790thread_stack_size(PyObject *self, PyObject *args)
791{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000792 size_t old_size;
793 Py_ssize_t new_size = 0;
794 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000795
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000796 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
797 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000798
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000799 if (new_size < 0) {
800 PyErr_SetString(PyExc_ValueError,
801 "size must be 0 or a positive value");
802 return NULL;
803 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000804
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000805 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000806
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000807 rc = PyThread_set_stacksize((size_t) new_size);
808 if (rc == -1) {
809 PyErr_Format(PyExc_ValueError,
810 "size not valid: %zd bytes",
811 new_size);
812 return NULL;
813 }
814 if (rc == -2) {
815 PyErr_SetString(ThreadError,
816 "setting stack size not supported");
817 return NULL;
818 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000819
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000820 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000821}
822
823PyDoc_STRVAR(stack_size_doc,
824"stack_size([size]) -> size\n\
825\n\
826Return the thread stack size used when creating new threads. The\n\
827optional size argument specifies the stack size (in bytes) to be used\n\
828for subsequently created threads, and must be 0 (use platform or\n\
829configured default) or a positive integer value of at least 32,768 (32k).\n\
830If changing the thread stack size is unsupported, a ThreadError\n\
831exception is raised. If the specified size is invalid, a ValueError\n\
832exception is raised, and the stack size is unmodified. 32k bytes\n\
833 currently the minimum supported stack size value to guarantee\n\
834sufficient stack space for the interpreter itself.\n\
835\n\
836Note that some platforms may have particular restrictions on values for\n\
837the stack size, such as requiring a minimum stack size larger than 32kB or\n\
838requiring allocation in multiples of the system memory page size\n\
839- platform documentation should be referred to for more information\n\
840(4kB pages are common; using multiples of 4096 for the stack size is\n\
841the suggested approach in the absence of more specific information).");
842
Barry Warsawd0c10421996-12-17 00:05:22 +0000843static PyMethodDef thread_methods[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000844 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
845 METH_VARARGS,
846 start_new_doc},
847 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
848 METH_VARARGS,
849 start_new_doc},
850 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
851 METH_NOARGS, allocate_doc},
852 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
853 METH_NOARGS, allocate_doc},
854 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
855 METH_NOARGS, exit_doc},
856 {"exit", (PyCFunction)thread_PyThread_exit_thread,
857 METH_NOARGS, exit_doc},
858 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
859 METH_NOARGS, interrupt_doc},
860 {"get_ident", (PyCFunction)thread_get_ident,
861 METH_NOARGS, get_ident_doc},
862 {"stack_size", (PyCFunction)thread_stack_size,
863 METH_VARARGS,
864 stack_size_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000865#ifndef NO_EXIT_PROG
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000866 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
867 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000868#endif
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000869 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000870};
871
872
873/* Initialization function */
874
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000875PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000876"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000877The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000878
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000879PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000880"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000881call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000882\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000883acquire() -- lock the lock, possibly blocking until it can be obtained\n\
884release() -- unlock of the lock\n\
885locked() -- test whether the lock is currently locked\n\
886\n\
887A lock is not owned by the thread that locked it; another thread may\n\
888unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000889will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000890
Martin v. Löwis1a214512008-06-11 05:26:20 +0000891static struct PyModuleDef threadmodule = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000892 PyModuleDef_HEAD_INIT,
893 "_thread",
894 thread_doc,
895 -1,
896 thread_methods,
897 NULL,
898 NULL,
899 NULL,
900 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000901};
902
903
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000904PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000905PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000906{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000907 PyObject *m, *d;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000908
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000909 /* Initialize types: */
Antoine Pitrou87d52602010-08-09 22:41:38 +0000910 if (PyType_Ready(&localdummytype) < 0)
911 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000912 if (PyType_Ready(&localtype) < 0)
913 return NULL;
914 if (PyType_Ready(&Locktype) < 0)
915 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000916
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000917 /* Create the module and add the functions */
918 m = PyModule_Create(&threadmodule);
919 if (m == NULL)
920 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000921
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000922 /* Add a symbolic constant */
923 d = PyModule_GetDict(m);
924 ThreadError = PyErr_NewException("_thread.error", NULL, NULL);
925 PyDict_SetItemString(d, "error", ThreadError);
926 Locktype.tp_doc = lock_doc;
927 Py_INCREF(&Locktype);
928 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Jim Fultond15dc062004-07-14 19:11:50 +0000929
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000930 Py_INCREF(&localtype);
931 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
932 return NULL;
933
934 /* Initialize the C thread library */
935 PyThread_init_thread();
936 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000937}