blob: 3d5e4ccb3248278a85bb70026df0513ac5a45fb2 [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 Rossum65d5b571998-12-21 19:32:43 +000052 PyThread_type_lock lock_lock;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000053} 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;
Guido van Rossum65d5b571998-12-21 19:32:43 +000064 self->lock_lock = PyThread_allocate_lock();
Guido van Rossum1984f1e1992-08-04 12:41:02 +000065 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 */
Guido van Rossum65d5b571998-12-21 19:32:43 +000078 PyThread_acquire_lock(self->lock_lock, 0);
79 PyThread_release_lock(self->lock_lock);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000080
Guido van Rossum65d5b571998-12-21 19:32:43 +000081 PyThread_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 Rossum65d5b571998-12-21 19:32:43 +000086lock_PyThread_acquire_lock(self, args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000087 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 Rossum65d5b571998-12-21 19:32:43 +0000100 i = PyThread_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\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000113(PyThread_acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000114\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 Rossum65d5b571998-12-21 19:32:43 +0000123lock_PyThread_release_lock(self, args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000124 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 */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000131 if (PyThread_acquire_lock(self->lock_lock, 0)) {
132 PyThread_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
Guido van Rossum65d5b571998-12-21 19:32:43 +0000137 PyThread_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\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000144(PyThread_release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000145\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
Guido van Rossum65d5b571998-12-21 19:32:43 +0000158 if (PyThread_acquire_lock(self->lock_lock, 0)) {
159 PyThread_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 Rossum65d5b571998-12-21 19:32:43 +0000172 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock, 0, acquire_doc},
173 {"acquire", (PyCFunction)lock_PyThread_acquire_lock, 0, acquire_doc},
174 {"release_lock", (PyCFunction)lock_PyThread_release_lock, 0, release_doc},
175 {"release", (PyCFunction)lock_PyThread_release_lock, 0, release_doc},
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000176 {"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 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000244}
245
Barry Warsawd0c10421996-12-17 00:05:22 +0000246static PyObject *
Guido van Rossum65d5b571998-12-21 19:32:43 +0000247thread_PyThread_start_new_thread(self, fargs)
Barry Warsawd0c10421996-12-17 00:05:22 +0000248 PyObject *self; /* Not used */
Guido van Rossuma027efa1997-05-05 20:56:21 +0000249 PyObject *fargs;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000250{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000251 PyObject *func, *args = NULL, *keyw = NULL;
252 struct bootstate *boot;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000253
Guido van Rossuma027efa1997-05-05 20:56:21 +0000254 if (!PyArg_ParseTuple(fargs, "OO|O", &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000255 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000256 if (!PyCallable_Check(func)) {
257 PyErr_SetString(PyExc_TypeError,
258 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000259 return NULL;
260 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000261 if (!PyTuple_Check(args)) {
262 PyErr_SetString(PyExc_TypeError,
263 "optional 2nd arg must be a tuple");
264 return NULL;
265 }
266 if (keyw != NULL && !PyDict_Check(keyw)) {
267 PyErr_SetString(PyExc_TypeError,
268 "optional 3rd arg must be a dictionary");
269 return NULL;
270 }
271 boot = PyMem_NEW(struct bootstate, 1);
272 if (boot == NULL)
273 return PyErr_NoMemory();
Guido van Rossumb02158e1997-08-02 03:13:11 +0000274 boot->interp = PyThreadState_Get()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000275 boot->func = func;
276 boot->args = args;
277 boot->keyw = keyw;
278 Py_INCREF(func);
279 Py_INCREF(args);
280 Py_XINCREF(keyw);
281 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000282 if (!PyThread_start_new_thread(t_bootstrap, (void*) boot)) {
Guido van Rossuma027efa1997-05-05 20:56:21 +0000283 PyErr_SetString(ThreadError, "can't start new thread\n");
284 Py_DECREF(func);
285 Py_DECREF(args);
286 Py_XDECREF(keyw);
287 PyMem_DEL(boot);
288 return NULL;
289 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000290 Py_INCREF(Py_None);
291 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000292}
293
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000294static char start_new_doc[] =
295"start_new_thread(functon, args[, kwargs])\n\
296(start_new() is an obsolete synonym)\n\
297\n\
298Start a new thread. The thread will call the function with positional\n\
299arguments from the tuple args and keyword arguments taken from the optional\n\
300dictionary kwargs. The thread exits when the function returns; the return\n\
301value is ignored. The thread will also exit when the function raises an\n\
302unhandled exception; a stack trace will be printed unless the exception is\n\
303SystemExit.";
304
Barry Warsawd0c10421996-12-17 00:05:22 +0000305static PyObject *
Guido van Rossum65d5b571998-12-21 19:32:43 +0000306thread_PyThread_exit_thread(self, args)
Barry Warsawd0c10421996-12-17 00:05:22 +0000307 PyObject *self; /* Not used */
308 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000309{
Barry Warsawd0c10421996-12-17 00:05:22 +0000310 if (!PyArg_NoArgs(args))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000311 return NULL;
Barry Warsawd0c10421996-12-17 00:05:22 +0000312 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000313 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000314}
315
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000316static char exit_doc[] =
317"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000318(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000319\n\
320This is synonymous to ``raise SystemExit''. It will cause the current\n\
321thread to exit silently unless the exception is caught.";
322
Guido van Rossumb6775db1994-08-01 11:34:53 +0000323#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000324static PyObject *
Guido van Rossum65d5b571998-12-21 19:32:43 +0000325thread_PyThread_exit_prog(self, args)
Barry Warsawd0c10421996-12-17 00:05:22 +0000326 PyObject *self; /* Not used */
327 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000328{
329 int sts;
Barry Warsawd0c10421996-12-17 00:05:22 +0000330 if (!PyArg_Parse(args, "i", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000331 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000332 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000333 for (;;) { } /* Should not be reached */
334}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000335#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000336
Barry Warsawd0c10421996-12-17 00:05:22 +0000337static PyObject *
Guido van Rossum65d5b571998-12-21 19:32:43 +0000338thread_PyThread_allocate_lock(self, args)
Barry Warsawd0c10421996-12-17 00:05:22 +0000339 PyObject *self; /* Not used */
340 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000341{
Barry Warsawd0c10421996-12-17 00:05:22 +0000342 if (!PyArg_NoArgs(args))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000343 return NULL;
Barry Warsawd0c10421996-12-17 00:05:22 +0000344 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000345}
346
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000347static char allocate_doc[] =
348"allocate_lock() -> lock object\n\
349(allocate() is an obsolete synonym)\n\
350\n\
351Create a new lock object. See LockType.__doc__ for information about locks.";
352
Barry Warsawd0c10421996-12-17 00:05:22 +0000353static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000354thread_get_ident(self, args)
Barry Warsawd0c10421996-12-17 00:05:22 +0000355 PyObject *self; /* Not used */
356 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000357{
358 long ident;
Barry Warsawd0c10421996-12-17 00:05:22 +0000359 if (!PyArg_NoArgs(args))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000360 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000361 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000362 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000363 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000364 return NULL;
365 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000366 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000367}
368
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000369static char get_ident_doc[] =
370"get_ident() -> integer\n\
371\n\
372Return a non-zero integer that uniquely identifies the current thread\n\
373amongst other threads that exist simultaneously.\n\
374This may be used to identify per-thread resources.\n\
375Even though on some platforms threads identities may appear to be\n\
376allocated consecutive numbers starting at 1, this behavior should not\n\
377be relied upon, and the number should be seen purely as a magic cookie.\n\
378A thread's identity may be reused for another thread after it exits.";
379
Barry Warsawd0c10421996-12-17 00:05:22 +0000380static PyMethodDef thread_methods[] = {
Guido van Rossum65d5b571998-12-21 19:32:43 +0000381 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread, 1,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000382 start_new_doc},
Guido van Rossum65d5b571998-12-21 19:32:43 +0000383 {"start_new", (PyCFunction)thread_PyThread_start_new_thread, 1,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000384 start_new_doc},
Guido van Rossum65d5b571998-12-21 19:32:43 +0000385 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock, 0,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000386 allocate_doc},
Guido van Rossum65d5b571998-12-21 19:32:43 +0000387 {"allocate", (PyCFunction)thread_PyThread_allocate_lock, 0,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000388 allocate_doc},
Guido van Rossum65d5b571998-12-21 19:32:43 +0000389 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread, 0,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000390 exit_doc},
Guido van Rossum65d5b571998-12-21 19:32:43 +0000391 {"exit", (PyCFunction)thread_PyThread_exit_thread, 0,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000392 exit_doc},
393 {"get_ident", (PyCFunction)thread_get_ident, 0,
394 get_ident_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000395#ifndef NO_EXIT_PROG
Guido van Rossum65d5b571998-12-21 19:32:43 +0000396 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000397#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000398 {NULL, NULL} /* sentinel */
399};
400
401
402/* Initialization function */
403
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000404static char thread_doc[] =
405"This module provides primitive operations to write multi-threaded programs.\n\
406The 'threading' module provides a more convenient interface.";
407
408static char lock_doc[] =
409"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000410call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000411\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000412acquire() -- lock the lock, possibly blocking until it can be obtained\n\
413release() -- unlock of the lock\n\
414locked() -- test whether the lock is currently locked\n\
415\n\
416A lock is not owned by the thread that locked it; another thread may\n\
417unlock it. A thread attempting to lock a lock that it has already locked\n\
418will block until another thread unlocks it. Deadlocks may ensue.";
419
Guido van Rossum3886bb61998-12-04 18:50:17 +0000420DL_EXPORT(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000421initthread()
422{
Barry Warsawd0c10421996-12-17 00:05:22 +0000423 PyObject *m, *d;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000424
425 /* Create the module and add the functions */
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000426 m = Py_InitModule3("thread", thread_methods, thread_doc);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000427
428 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000429 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000430 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000431 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000432 Locktype.tp_doc = lock_doc;
433 Py_INCREF(&Locktype);
434 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000435
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000436 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000437 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000438}