blob: 461953ea2acf7a6b19821244e8a5b7dda7f61575 [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
38Error! The rest of Python is not compiled with thread support.
39Rerun configure, adding a --with-thread option.
40#endif
41
Guido van Rossum1984f1e1992-08-04 12:41:02 +000042#include "thread.h"
43
Barry Warsawd0c10421996-12-17 00:05:22 +000044extern int _PyThread_Started;
Guido van Rossumf9f2e821992-08-17 08:59:08 +000045
Barry Warsawd0c10421996-12-17 00:05:22 +000046static PyObject *ThreadError;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000047
48
49/* Lock objects */
50
51typedef struct {
Barry Warsawd0c10421996-12-17 00:05:22 +000052 PyObject_HEAD
Guido van Rossum1984f1e1992-08-04 12:41:02 +000053 type_lock lock_lock;
54} lockobject;
55
Barry Warsawd0c10421996-12-17 00:05:22 +000056staticforward PyTypeObject Locktype;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000057
58#define is_lockobject(v) ((v)->ob_type == &Locktype)
59
Sjoerd Mullendered59d201993-01-06 13:36:38 +000060type_lock
61getlocklock(lock)
Barry Warsawd0c10421996-12-17 00:05:22 +000062 PyObject *lock;
Sjoerd Mullendered59d201993-01-06 13:36:38 +000063{
64 if (lock == NULL || !is_lockobject(lock))
65 return NULL;
66 else
67 return ((lockobject *) lock)->lock_lock;
68}
69
Guido van Rossum1984f1e1992-08-04 12:41:02 +000070static lockobject *
71newlockobject()
72{
73 lockobject *self;
Barry Warsawd0c10421996-12-17 00:05:22 +000074 self = PyObject_NEW(lockobject, &Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000075 if (self == NULL)
76 return NULL;
77 self->lock_lock = allocate_lock();
78 if (self->lock_lock == NULL) {
Barry Warsawd0c10421996-12-17 00:05:22 +000079 PyMem_DEL(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000080 self = NULL;
Barry Warsawd0c10421996-12-17 00:05:22 +000081 PyErr_SetString(ThreadError, "can't allocate lock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +000082 }
83 return self;
84}
85
86static void
87lock_dealloc(self)
88 lockobject *self;
89{
90 /* Unlock the lock so it's safe to free it */
91 acquire_lock(self->lock_lock, 0);
92 release_lock(self->lock_lock);
93
94 free_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000095 PyMem_DEL(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000096}
97
Barry Warsawd0c10421996-12-17 00:05:22 +000098static PyObject *
Guido van Rossum1984f1e1992-08-04 12:41:02 +000099lock_acquire_lock(self, args)
100 lockobject *self;
Barry Warsawd0c10421996-12-17 00:05:22 +0000101 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000102{
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000103 int i;
104
105 if (args != NULL) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000106 if (!PyArg_Parse(args, "i", &i))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000107 return NULL;
108 }
109 else
110 i = 1;
111
Barry Warsawd0c10421996-12-17 00:05:22 +0000112 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000113 i = acquire_lock(self->lock_lock, i);
Barry Warsawd0c10421996-12-17 00:05:22 +0000114 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000115
116 if (args == NULL) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000117 Py_INCREF(Py_None);
118 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000119 }
120 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000121 return PyInt_FromLong((long)i);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000122}
123
Barry Warsawd0c10421996-12-17 00:05:22 +0000124static PyObject *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000125lock_release_lock(self, args)
126 lockobject *self;
Barry Warsawd0c10421996-12-17 00:05:22 +0000127 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000128{
Barry Warsawd0c10421996-12-17 00:05:22 +0000129 if (!PyArg_NoArgs(args))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000130 return NULL;
131
132 /* Sanity check: the lock must be locked */
133 if (acquire_lock(self->lock_lock, 0)) {
134 release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +0000135 PyErr_SetString(ThreadError, "release unlocked lock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000136 return NULL;
137 }
138
139 release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +0000140 Py_INCREF(Py_None);
141 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000142}
143
Barry Warsawd0c10421996-12-17 00:05:22 +0000144static PyObject *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000145lock_locked_lock(self, args)
146 lockobject *self;
Barry Warsawd0c10421996-12-17 00:05:22 +0000147 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000148{
Barry Warsawd0c10421996-12-17 00:05:22 +0000149 if (!PyArg_NoArgs(args))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000150 return NULL;
151
152 if (acquire_lock(self->lock_lock, 0)) {
153 release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +0000154 return PyInt_FromLong(0L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000155 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000156 return PyInt_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000157}
158
Barry Warsawd0c10421996-12-17 00:05:22 +0000159static PyMethodDef lock_methods[] = {
160 {"acquire_lock", (PyCFunction)lock_acquire_lock},
161 {"acquire", (PyCFunction)lock_acquire_lock},
162 {"release_lock", (PyCFunction)lock_release_lock},
163 {"release", (PyCFunction)lock_release_lock},
164 {"locked_lock", (PyCFunction)lock_locked_lock},
165 {"locked", (PyCFunction)lock_locked_lock},
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000166 {NULL, NULL} /* sentinel */
167};
168
Barry Warsawd0c10421996-12-17 00:05:22 +0000169static PyObject *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000170lock_getattr(self, name)
171 lockobject *self;
172 char *name;
173{
Barry Warsawd0c10421996-12-17 00:05:22 +0000174 return Py_FindMethod(lock_methods, (PyObject *)self, name);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000175}
176
Barry Warsawd0c10421996-12-17 00:05:22 +0000177static PyTypeObject Locktype = {
178 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000179 0, /*ob_size*/
180 "lock", /*tp_name*/
181 sizeof(lockobject), /*tp_size*/
182 0, /*tp_itemsize*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000183 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000184 (destructor)lock_dealloc, /*tp_dealloc*/
185 0, /*tp_print*/
186 (getattrfunc)lock_getattr, /*tp_getattr*/
187 0, /*tp_setattr*/
188 0, /*tp_compare*/
189 0, /*tp_repr*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000190};
191
192
193/* Module functions */
194
195static void
196t_bootstrap(args_raw)
197 void *args_raw;
198{
Barry Warsawd0c10421996-12-17 00:05:22 +0000199 PyObject *args = (PyObject *) args_raw;
200 PyObject *func, *arg, *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000201
Barry Warsawd0c10421996-12-17 00:05:22 +0000202 _PyThread_Started++;
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000203
Barry Warsawd0c10421996-12-17 00:05:22 +0000204 PyEval_RestoreThread((void *)NULL);
205 func = PyTuple_GetItem(args, 0);
206 arg = PyTuple_GetItem(args, 1);
207 res = PyEval_CallObject(func, arg);
208 Py_DECREF(args); /* Matches the INCREF(args) in thread_start_new_thread */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000209 if (res == NULL) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000210 if (PyErr_Occurred() == PyExc_SystemExit)
211 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000212 else {
213 fprintf(stderr, "Unhandled exception in thread:\n");
Barry Warsawd0c10421996-12-17 00:05:22 +0000214 PyErr_Print(); /* From pythonmain.c */
Guido van Rossum385e7c61995-03-17 10:42:27 +0000215 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000216 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000217 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000218 Py_DECREF(res);
219 (void) PyEval_SaveThread(); /* Should always be NULL */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000220 exit_thread();
221}
222
Barry Warsawd0c10421996-12-17 00:05:22 +0000223static PyObject *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000224thread_start_new_thread(self, args)
Barry Warsawd0c10421996-12-17 00:05:22 +0000225 PyObject *self; /* Not used */
226 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000227{
Barry Warsawd0c10421996-12-17 00:05:22 +0000228 PyObject *func, *arg;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000229
Barry Warsawd0c10421996-12-17 00:05:22 +0000230 if (!PyArg_Parse(args, "(OO)", &func, &arg))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000231 return NULL;
Barry Warsawd0c10421996-12-17 00:05:22 +0000232 Py_INCREF(args);
Sjoerd Mullendered59d201993-01-06 13:36:38 +0000233 /* Initialize the interpreter's stack save/restore mechanism */
Barry Warsawd0c10421996-12-17 00:05:22 +0000234 PyEval_InitThreads();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000235 if (!start_new_thread(t_bootstrap, (void*) args)) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000236 Py_DECREF(args);
237 PyErr_SetString(ThreadError, "can't start new thread\n");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000238 return NULL;
239 }
240 /* Otherwise the DECREF(args) is done by t_bootstrap */
Barry Warsawd0c10421996-12-17 00:05:22 +0000241 Py_INCREF(Py_None);
242 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000243}
244
Barry Warsawd0c10421996-12-17 00:05:22 +0000245static PyObject *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000246thread_exit_thread(self, args)
Barry Warsawd0c10421996-12-17 00:05:22 +0000247 PyObject *self; /* Not used */
248 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000249{
Barry Warsawd0c10421996-12-17 00:05:22 +0000250 if (!PyArg_NoArgs(args))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000251 return NULL;
Barry Warsawd0c10421996-12-17 00:05:22 +0000252 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000253 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000254}
255
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000257static PyObject *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000258thread_exit_prog(self, args)
Barry Warsawd0c10421996-12-17 00:05:22 +0000259 PyObject *self; /* Not used */
260 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000261{
262 int sts;
Barry Warsawd0c10421996-12-17 00:05:22 +0000263 if (!PyArg_Parse(args, "i", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000264 return NULL;
Barry Warsawd0c10421996-12-17 00:05:22 +0000265 Py_Exit(sts); /* Calls exit_prog(sts) or _exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000266 for (;;) { } /* Should not be reached */
267}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000269
Barry Warsawd0c10421996-12-17 00:05:22 +0000270static PyObject *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000271thread_allocate_lock(self, args)
Barry Warsawd0c10421996-12-17 00:05:22 +0000272 PyObject *self; /* Not used */
273 PyObject *args;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000274{
Barry Warsawd0c10421996-12-17 00:05:22 +0000275 if (!PyArg_NoArgs(args))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000276 return NULL;
Barry Warsawd0c10421996-12-17 00:05:22 +0000277 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000278}
279
Barry Warsawd0c10421996-12-17 00:05:22 +0000280static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281thread_get_ident(self, args)
Barry Warsawd0c10421996-12-17 00:05:22 +0000282 PyObject *self; /* Not used */
283 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284{
285 long ident;
Barry Warsawd0c10421996-12-17 00:05:22 +0000286 if (!PyArg_NoArgs(args))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287 return NULL;
288 ident = get_thread_ident();
289 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000290 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291 return NULL;
292 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000293 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000294}
295
Barry Warsawd0c10421996-12-17 00:05:22 +0000296static PyMethodDef thread_methods[] = {
297 {"start_new_thread", (PyCFunction)thread_start_new_thread},
298 {"start_new", (PyCFunction)thread_start_new_thread},
299 {"allocate_lock", (PyCFunction)thread_allocate_lock},
300 {"allocate", (PyCFunction)thread_allocate_lock},
301 {"exit_thread", (PyCFunction)thread_exit_thread},
302 {"exit", (PyCFunction)thread_exit_thread},
303 {"get_ident", (PyCFunction)thread_get_ident},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000304#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000305 {"exit_prog", (PyCFunction)thread_exit_prog},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000306#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000307 {NULL, NULL} /* sentinel */
308};
309
310
311/* Initialization function */
312
313void
314initthread()
315{
Barry Warsawd0c10421996-12-17 00:05:22 +0000316 PyObject *m, *d;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000317
318 /* Create the module and add the functions */
Barry Warsawd0c10421996-12-17 00:05:22 +0000319 m = Py_InitModule("thread", thread_methods);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000320
321 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000322 d = PyModule_GetDict(m);
323 ThreadError = PyString_FromString("thread.error");
Barry Warsawd0c10421996-12-17 00:05:22 +0000324 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000325
326 /* Check for errors */
Barry Warsawd0c10421996-12-17 00:05:22 +0000327 if (PyErr_Occurred())
328 Py_FatalError("can't initialize module thread");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000329
330 /* Initialize the C thread library */
331 init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000332}