blob: c37dc20849b33df27d40a588d4f9c97889a5ebc0 [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;
Antoine Pitroufcd2a792010-08-28 18:27:09 +000016static PyObject *str_dict;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000017
18
19/* Lock objects */
20
21typedef struct {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000022 PyObject_HEAD
23 PyThread_type_lock lock_lock;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000024} lockobject;
25
Guido van Rossum1984f1e1992-08-04 12:41:02 +000026static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000027lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000028{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000029 if (self->lock_lock != NULL) {
30 /* Unlock the lock so it's safe to free it */
31 PyThread_acquire_lock(self->lock_lock, 0);
32 PyThread_release_lock(self->lock_lock);
33
34 PyThread_free_lock(self->lock_lock);
35 }
36 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000037}
38
Barry Warsawd0c10421996-12-17 00:05:22 +000039static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000040lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000041{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000042 int i = 1;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000043
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000044 if (!PyArg_ParseTuple(args, "|i:acquire", &i))
45 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000046
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000047 Py_BEGIN_ALLOW_THREADS
48 i = PyThread_acquire_lock(self->lock_lock, i);
49 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +000050
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000051 return PyBool_FromLong((long)i);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000052}
53
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000054PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000055"acquire([wait]) -> None or bool\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000056(acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000057\n\
58Lock the lock. Without argument, this blocks if the lock is already\n\
59locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000060the lock, and return None once the lock is acquired.\n\
61With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000062and the return value reflects whether the lock is acquired.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000063The blocking operation is not interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000064
Barry Warsawd0c10421996-12-17 00:05:22 +000065static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000066lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000067{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000068 /* Sanity check: the lock must be locked */
69 if (PyThread_acquire_lock(self->lock_lock, 0)) {
70 PyThread_release_lock(self->lock_lock);
71 PyErr_SetString(ThreadError, "release unlocked lock");
72 return NULL;
73 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +000074
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000075 PyThread_release_lock(self->lock_lock);
76 Py_INCREF(Py_None);
77 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000078}
79
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000080PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +000081"release()\n\
Guido van Rossumf6694362006-03-10 02:28:35 +000082(release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000083\n\
84Release the lock, allowing another thread that is blocked waiting for\n\
85the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000086but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000087
Barry Warsawd0c10421996-12-17 00:05:22 +000088static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000089lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000090{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000091 if (PyThread_acquire_lock(self->lock_lock, 0)) {
92 PyThread_release_lock(self->lock_lock);
93 return PyBool_FromLong(0L);
94 }
95 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000096}
97
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000098PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000099"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000100(locked_lock() is an obsolete synonym)\n\
101\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000102Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000103
Barry Warsawd0c10421996-12-17 00:05:22 +0000104static PyMethodDef lock_methods[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000105 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
106 METH_VARARGS, acquire_doc},
107 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
108 METH_VARARGS, acquire_doc},
109 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
110 METH_NOARGS, release_doc},
111 {"release", (PyCFunction)lock_PyThread_release_lock,
112 METH_NOARGS, release_doc},
113 {"locked_lock", (PyCFunction)lock_locked_lock,
114 METH_NOARGS, locked_doc},
115 {"locked", (PyCFunction)lock_locked_lock,
116 METH_NOARGS, locked_doc},
117 {"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
118 METH_VARARGS, acquire_doc},
119 {"__exit__", (PyCFunction)lock_PyThread_release_lock,
120 METH_VARARGS, release_doc},
121 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000122};
123
Barry Warsawd0c10421996-12-17 00:05:22 +0000124static PyTypeObject Locktype = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000125 PyVarObject_HEAD_INIT(&PyType_Type, 0)
126 "_thread.lock", /*tp_name*/
127 sizeof(lockobject), /*tp_size*/
128 0, /*tp_itemsize*/
129 /* methods */
130 (destructor)lock_dealloc, /*tp_dealloc*/
131 0, /*tp_print*/
132 0, /*tp_getattr*/
133 0, /*tp_setattr*/
134 0, /*tp_reserved*/
135 0, /*tp_repr*/
136 0, /*tp_as_number*/
137 0, /*tp_as_sequence*/
138 0, /*tp_as_mapping*/
139 0, /*tp_hash*/
140 0, /*tp_call*/
141 0, /*tp_str*/
142 0, /*tp_getattro*/
143 0, /*tp_setattro*/
144 0, /*tp_as_buffer*/
145 Py_TPFLAGS_DEFAULT, /*tp_flags*/
146 0, /*tp_doc*/
147 0, /*tp_traverse*/
148 0, /*tp_clear*/
149 0, /*tp_richcompare*/
150 0, /*tp_weaklistoffset*/
151 0, /*tp_iter*/
152 0, /*tp_iternext*/
153 lock_methods, /*tp_methods*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000154};
155
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000156static lockobject *
157newlockobject(void)
158{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000159 lockobject *self;
160 self = PyObject_New(lockobject, &Locktype);
161 if (self == NULL)
162 return NULL;
163 self->lock_lock = PyThread_allocate_lock();
164 if (self->lock_lock == NULL) {
165 Py_DECREF(self);
166 PyErr_SetString(ThreadError, "can't allocate lock");
167 return NULL;
168 }
169 return self;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000170}
171
Jim Fultond15dc062004-07-14 19:11:50 +0000172/* Thread-local objects */
173
174#include "structmember.h"
175
Antoine Pitrou87d52602010-08-09 22:41:38 +0000176/* Quick overview:
177
178 We need to be able to reclaim reference cycles as soon as possible
179 (both when a thread is being terminated, or a thread-local object
180 becomes unreachable from user data). Constraints:
181 - it must not be possible for thread-state dicts to be involved in
182 reference cycles (otherwise the cyclic GC will refuse to consider
183 objects referenced from a reachable thread-state dict, even though
184 local_dealloc would clear them)
185 - the death of a thread-state dict must still imply destruction of the
186 corresponding local dicts in all thread-local objects.
187
188 Our implementation uses small "localdummy" objects in order to break
189 the reference chain. These trivial objects are hashable (using the
190 default scheme of identity hashing) and weakrefable.
191 Each thread-state holds a separate localdummy for each local object
192 (as a /strong reference/),
193 and each thread-local object holds a dict mapping /weak references/
194 of localdummies to local dicts.
195
196 Therefore:
197 - only the thread-state dict holds a strong reference to the dummies
198 - only the thread-local object holds a strong reference to the local dicts
199 - only outside objects (application- or library-level) hold strong
200 references to the thread-local objects
201 - as soon as a thread-state dict is destroyed, the weakref callbacks of all
202 dummies attached to that thread are called, and destroy the corresponding
203 local dicts from thread-local objects
204 - as soon as a thread-local object is destroyed, its local dicts are
205 destroyed and its dummies are manually removed from all thread states
206 - the GC can do its work correctly when a thread-local object is dangling,
207 without any interference from the thread-state dicts
208
209 As an additional optimization, each localdummy holds a borrowed reference
210 to the corresponding localdict. This borrowed reference is only used
211 by the thread-local object which has created the localdummy, which should
212 guarantee that the localdict still exists when accessed.
213*/
214
215typedef struct {
216 PyObject_HEAD
217 PyObject *localdict; /* Borrowed reference! */
218 PyObject *weakreflist; /* List of weak references to self */
219} localdummyobject;
220
221static void
222localdummy_dealloc(localdummyobject *self)
223{
224 if (self->weakreflist != NULL)
225 PyObject_ClearWeakRefs((PyObject *) self);
226 Py_TYPE(self)->tp_free((PyObject*)self);
227}
228
229static PyTypeObject localdummytype = {
230 PyVarObject_HEAD_INIT(NULL, 0)
231 /* tp_name */ "_thread._localdummy",
232 /* tp_basicsize */ sizeof(localdummyobject),
233 /* tp_itemsize */ 0,
234 /* tp_dealloc */ (destructor)localdummy_dealloc,
235 /* tp_print */ 0,
236 /* tp_getattr */ 0,
237 /* tp_setattr */ 0,
238 /* tp_reserved */ 0,
239 /* tp_repr */ 0,
240 /* tp_as_number */ 0,
241 /* tp_as_sequence */ 0,
242 /* tp_as_mapping */ 0,
243 /* tp_hash */ 0,
244 /* tp_call */ 0,
245 /* tp_str */ 0,
246 /* tp_getattro */ 0,
247 /* tp_setattro */ 0,
248 /* tp_as_buffer */ 0,
249 /* tp_flags */ Py_TPFLAGS_DEFAULT,
250 /* tp_doc */ "Thread-local dummy",
251 /* tp_traverse */ 0,
252 /* tp_clear */ 0,
253 /* tp_richcompare */ 0,
254 /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
255};
256
257
Jim Fultond15dc062004-07-14 19:11:50 +0000258typedef struct {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000259 PyObject_HEAD
260 PyObject *key;
261 PyObject *args;
262 PyObject *kw;
Antoine Pitrou87d52602010-08-09 22:41:38 +0000263 PyObject *weakreflist; /* List of weak references to self */
264 /* A {localdummy weakref -> localdict} dict */
265 PyObject *dummies;
266 /* The callback for weakrefs to localdummies */
267 PyObject *wr_callback;
Jim Fultond15dc062004-07-14 19:11:50 +0000268} localobject;
269
Antoine Pitrou87d52602010-08-09 22:41:38 +0000270/* Forward declaration */
271static PyObject *_ldict(localobject *self);
272static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);
273
Antoine Pitroufcd2a792010-08-28 18:27:09 +0000274/* Create and register the dummy for the current thread.
275 Returns a borrowed reference of the corresponding local dict */
276static PyObject *
Antoine Pitrou87d52602010-08-09 22:41:38 +0000277_local_create_dummy(localobject *self)
278{
279 PyObject *tdict, *ldict = NULL, *wr = NULL;
280 localdummyobject *dummy = NULL;
281 int r;
282
283 tdict = PyThreadState_GetDict();
284 if (tdict == NULL) {
285 PyErr_SetString(PyExc_SystemError,
286 "Couldn't get thread-state dictionary");
287 goto err;
288 }
289
290 ldict = PyDict_New();
291 if (ldict == NULL)
292 goto err;
293 dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
294 if (dummy == NULL)
295 goto err;
296 dummy->localdict = ldict;
297 wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
298 if (wr == NULL)
299 goto err;
300
301 /* As a side-effect, this will cache the weakref's hash before the
302 dummy gets deleted */
303 r = PyDict_SetItem(self->dummies, wr, ldict);
304 if (r < 0)
305 goto err;
306 Py_CLEAR(wr);
307 r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
308 if (r < 0)
309 goto err;
310 Py_CLEAR(dummy);
311
Antoine Pitroufcd2a792010-08-28 18:27:09 +0000312 Py_DECREF(ldict);
313 return ldict;
Antoine Pitrou87d52602010-08-09 22:41:38 +0000314
315err:
316 Py_XDECREF(ldict);
317 Py_XDECREF(wr);
318 Py_XDECREF(dummy);
Antoine Pitroufcd2a792010-08-28 18:27:09 +0000319 return NULL;
Antoine Pitrou87d52602010-08-09 22:41:38 +0000320}
321
Jim Fultond15dc062004-07-14 19:11:50 +0000322static PyObject *
323local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
324{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000325 localobject *self;
Antoine Pitrou87d52602010-08-09 22:41:38 +0000326 PyObject *wr;
327 static PyMethodDef wr_callback_def = {
328 "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
329 };
Jim Fultond15dc062004-07-14 19:11:50 +0000330
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000331 if (type->tp_init == PyBaseObject_Type.tp_init
332 && ((args && PyObject_IsTrue(args))
333 || (kw && PyObject_IsTrue(kw)))) {
334 PyErr_SetString(PyExc_TypeError,
335 "Initialization arguments are not supported");
336 return NULL;
337 }
Jim Fultond15dc062004-07-14 19:11:50 +0000338
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000339 self = (localobject *)type->tp_alloc(type, 0);
340 if (self == NULL)
341 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000342
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000343 Py_XINCREF(args);
344 self->args = args;
345 Py_XINCREF(kw);
346 self->kw = kw;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000347 self->key = PyUnicode_FromFormat("thread.local.%p", self);
348 if (self->key == NULL)
349 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000350
Antoine Pitrou87d52602010-08-09 22:41:38 +0000351 self->dummies = PyDict_New();
352 if (self->dummies == NULL)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000353 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000354
Antoine Pitrou87d52602010-08-09 22:41:38 +0000355 /* We use a weak reference to self in the callback closure
356 in order to avoid spurious reference cycles */
357 wr = PyWeakref_NewRef((PyObject *) self, NULL);
358 if (wr == NULL)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000359 goto err;
Antoine Pitrou87d52602010-08-09 22:41:38 +0000360 self->wr_callback = PyCFunction_New(&wr_callback_def, wr);
361 Py_DECREF(wr);
362 if (self->wr_callback == NULL)
363 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000364
Antoine Pitroufcd2a792010-08-28 18:27:09 +0000365 if (_local_create_dummy(self) == NULL)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000366 goto err;
Jim Fultond15dc062004-07-14 19:11:50 +0000367
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000368 return (PyObject *)self;
Michael W. Hudson2368b3c2005-06-15 12:48:40 +0000369
370 err:
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000371 Py_DECREF(self);
372 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000373}
374
375static int
376local_traverse(localobject *self, visitproc visit, void *arg)
377{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000378 Py_VISIT(self->args);
379 Py_VISIT(self->kw);
Antoine Pitrou87d52602010-08-09 22:41:38 +0000380 Py_VISIT(self->dummies);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000381 return 0;
Jim Fultond15dc062004-07-14 19:11:50 +0000382}
383
384static int
385local_clear(localobject *self)
386{
Antoine Pitrou87d52602010-08-09 22:41:38 +0000387 PyThreadState *tstate;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000388 Py_CLEAR(self->args);
389 Py_CLEAR(self->kw);
Antoine Pitrou87d52602010-08-09 22:41:38 +0000390 Py_CLEAR(self->dummies);
Antoine Pitrou87d52602010-08-09 22:41:38 +0000391 Py_CLEAR(self->wr_callback);
392 /* Remove all strong references to dummies from the thread states */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000393 if (self->key
394 && (tstate = PyThreadState_Get())
395 && tstate->interp) {
396 for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
397 tstate;
398 tstate = PyThreadState_Next(tstate))
399 if (tstate->dict &&
400 PyDict_GetItem(tstate->dict, self->key))
401 PyDict_DelItem(tstate->dict, self->key);
402 }
Antoine Pitrou87d52602010-08-09 22:41:38 +0000403 return 0;
404}
Jim Fultond15dc062004-07-14 19:11:50 +0000405
Antoine Pitrou87d52602010-08-09 22:41:38 +0000406static void
407local_dealloc(localobject *self)
408{
409 /* Weakrefs must be invalidated right now, otherwise they can be used
410 from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
411 if (self->weakreflist != NULL)
412 PyObject_ClearWeakRefs((PyObject *) self);
413
414 PyObject_GC_UnTrack(self);
415
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000416 local_clear(self);
Antoine Pitrou87d52602010-08-09 22:41:38 +0000417 Py_XDECREF(self->key);
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000418 Py_TYPE(self)->tp_free((PyObject*)self);
Jim Fultond15dc062004-07-14 19:11:50 +0000419}
420
Antoine Pitrou87d52602010-08-09 22:41:38 +0000421/* Returns a borrowed reference to the local dict, creating it if necessary */
Jim Fultond15dc062004-07-14 19:11:50 +0000422static PyObject *
423_ldict(localobject *self)
424{
Antoine Pitrou87d52602010-08-09 22:41:38 +0000425 PyObject *tdict, *ldict, *dummy;
Jim Fultond15dc062004-07-14 19:11:50 +0000426
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000427 tdict = PyThreadState_GetDict();
428 if (tdict == NULL) {
429 PyErr_SetString(PyExc_SystemError,
430 "Couldn't get thread-state dictionary");
431 return NULL;
432 }
Jim Fultond15dc062004-07-14 19:11:50 +0000433
Antoine Pitrou87d52602010-08-09 22:41:38 +0000434 dummy = PyDict_GetItem(tdict, self->key);
435 if (dummy == NULL) {
Antoine Pitroufcd2a792010-08-28 18:27:09 +0000436 ldict = _local_create_dummy(self);
437 if (ldict == NULL)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000438 return NULL;
Jim Fultond15dc062004-07-14 19:11:50 +0000439
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000440 if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
441 Py_TYPE(self)->tp_init((PyObject*)self,
442 self->args, self->kw) < 0) {
443 /* we need to get rid of ldict from thread so
444 we create a new one the next time we do an attr
445 acces */
446 PyDict_DelItem(tdict, self->key);
447 return NULL;
448 }
Antoine Pitrou87d52602010-08-09 22:41:38 +0000449 }
450 else {
451 assert(Py_TYPE(dummy) == &localdummytype);
452 ldict = ((localdummyobject *) dummy)->localdict;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000453 }
Jim Fultond15dc062004-07-14 19:11:50 +0000454
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000455 return ldict;
Jim Fultond15dc062004-07-14 19:11:50 +0000456}
457
Jim Fultond15dc062004-07-14 19:11:50 +0000458static int
459local_setattro(localobject *self, PyObject *name, PyObject *v)
460{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000461 PyObject *ldict;
Antoine Pitroufcd2a792010-08-28 18:27:09 +0000462 int r;
Jim Fultond15dc062004-07-14 19:11:50 +0000463
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000464 ldict = _ldict(self);
465 if (ldict == NULL)
466 return -1;
467
Antoine Pitroufcd2a792010-08-28 18:27:09 +0000468 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
469 if (r == 1) {
470 PyErr_Format(PyExc_AttributeError,
471 "'%.50s' object attribute '%U' is read-only",
472 Py_TYPE(self)->tp_name, name);
473 return -1;
474 }
475 if (r == -1)
476 return -1;
Jim Fultond15dc062004-07-14 19:11:50 +0000477
Antoine Pitroufcd2a792010-08-28 18:27:09 +0000478 return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
Jim Fultond15dc062004-07-14 19:11:50 +0000479}
480
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000481static PyObject *local_getattro(localobject *, PyObject *);
482
Jim Fultond15dc062004-07-14 19:11:50 +0000483static PyTypeObject localtype = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000484 PyVarObject_HEAD_INIT(NULL, 0)
485 /* tp_name */ "_thread._local",
486 /* tp_basicsize */ sizeof(localobject),
487 /* tp_itemsize */ 0,
488 /* tp_dealloc */ (destructor)local_dealloc,
489 /* tp_print */ 0,
490 /* tp_getattr */ 0,
491 /* tp_setattr */ 0,
492 /* tp_reserved */ 0,
493 /* tp_repr */ 0,
494 /* tp_as_number */ 0,
495 /* tp_as_sequence */ 0,
496 /* tp_as_mapping */ 0,
497 /* tp_hash */ 0,
498 /* tp_call */ 0,
499 /* tp_str */ 0,
500 /* tp_getattro */ (getattrofunc)local_getattro,
501 /* tp_setattro */ (setattrofunc)local_setattro,
502 /* tp_as_buffer */ 0,
Antoine Pitrou87d52602010-08-09 22:41:38 +0000503 /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
504 | Py_TPFLAGS_HAVE_GC,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000505 /* tp_doc */ "Thread-local data",
506 /* tp_traverse */ (traverseproc)local_traverse,
507 /* tp_clear */ (inquiry)local_clear,
508 /* tp_richcompare */ 0,
Antoine Pitrou87d52602010-08-09 22:41:38 +0000509 /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000510 /* tp_iter */ 0,
511 /* tp_iternext */ 0,
512 /* tp_methods */ 0,
513 /* tp_members */ 0,
Antoine Pitroufcd2a792010-08-28 18:27:09 +0000514 /* tp_getset */ 0,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000515 /* tp_base */ 0,
516 /* tp_dict */ 0, /* internal use */
517 /* tp_descr_get */ 0,
518 /* tp_descr_set */ 0,
Antoine Pitroufcd2a792010-08-28 18:27:09 +0000519 /* tp_dictoffset */ 0,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000520 /* tp_init */ 0,
521 /* tp_alloc */ 0,
522 /* tp_new */ local_new,
523 /* tp_free */ 0, /* Low-level free-mem routine */
524 /* tp_is_gc */ 0, /* For PyObject_IS_GC */
Jim Fultond15dc062004-07-14 19:11:50 +0000525};
526
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000527static PyObject *
528local_getattro(localobject *self, PyObject *name)
529{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000530 PyObject *ldict, *value;
Antoine Pitroufcd2a792010-08-28 18:27:09 +0000531 int r;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000532
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000533 ldict = _ldict(self);
534 if (ldict == NULL)
535 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000536
Antoine Pitroufcd2a792010-08-28 18:27:09 +0000537 r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
538 if (r == 1) {
539 Py_INCREF(ldict);
540 return ldict;
541 }
542 if (r == -1)
543 return NULL;
544
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000545 if (Py_TYPE(self) != &localtype)
546 /* use generic lookup for subtypes */
Antoine Pitroufcd2a792010-08-28 18:27:09 +0000547 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000548
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000549 /* Optimization: just look in dict ourselves */
550 value = PyDict_GetItem(ldict, name);
551 if (value == NULL)
552 /* Fall back on generic to get __class__ and __dict__ */
Antoine Pitroufcd2a792010-08-28 18:27:09 +0000553 return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000554
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000555 Py_INCREF(value);
556 return value;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000557}
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000558
Antoine Pitrou87d52602010-08-09 22:41:38 +0000559/* Called when a dummy is destroyed. */
560static PyObject *
561_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
562{
563 PyObject *obj;
564 localobject *self;
565 assert(PyWeakref_CheckRef(localweakref));
566 obj = PyWeakref_GET_OBJECT(localweakref);
567 if (obj == Py_None)
568 Py_RETURN_NONE;
569 Py_INCREF(obj);
570 assert(PyObject_TypeCheck(obj, &localtype));
571 /* If the thread-local object is still alive and not being cleared,
572 remove the corresponding local dict */
573 self = (localobject *) obj;
574 if (self->dummies != NULL) {
575 PyObject *ldict;
576 ldict = PyDict_GetItem(self->dummies, dummyweakref);
577 if (ldict != NULL) {
Antoine Pitrou87d52602010-08-09 22:41:38 +0000578 PyDict_DelItem(self->dummies, dummyweakref);
579 }
580 if (PyErr_Occurred())
581 PyErr_WriteUnraisable(obj);
582 }
583 Py_DECREF(obj);
584 Py_RETURN_NONE;
585}
586
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000587/* Module functions */
588
Guido van Rossuma027efa1997-05-05 20:56:21 +0000589struct bootstate {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000590 PyInterpreterState *interp;
591 PyObject *func;
592 PyObject *args;
593 PyObject *keyw;
594 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000595};
596
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000597static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000598t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000599{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000600 struct bootstate *boot = (struct bootstate *) boot_raw;
601 PyThreadState *tstate;
602 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000603
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000604 tstate = boot->tstate;
605 tstate->thread_id = PyThread_get_thread_ident();
606 _PyThreadState_Init(tstate);
607 PyEval_AcquireThread(tstate);
608 res = PyEval_CallObjectWithKeywords(
609 boot->func, boot->args, boot->keyw);
610 if (res == NULL) {
611 if (PyErr_ExceptionMatches(PyExc_SystemExit))
612 PyErr_Clear();
613 else {
614 PyObject *file;
615 PySys_WriteStderr(
616 "Unhandled exception in thread started by ");
617 file = PySys_GetObject("stderr");
618 if (file != NULL && file != Py_None)
619 PyFile_WriteObject(boot->func, file, 0);
620 else
621 PyObject_Print(boot->func, stderr, 0);
622 PySys_WriteStderr("\n");
623 PyErr_PrintEx(0);
624 }
625 }
626 else
627 Py_DECREF(res);
628 Py_DECREF(boot->func);
629 Py_DECREF(boot->args);
630 Py_XDECREF(boot->keyw);
631 PyMem_DEL(boot_raw);
632 PyThreadState_Clear(tstate);
633 PyThreadState_DeleteCurrent();
634 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000635}
636
Barry Warsawd0c10421996-12-17 00:05:22 +0000637static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000638thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000639{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000640 PyObject *func, *args, *keyw = NULL;
641 struct bootstate *boot;
642 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000643
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000644 if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
645 &func, &args, &keyw))
646 return NULL;
647 if (!PyCallable_Check(func)) {
648 PyErr_SetString(PyExc_TypeError,
649 "first arg must be callable");
650 return NULL;
651 }
652 if (!PyTuple_Check(args)) {
653 PyErr_SetString(PyExc_TypeError,
654 "2nd arg must be a tuple");
655 return NULL;
656 }
657 if (keyw != NULL && !PyDict_Check(keyw)) {
658 PyErr_SetString(PyExc_TypeError,
659 "optional 3rd arg must be a dictionary");
660 return NULL;
661 }
662 boot = PyMem_NEW(struct bootstate, 1);
663 if (boot == NULL)
664 return PyErr_NoMemory();
665 boot->interp = PyThreadState_GET()->interp;
666 boot->func = func;
667 boot->args = args;
668 boot->keyw = keyw;
669 boot->tstate = _PyThreadState_Prealloc(boot->interp);
670 if (boot->tstate == NULL) {
671 PyMem_DEL(boot);
672 return PyErr_NoMemory();
673 }
674 Py_INCREF(func);
675 Py_INCREF(args);
676 Py_XINCREF(keyw);
677 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
678 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
679 if (ident == -1) {
680 PyErr_SetString(ThreadError, "can't start new thread");
681 Py_DECREF(func);
682 Py_DECREF(args);
683 Py_XDECREF(keyw);
684 PyThreadState_Clear(boot->tstate);
685 PyMem_DEL(boot);
686 return NULL;
687 }
688 return PyLong_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000689}
690
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000691PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000692"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000693(start_new() is an obsolete synonym)\n\
694\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000695Start a new thread and return its identifier. The thread will call the\n\
696function with positional arguments from the tuple args and keyword arguments\n\
697taken from the optional dictionary kwargs. The thread exits when the\n\
698function returns; the return value is ignored. The thread will also exit\n\
699when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000700printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000701
Barry Warsawd0c10421996-12-17 00:05:22 +0000702static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000703thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000704{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000705 PyErr_SetNone(PyExc_SystemExit);
706 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000707}
708
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000709PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000710"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000711(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000712\n\
713This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000714thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000715
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000716static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000717thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000718{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000719 PyErr_SetInterrupt();
720 Py_INCREF(Py_None);
721 return Py_None;
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000722}
723
724PyDoc_STRVAR(interrupt_doc,
725"interrupt_main()\n\
726\n\
727Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000728A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000729);
730
Guido van Rossumb6775db1994-08-01 11:34:53 +0000731#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000732static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000733thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000734{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000735 int sts;
736 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
737 return NULL;
738 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
739 for (;;) { } /* Should not be reached */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000740}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000741#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000742
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000743static lockobject *newlockobject(void);
744
Barry Warsawd0c10421996-12-17 00:05:22 +0000745static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000746thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000747{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000748 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000749}
750
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000751PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000752"allocate_lock() -> lock object\n\
753(allocate() is an obsolete synonym)\n\
754\n\
Alexander Belopolsky102594f2010-08-16 20:26:04 +0000755Create a new lock object. See help(LockType) for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000756
Barry Warsawd0c10421996-12-17 00:05:22 +0000757static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000758thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000759{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000760 long ident;
761 ident = PyThread_get_thread_ident();
762 if (ident == -1) {
763 PyErr_SetString(ThreadError, "no current thread ident");
764 return NULL;
765 }
766 return PyLong_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000767}
768
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000769PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000770"get_ident() -> integer\n\
771\n\
772Return a non-zero integer that uniquely identifies the current thread\n\
773amongst other threads that exist simultaneously.\n\
774This may be used to identify per-thread resources.\n\
775Even though on some platforms threads identities may appear to be\n\
776allocated consecutive numbers starting at 1, this behavior should not\n\
777be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000778A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000779
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000780static PyObject *
781thread_stack_size(PyObject *self, PyObject *args)
782{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000783 size_t old_size;
784 Py_ssize_t new_size = 0;
785 int rc;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000786
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000787 if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
788 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000789
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000790 if (new_size < 0) {
791 PyErr_SetString(PyExc_ValueError,
792 "size must be 0 or a positive value");
793 return NULL;
794 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000795
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000796 old_size = PyThread_get_stacksize();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000797
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000798 rc = PyThread_set_stacksize((size_t) new_size);
799 if (rc == -1) {
800 PyErr_Format(PyExc_ValueError,
801 "size not valid: %zd bytes",
802 new_size);
803 return NULL;
804 }
805 if (rc == -2) {
806 PyErr_SetString(ThreadError,
807 "setting stack size not supported");
808 return NULL;
809 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000810
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000811 return PyLong_FromSsize_t((Py_ssize_t) old_size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000812}
813
814PyDoc_STRVAR(stack_size_doc,
815"stack_size([size]) -> size\n\
816\n\
817Return the thread stack size used when creating new threads. The\n\
818optional size argument specifies the stack size (in bytes) to be used\n\
819for subsequently created threads, and must be 0 (use platform or\n\
820configured default) or a positive integer value of at least 32,768 (32k).\n\
821If changing the thread stack size is unsupported, a ThreadError\n\
822exception is raised. If the specified size is invalid, a ValueError\n\
823exception is raised, and the stack size is unmodified. 32k bytes\n\
824 currently the minimum supported stack size value to guarantee\n\
825sufficient stack space for the interpreter itself.\n\
826\n\
827Note that some platforms may have particular restrictions on values for\n\
828the stack size, such as requiring a minimum stack size larger than 32kB or\n\
829requiring allocation in multiples of the system memory page size\n\
830- platform documentation should be referred to for more information\n\
831(4kB pages are common; using multiples of 4096 for the stack size is\n\
832the suggested approach in the absence of more specific information).");
833
Barry Warsawd0c10421996-12-17 00:05:22 +0000834static PyMethodDef thread_methods[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000835 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
836 METH_VARARGS,
837 start_new_doc},
838 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
839 METH_VARARGS,
840 start_new_doc},
841 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
842 METH_NOARGS, allocate_doc},
843 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
844 METH_NOARGS, allocate_doc},
845 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
846 METH_NOARGS, exit_doc},
847 {"exit", (PyCFunction)thread_PyThread_exit_thread,
848 METH_NOARGS, exit_doc},
849 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
850 METH_NOARGS, interrupt_doc},
851 {"get_ident", (PyCFunction)thread_get_ident,
852 METH_NOARGS, get_ident_doc},
853 {"stack_size", (PyCFunction)thread_stack_size,
854 METH_VARARGS,
855 stack_size_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000856#ifndef NO_EXIT_PROG
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000857 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
858 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000859#endif
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000860 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000861};
862
863
864/* Initialization function */
865
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000866PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000867"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000868The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000869
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000870PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000871"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000872call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000873\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000874acquire() -- lock the lock, possibly blocking until it can be obtained\n\
875release() -- unlock of the lock\n\
876locked() -- test whether the lock is currently locked\n\
877\n\
878A lock is not owned by the thread that locked it; another thread may\n\
879unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000880will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000881
Martin v. Löwis1a214512008-06-11 05:26:20 +0000882static struct PyModuleDef threadmodule = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000883 PyModuleDef_HEAD_INIT,
884 "_thread",
885 thread_doc,
886 -1,
887 thread_methods,
888 NULL,
889 NULL,
890 NULL,
891 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000892};
893
894
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000895PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000896PyInit__thread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000897{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000898 PyObject *m, *d;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000899
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000900 /* Initialize types: */
Antoine Pitrou87d52602010-08-09 22:41:38 +0000901 if (PyType_Ready(&localdummytype) < 0)
902 return NULL;
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000903 if (PyType_Ready(&localtype) < 0)
904 return NULL;
905 if (PyType_Ready(&Locktype) < 0)
906 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000907
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000908 /* Create the module and add the functions */
909 m = PyModule_Create(&threadmodule);
910 if (m == NULL)
911 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000912
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000913 /* Add a symbolic constant */
914 d = PyModule_GetDict(m);
915 ThreadError = PyErr_NewException("_thread.error", NULL, NULL);
916 PyDict_SetItemString(d, "error", ThreadError);
917 Locktype.tp_doc = lock_doc;
918 Py_INCREF(&Locktype);
919 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Jim Fultond15dc062004-07-14 19:11:50 +0000920
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000921 Py_INCREF(&localtype);
922 if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
923 return NULL;
924
Antoine Pitroufcd2a792010-08-28 18:27:09 +0000925 str_dict = PyUnicode_InternFromString("__dict__");
926 if (str_dict == NULL)
927 return NULL;
928
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000929 /* Initialize the C thread library */
930 PyThread_init_thread();
931 return m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000932}