blob: a1ba362ae94553b792f9f7c071918e76ba09e6d0 [file] [log] [blame]
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum1984f1e1992-08-04 12:41:02 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum1984f1e1992-08-04 12:41:02 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum1984f1e1992-08-04 12:41:02 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum1984f1e1992-08-04 12:41:02 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum1984f1e1992-08-04 12:41:02 +000029
30******************************************************************/
31
32/* Thread module */
33/* Interface to Sjoerd's portable C thread library */
34
Barry Warsawd0c10421996-12-17 00:05:22 +000035#include "Python.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000036
Guido van Rossumb6775db1994-08-01 11:34:53 +000037#ifndef WITH_THREAD
Guido van Rossuma027efa1997-05-05 20:56:21 +000038#error "Error! The rest of Python is not compiled with thread support."
39#error "Rerun configure, adding a --with-thread option."
40#error "Then run `make clean' followed by `make'."
Guido van Rossumb6775db1994-08-01 11:34:53 +000041#endif
42
Guido van Rossum49b56061998-10-01 20:42:43 +000043#include "pythread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000044
Barry Warsawd0c10421996-12-17 00:05:22 +000045static PyObject *ThreadError;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000046
47
48/* Lock objects */
49
50typedef struct {
Barry Warsawd0c10421996-12-17 00:05:22 +000051 PyObject_HEAD
Guido van Rossum1984f1e1992-08-04 12:41:02 +000052 type_lock lock_lock;
53} lockobject;
54
Barry Warsawd0c10421996-12-17 00:05:22 +000055staticforward PyTypeObject Locktype;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000056
Guido van Rossum1984f1e1992-08-04 12:41:02 +000057static lockobject *
58newlockobject()
59{
60 lockobject *self;
Barry Warsawd0c10421996-12-17 00:05:22 +000061 self = PyObject_NEW(lockobject, &Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000062 if (self == NULL)
63 return NULL;
64 self->lock_lock = allocate_lock();
65 if (self->lock_lock == NULL) {
Barry Warsawd0c10421996-12-17 00:05:22 +000066 PyMem_DEL(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000067 self = NULL;
Barry Warsawd0c10421996-12-17 00:05:22 +000068 PyErr_SetString(ThreadError, "can't allocate lock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +000069 }
70 return self;
71}
72
73static void
74lock_dealloc(self)
75 lockobject *self;
76{
77 /* Unlock the lock so it's safe to free it */
78 acquire_lock(self->lock_lock, 0);
79 release_lock(self->lock_lock);
80
81 free_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000082 PyMem_DEL(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000083}
84
Barry Warsawd0c10421996-12-17 00:05:22 +000085static PyObject *
Guido van Rossum1984f1e1992-08-04 12:41:02 +000086lock_acquire_lock(self, args)
87 lockobject *self;
Barry Warsawd0c10421996-12-17 00:05:22 +000088 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000089{
Guido van Rossum1984f1e1992-08-04 12:41:02 +000090 int i;
91
92 if (args != NULL) {
Barry Warsawd0c10421996-12-17 00:05:22 +000093 if (!PyArg_Parse(args, "i", &i))
Guido van Rossum1984f1e1992-08-04 12:41:02 +000094 return NULL;
95 }
96 else
97 i = 1;
98
Barry Warsawd0c10421996-12-17 00:05:22 +000099 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000100 i = acquire_lock(self->lock_lock, i);
Barry Warsawd0c10421996-12-17 00:05:22 +0000101 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000102
103 if (args == NULL) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000104 Py_INCREF(Py_None);
105 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000106 }
107 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000108 return PyInt_FromLong((long)i);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000109}
110
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000111static char acquire_doc[] =
112"acquire([wait]) -> None or Boolean\n\
113(acquire_lock() is an obsolete synonym)\n\
114\n\
115Lock the lock. Without argument, this blocks if the lock is already\n\
116locked (even by the same thread), waiting for another thread to release\n\
117the lock, and return None when the lock is acquired.\n\
118With a Boolean argument, this will only block if the argument is true,\n\
119and the return value reflects whether the lock is acquired.\n\
120The blocking operation is not interruptible.";
121
Barry Warsawd0c10421996-12-17 00:05:22 +0000122static PyObject *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000123lock_release_lock(self, args)
124 lockobject *self;
Barry Warsawd0c10421996-12-17 00:05:22 +0000125 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000126{
Barry Warsawd0c10421996-12-17 00:05:22 +0000127 if (!PyArg_NoArgs(args))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000128 return NULL;
129
130 /* Sanity check: the lock must be locked */
131 if (acquire_lock(self->lock_lock, 0)) {
132 release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +0000133 PyErr_SetString(ThreadError, "release unlocked lock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000134 return NULL;
135 }
136
137 release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +0000138 Py_INCREF(Py_None);
139 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000140}
141
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000142static char release_doc[] =
143"release()\n\
144(release_lock() is an obsolete synonym)\n\
145\n\
146Release the lock, allowing another thread that is blocked waiting for\n\
147the lock to acquire the lock. The lock must be in the locked state,\n\
148but it needn't be locked by the same thread that unlocks it.";
149
Barry Warsawd0c10421996-12-17 00:05:22 +0000150static PyObject *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000151lock_locked_lock(self, args)
152 lockobject *self;
Barry Warsawd0c10421996-12-17 00:05:22 +0000153 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000154{
Barry Warsawd0c10421996-12-17 00:05:22 +0000155 if (!PyArg_NoArgs(args))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000156 return NULL;
157
158 if (acquire_lock(self->lock_lock, 0)) {
159 release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +0000160 return PyInt_FromLong(0L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000161 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000162 return PyInt_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000163}
164
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000165static char locked_doc[] =
166"locked() -> Boolean\n\
167(locked_lock() is an obsolete synonym)\n\
168\n\
169Return whether the lock is in the locked state.";
170
Barry Warsawd0c10421996-12-17 00:05:22 +0000171static PyMethodDef lock_methods[] = {
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000172 {"acquire_lock", (PyCFunction)lock_acquire_lock, 0, acquire_doc},
173 {"acquire", (PyCFunction)lock_acquire_lock, 0, acquire_doc},
174 {"release_lock", (PyCFunction)lock_release_lock, 0, release_doc},
175 {"release", (PyCFunction)lock_release_lock, 0, release_doc},
176 {"locked_lock", (PyCFunction)lock_locked_lock, 0, locked_doc},
177 {"locked", (PyCFunction)lock_locked_lock, 0, locked_doc},
178 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000179};
180
Barry Warsawd0c10421996-12-17 00:05:22 +0000181static PyObject *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000182lock_getattr(self, name)
183 lockobject *self;
184 char *name;
185{
Barry Warsawd0c10421996-12-17 00:05:22 +0000186 return Py_FindMethod(lock_methods, (PyObject *)self, name);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000187}
188
Barry Warsawd0c10421996-12-17 00:05:22 +0000189static PyTypeObject Locktype = {
190 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000191 0, /*ob_size*/
192 "lock", /*tp_name*/
193 sizeof(lockobject), /*tp_size*/
194 0, /*tp_itemsize*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000195 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196 (destructor)lock_dealloc, /*tp_dealloc*/
197 0, /*tp_print*/
198 (getattrfunc)lock_getattr, /*tp_getattr*/
199 0, /*tp_setattr*/
200 0, /*tp_compare*/
201 0, /*tp_repr*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000202};
203
204
205/* Module functions */
206
Guido van Rossuma027efa1997-05-05 20:56:21 +0000207struct bootstate {
208 PyInterpreterState *interp;
209 PyObject *func;
210 PyObject *args;
211 PyObject *keyw;
212};
213
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000214static void
Guido van Rossuma027efa1997-05-05 20:56:21 +0000215t_bootstrap(boot_raw)
216 void *boot_raw;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000217{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000218 struct bootstate *boot = (struct bootstate *) boot_raw;
Guido van Rossum75aa0d61997-07-18 23:57:50 +0000219 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000220 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000221
Guido van Rossuma027efa1997-05-05 20:56:21 +0000222 tstate = PyThreadState_New(boot->interp);
Guido van Rossum75aa0d61997-07-18 23:57:50 +0000223 PyEval_AcquireThread(tstate);
Guido van Rossuma027efa1997-05-05 20:56:21 +0000224 res = PyEval_CallObjectWithKeywords(
225 boot->func, boot->args, boot->keyw);
226 Py_DECREF(boot->func);
227 Py_DECREF(boot->args);
228 Py_XDECREF(boot->keyw);
229 PyMem_DEL(boot_raw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000230 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000231 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000232 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000233 else {
234 fprintf(stderr, "Unhandled exception in thread:\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000235 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000236 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000237 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000238 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000239 Py_DECREF(res);
Guido van Rossumb02158e1997-08-02 03:13:11 +0000240 PyThreadState_Clear(tstate);
Guido van Rossum75aa0d61997-07-18 23:57:50 +0000241 PyEval_ReleaseThread(tstate);
Guido van Rossuma027efa1997-05-05 20:56:21 +0000242 PyThreadState_Delete(tstate);
Guido van Rossumbcc20741998-08-04 22:53:56 +0000243#ifdef __BEOS__
244 /* Dunno if this will cause problems with other ports; the BeOS thread
245 * support features only 100% renamed functions. [cjh]
246 */
247 PyThread_exit_thread();
248#else
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000249 exit_thread();
Guido van Rossumbcc20741998-08-04 22:53:56 +0000250#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000251}
252
Barry Warsawd0c10421996-12-17 00:05:22 +0000253static PyObject *
Guido van Rossuma027efa1997-05-05 20:56:21 +0000254thread_start_new_thread(self, fargs)
Barry Warsawd0c10421996-12-17 00:05:22 +0000255 PyObject *self; /* Not used */
Guido van Rossuma027efa1997-05-05 20:56:21 +0000256 PyObject *fargs;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000257{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000258 PyObject *func, *args = NULL, *keyw = NULL;
259 struct bootstate *boot;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000260
Guido van Rossuma027efa1997-05-05 20:56:21 +0000261 if (!PyArg_ParseTuple(fargs, "OO|O", &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000262 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000263 if (!PyCallable_Check(func)) {
264 PyErr_SetString(PyExc_TypeError,
265 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000266 return NULL;
267 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000268 if (!PyTuple_Check(args)) {
269 PyErr_SetString(PyExc_TypeError,
270 "optional 2nd arg must be a tuple");
271 return NULL;
272 }
273 if (keyw != NULL && !PyDict_Check(keyw)) {
274 PyErr_SetString(PyExc_TypeError,
275 "optional 3rd arg must be a dictionary");
276 return NULL;
277 }
278 boot = PyMem_NEW(struct bootstate, 1);
279 if (boot == NULL)
280 return PyErr_NoMemory();
Guido van Rossumb02158e1997-08-02 03:13:11 +0000281 boot->interp = PyThreadState_Get()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000282 boot->func = func;
283 boot->args = args;
284 boot->keyw = keyw;
285 Py_INCREF(func);
286 Py_INCREF(args);
287 Py_XINCREF(keyw);
288 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
289 if (!start_new_thread(t_bootstrap, (void*) boot)) {
290 PyErr_SetString(ThreadError, "can't start new thread\n");
291 Py_DECREF(func);
292 Py_DECREF(args);
293 Py_XDECREF(keyw);
294 PyMem_DEL(boot);
295 return NULL;
296 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000297 Py_INCREF(Py_None);
298 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000299}
300
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000301static char start_new_doc[] =
302"start_new_thread(functon, args[, kwargs])\n\
303(start_new() is an obsolete synonym)\n\
304\n\
305Start a new thread. The thread will call the function with positional\n\
306arguments from the tuple args and keyword arguments taken from the optional\n\
307dictionary kwargs. The thread exits when the function returns; the return\n\
308value is ignored. The thread will also exit when the function raises an\n\
309unhandled exception; a stack trace will be printed unless the exception is\n\
310SystemExit.";
311
Barry Warsawd0c10421996-12-17 00:05:22 +0000312static PyObject *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000313thread_exit_thread(self, args)
Barry Warsawd0c10421996-12-17 00:05:22 +0000314 PyObject *self; /* Not used */
315 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000316{
Barry Warsawd0c10421996-12-17 00:05:22 +0000317 if (!PyArg_NoArgs(args))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000318 return NULL;
Barry Warsawd0c10421996-12-17 00:05:22 +0000319 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000320 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000321}
322
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000323static char exit_doc[] =
324"exit()\n\
325(exit_thread() is an obsolete synonym)\n\
326\n\
327This is synonymous to ``raise SystemExit''. It will cause the current\n\
328thread to exit silently unless the exception is caught.";
329
Guido van Rossumb6775db1994-08-01 11:34:53 +0000330#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000331static PyObject *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000332thread_exit_prog(self, args)
Barry Warsawd0c10421996-12-17 00:05:22 +0000333 PyObject *self; /* Not used */
334 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000335{
336 int sts;
Barry Warsawd0c10421996-12-17 00:05:22 +0000337 if (!PyArg_Parse(args, "i", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000338 return NULL;
Barry Warsawd0c10421996-12-17 00:05:22 +0000339 Py_Exit(sts); /* Calls exit_prog(sts) or _exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000340 for (;;) { } /* Should not be reached */
341}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000342#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000343
Barry Warsawd0c10421996-12-17 00:05:22 +0000344static PyObject *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000345thread_allocate_lock(self, args)
Barry Warsawd0c10421996-12-17 00:05:22 +0000346 PyObject *self; /* Not used */
347 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000348{
Barry Warsawd0c10421996-12-17 00:05:22 +0000349 if (!PyArg_NoArgs(args))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000350 return NULL;
Barry Warsawd0c10421996-12-17 00:05:22 +0000351 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000352}
353
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000354static char allocate_doc[] =
355"allocate_lock() -> lock object\n\
356(allocate() is an obsolete synonym)\n\
357\n\
358Create a new lock object. See LockType.__doc__ for information about locks.";
359
Barry Warsawd0c10421996-12-17 00:05:22 +0000360static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000361thread_get_ident(self, args)
Barry Warsawd0c10421996-12-17 00:05:22 +0000362 PyObject *self; /* Not used */
363 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000364{
365 long ident;
Barry Warsawd0c10421996-12-17 00:05:22 +0000366 if (!PyArg_NoArgs(args))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000367 return NULL;
368 ident = get_thread_ident();
369 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000370 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000371 return NULL;
372 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000373 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000374}
375
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000376static char get_ident_doc[] =
377"get_ident() -> integer\n\
378\n\
379Return a non-zero integer that uniquely identifies the current thread\n\
380amongst other threads that exist simultaneously.\n\
381This may be used to identify per-thread resources.\n\
382Even though on some platforms threads identities may appear to be\n\
383allocated consecutive numbers starting at 1, this behavior should not\n\
384be relied upon, and the number should be seen purely as a magic cookie.\n\
385A thread's identity may be reused for another thread after it exits.";
386
Barry Warsawd0c10421996-12-17 00:05:22 +0000387static PyMethodDef thread_methods[] = {
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000388 {"start_new_thread", (PyCFunction)thread_start_new_thread, 1,
389 start_new_doc},
390 {"start_new", (PyCFunction)thread_start_new_thread, 1,
391 start_new_doc},
392 {"allocate_lock", (PyCFunction)thread_allocate_lock, 0,
393 allocate_doc},
394 {"allocate", (PyCFunction)thread_allocate_lock, 0,
395 allocate_doc},
396 {"exit_thread", (PyCFunction)thread_exit_thread, 0,
397 exit_doc},
398 {"exit", (PyCFunction)thread_exit_thread, 0,
399 exit_doc},
400 {"get_ident", (PyCFunction)thread_get_ident, 0,
401 get_ident_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000402#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000403 {"exit_prog", (PyCFunction)thread_exit_prog},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000404#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000405 {NULL, NULL} /* sentinel */
406};
407
408
409/* Initialization function */
410
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000411static char thread_doc[] =
412"This module provides primitive operations to write multi-threaded programs.\n\
413The 'threading' module provides a more convenient interface.";
414
415static char lock_doc[] =
416"A lock object is a synchronization primitive. To create a lock,\n\
417call the allocate_lock() function. Methods are:\n\
418\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000419acquire() -- lock the lock, possibly blocking until it can be obtained\n\
420release() -- unlock of the lock\n\
421locked() -- test whether the lock is currently locked\n\
422\n\
423A lock is not owned by the thread that locked it; another thread may\n\
424unlock it. A thread attempting to lock a lock that it has already locked\n\
425will block until another thread unlocks it. Deadlocks may ensue.";
426
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000427void
428initthread()
429{
Barry Warsawd0c10421996-12-17 00:05:22 +0000430 PyObject *m, *d;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000431
432 /* Create the module and add the functions */
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000433 m = Py_InitModule3("thread", thread_methods, thread_doc);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000434
435 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000436 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000437 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000438 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000439 Locktype.tp_doc = lock_doc;
440 Py_INCREF(&Locktype);
441 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000442
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000443 /* Initialize the C thread library */
444 init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000445}