blob: 24a32ae3252772840cb30a9d9beb7ec02e88f1d7 [file] [log] [blame]
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001
2/* Thread module */
3/* Interface to Sjoerd's portable C thread library */
4
Barry Warsawd0c10421996-12-17 00:05:22 +00005#include "Python.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +00006
Guido van Rossumb6775db1994-08-01 11:34:53 +00007#ifndef WITH_THREAD
Guido van Rossuma027efa1997-05-05 20:56:21 +00008#error "Error! The rest of Python is not compiled with thread support."
Neal Norwitz884baa12002-09-05 21:31:04 +00009#error "Rerun configure, adding a --with-threads option."
Guido van Rossuma027efa1997-05-05 20:56:21 +000010#error "Then run `make clean' followed by `make'."
Guido van Rossumb6775db1994-08-01 11:34:53 +000011#endif
12
Guido van Rossum49b56061998-10-01 20:42:43 +000013#include "pythread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000014
Barry Warsawd0c10421996-12-17 00:05:22 +000015static PyObject *ThreadError;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000016
17
18/* Lock objects */
19
20typedef struct {
Barry Warsawd0c10421996-12-17 00:05:22 +000021 PyObject_HEAD
Guido van Rossum65d5b571998-12-21 19:32:43 +000022 PyThread_type_lock lock_lock;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000023} lockobject;
24
Jeremy Hylton938ace62002-07-17 16:30:39 +000025static PyTypeObject Locktype;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000026
Guido van Rossum1984f1e1992-08-04 12:41:02 +000027static lockobject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000028newlockobject(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000029{
30 lockobject *self;
Guido van Rossumb18618d2000-05-03 23:44:39 +000031 self = PyObject_New(lockobject, &Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000032 if (self == NULL)
33 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +000034 self->lock_lock = PyThread_allocate_lock();
Guido van Rossum1984f1e1992-08-04 12:41:02 +000035 if (self->lock_lock == NULL) {
Guido van Rossumb18618d2000-05-03 23:44:39 +000036 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000037 self = NULL;
Barry Warsawd0c10421996-12-17 00:05:22 +000038 PyErr_SetString(ThreadError, "can't allocate lock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +000039 }
40 return self;
41}
42
43static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000044lock_dealloc(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000045{
46 /* Unlock the lock so it's safe to free it */
Guido van Rossum65d5b571998-12-21 19:32:43 +000047 PyThread_acquire_lock(self->lock_lock, 0);
48 PyThread_release_lock(self->lock_lock);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000049
Guido van Rossum65d5b571998-12-21 19:32:43 +000050 PyThread_free_lock(self->lock_lock);
Guido van Rossumb18618d2000-05-03 23:44:39 +000051 PyObject_Del(self);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000052}
53
Barry Warsawd0c10421996-12-17 00:05:22 +000054static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +000055lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000056{
Neal Norwitzba3a16c2002-03-31 15:27:00 +000057 int i = 1;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000058
Neal Norwitzba3a16c2002-03-31 15:27:00 +000059 if (!PyArg_ParseTuple(args, "|i:acquire", &i))
60 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000061
Barry Warsawd0c10421996-12-17 00:05:22 +000062 Py_BEGIN_ALLOW_THREADS
Guido van Rossum65d5b571998-12-21 19:32:43 +000063 i = PyThread_acquire_lock(self->lock_lock, i);
Barry Warsawd0c10421996-12-17 00:05:22 +000064 Py_END_ALLOW_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +000065
66 if (args == NULL) {
Barry Warsawd0c10421996-12-17 00:05:22 +000067 Py_INCREF(Py_None);
68 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000069 }
70 else
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000071 return PyBool_FromLong((long)i);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000072}
73
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000074PyDoc_STRVAR(acquire_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000075"acquire([wait]) -> None or bool\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +000076(PyThread_acquire_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000077\n\
78Lock the lock. Without argument, this blocks if the lock is already\n\
79locked (even by the same thread), waiting for another thread to release\n\
Guido van Rossum8fdc75b2002-04-07 06:32:21 +000080the lock, and return None once the lock is acquired.\n\
81With an argument, this will only block if the argument is true,\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +000082and the return value reflects whether the lock is acquired.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000083The blocking operation is not interruptible.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +000084
Barry Warsawd0c10421996-12-17 00:05:22 +000085static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000086lock_PyThread_release_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +000087{
Guido van Rossum1984f1e1992-08-04 12:41:02 +000088 /* Sanity check: the lock must be locked */
Guido van Rossum65d5b571998-12-21 19:32:43 +000089 if (PyThread_acquire_lock(self->lock_lock, 0)) {
90 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000091 PyErr_SetString(ThreadError, "release unlocked lock");
Guido van Rossum1984f1e1992-08-04 12:41:02 +000092 return NULL;
93 }
94
Guido van Rossum65d5b571998-12-21 19:32:43 +000095 PyThread_release_lock(self->lock_lock);
Barry Warsawd0c10421996-12-17 00:05:22 +000096 Py_INCREF(Py_None);
97 return Py_None;
Guido van Rossum1984f1e1992-08-04 12:41:02 +000098}
99
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000100PyDoc_STRVAR(release_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000101"release()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000102(PyThread_release_lock() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000103\n\
104Release the lock, allowing another thread that is blocked waiting for\n\
105the lock to acquire the lock. The lock must be in the locked state,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000106but it needn't be locked by the same thread that unlocks it.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000107
Barry Warsawd0c10421996-12-17 00:05:22 +0000108static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000109lock_locked_lock(lockobject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000110{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000111 if (PyThread_acquire_lock(self->lock_lock, 0)) {
112 PyThread_release_lock(self->lock_lock);
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000113 return PyBool_FromLong(0L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000114 }
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000115 return PyBool_FromLong(1L);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000116}
117
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000118PyDoc_STRVAR(locked_doc,
Guido van Rossum8fdc75b2002-04-07 06:32:21 +0000119"locked() -> bool\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000120(locked_lock() is an obsolete synonym)\n\
121\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000122Return whether the lock is in the locked state.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000123
Barry Warsawd0c10421996-12-17 00:05:22 +0000124static PyMethodDef lock_methods[] = {
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000125 {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000126 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000127 {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000128 METH_VARARGS, acquire_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000129 {"release_lock", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000130 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000131 {"release", (PyCFunction)lock_PyThread_release_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000132 METH_NOARGS, release_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000133 {"locked_lock", (PyCFunction)lock_locked_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000134 METH_NOARGS, locked_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000135 {"locked", (PyCFunction)lock_locked_lock,
Neal Norwitz23584252002-03-25 21:05:50 +0000136 METH_NOARGS, locked_doc},
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000137 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000138};
139
Barry Warsawd0c10421996-12-17 00:05:22 +0000140static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000141lock_getattr(lockobject *self, char *name)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000142{
Barry Warsawd0c10421996-12-17 00:05:22 +0000143 return Py_FindMethod(lock_methods, (PyObject *)self, name);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000144}
145
Barry Warsawd0c10421996-12-17 00:05:22 +0000146static PyTypeObject Locktype = {
147 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000148 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000149 "thread.lock", /*tp_name*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000150 sizeof(lockobject), /*tp_size*/
151 0, /*tp_itemsize*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000152 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000153 (destructor)lock_dealloc, /*tp_dealloc*/
154 0, /*tp_print*/
155 (getattrfunc)lock_getattr, /*tp_getattr*/
156 0, /*tp_setattr*/
157 0, /*tp_compare*/
158 0, /*tp_repr*/
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000159};
160
161
162/* Module functions */
163
Guido van Rossuma027efa1997-05-05 20:56:21 +0000164struct bootstate {
165 PyInterpreterState *interp;
166 PyObject *func;
167 PyObject *args;
168 PyObject *keyw;
169};
170
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000171static void
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000172t_bootstrap(void *boot_raw)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000173{
Guido van Rossuma027efa1997-05-05 20:56:21 +0000174 struct bootstate *boot = (struct bootstate *) boot_raw;
Guido van Rossum75aa0d61997-07-18 23:57:50 +0000175 PyThreadState *tstate;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000176 PyObject *res;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000177
Guido van Rossuma027efa1997-05-05 20:56:21 +0000178 tstate = PyThreadState_New(boot->interp);
Guido van Rossum75aa0d61997-07-18 23:57:50 +0000179 PyEval_AcquireThread(tstate);
Guido van Rossuma027efa1997-05-05 20:56:21 +0000180 res = PyEval_CallObjectWithKeywords(
181 boot->func, boot->args, boot->keyw);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000182 if (res == NULL) {
Fred Drakebebc97f1998-05-28 04:35:12 +0000183 if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsawd0c10421996-12-17 00:05:22 +0000184 PyErr_Clear();
Guido van Rossum385e7c61995-03-17 10:42:27 +0000185 else {
Guido van Rossum24ccca12003-04-29 19:44:05 +0000186 PyObject *file;
187 PySys_WriteStderr(
188 "Unhandled exception in thread started by ");
189 file = PySys_GetObject("stderr");
190 if (file)
191 PyFile_WriteObject(boot->func, file, 0);
192 else
193 PyObject_Print(boot->func, stderr, 0);
194 PySys_WriteStderr("\n");
Guido van Rossum40769dd1998-02-06 22:32:08 +0000195 PyErr_PrintEx(0);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000196 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000197 }
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000198 else
Barry Warsawd0c10421996-12-17 00:05:22 +0000199 Py_DECREF(res);
Guido van Rossum24ccca12003-04-29 19:44:05 +0000200 Py_DECREF(boot->func);
201 Py_DECREF(boot->args);
202 Py_XDECREF(boot->keyw);
203 PyMem_DEL(boot_raw);
Guido van Rossumb02158e1997-08-02 03:13:11 +0000204 PyThreadState_Clear(tstate);
Guido van Rossum2528b192001-01-23 01:47:18 +0000205 PyThreadState_DeleteCurrent();
Guido van Rossumbcc20741998-08-04 22:53:56 +0000206 PyThread_exit_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000207}
208
Barry Warsawd0c10421996-12-17 00:05:22 +0000209static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000210thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000211{
Guido van Rossum38d45b72000-09-01 20:47:58 +0000212 PyObject *func, *args, *keyw = NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000213 struct bootstate *boot;
Guido van Rossum3c288632001-10-16 21:13:49 +0000214 long ident;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000215
Guido van Rossum43713e52000-02-29 13:59:29 +0000216 if (!PyArg_ParseTuple(fargs, "OO|O:start_new_thread", &func, &args, &keyw))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000217 return NULL;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000218 if (!PyCallable_Check(func)) {
219 PyErr_SetString(PyExc_TypeError,
220 "first arg must be callable");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000221 return NULL;
222 }
Guido van Rossuma027efa1997-05-05 20:56:21 +0000223 if (!PyTuple_Check(args)) {
224 PyErr_SetString(PyExc_TypeError,
Guido van Rossum38d45b72000-09-01 20:47:58 +0000225 "2nd arg must be a tuple");
Guido van Rossuma027efa1997-05-05 20:56:21 +0000226 return NULL;
227 }
228 if (keyw != NULL && !PyDict_Check(keyw)) {
229 PyErr_SetString(PyExc_TypeError,
230 "optional 3rd arg must be a dictionary");
231 return NULL;
232 }
233 boot = PyMem_NEW(struct bootstate, 1);
234 if (boot == NULL)
235 return PyErr_NoMemory();
Guido van Rossumb02158e1997-08-02 03:13:11 +0000236 boot->interp = PyThreadState_Get()->interp;
Guido van Rossuma027efa1997-05-05 20:56:21 +0000237 boot->func = func;
238 boot->args = args;
239 boot->keyw = keyw;
240 Py_INCREF(func);
241 Py_INCREF(args);
242 Py_XINCREF(keyw);
243 PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
Guido van Rossum3c288632001-10-16 21:13:49 +0000244 ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
245 if (ident == -1) {
Guido van Rossuma027efa1997-05-05 20:56:21 +0000246 PyErr_SetString(ThreadError, "can't start new thread\n");
247 Py_DECREF(func);
248 Py_DECREF(args);
249 Py_XDECREF(keyw);
250 PyMem_DEL(boot);
251 return NULL;
252 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000253 return PyInt_FromLong(ident);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000254}
255
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000256PyDoc_STRVAR(start_new_doc,
Andrew M. Kuchling38300c62001-10-05 12:24:15 +0000257"start_new_thread(function, args[, kwargs])\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000258(start_new() is an obsolete synonym)\n\
259\n\
Guido van Rossum3c288632001-10-16 21:13:49 +0000260Start a new thread and return its identifier. The thread will call the\n\
261function with positional arguments from the tuple args and keyword arguments\n\
262taken from the optional dictionary kwargs. The thread exits when the\n\
263function returns; the return value is ignored. The thread will also exit\n\
264when the function raises an unhandled exception; a stack trace will be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000265printed unless the exception is SystemExit.\n");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000266
Barry Warsawd0c10421996-12-17 00:05:22 +0000267static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000268thread_PyThread_exit_thread(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000269{
Barry Warsawd0c10421996-12-17 00:05:22 +0000270 PyErr_SetNone(PyExc_SystemExit);
Guido van Rossum385e7c61995-03-17 10:42:27 +0000271 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000272}
273
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000274PyDoc_STRVAR(exit_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000275"exit()\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000276(PyThread_exit_thread() is an obsolete synonym)\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000277\n\
278This is synonymous to ``raise SystemExit''. It will cause the current\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000279thread to exit silently unless the exception is caught.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000280
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000281static PyObject *
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000282thread_PyThread_interrupt_main(PyObject * self)
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000283{
284 PyErr_SetInterrupt();
285 Py_INCREF(Py_None);
286 return Py_None;
287}
288
289PyDoc_STRVAR(interrupt_doc,
290"interrupt_main()\n\
291\n\
292Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000293A subthread can use this function to interrupt the main thread."
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000294);
295
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296#ifndef NO_EXIT_PROG
Barry Warsawd0c10421996-12-17 00:05:22 +0000297static PyObject *
Peter Schneider-Kamp3707efe2000-07-10 10:03:58 +0000298thread_PyThread_exit_prog(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000299{
300 int sts;
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000301 if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000302 return NULL;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000303 Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000304 for (;;) { } /* Should not be reached */
305}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000306#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000307
Barry Warsawd0c10421996-12-17 00:05:22 +0000308static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000309thread_PyThread_allocate_lock(PyObject *self)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000310{
Barry Warsawd0c10421996-12-17 00:05:22 +0000311 return (PyObject *) newlockobject();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000312}
313
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000314PyDoc_STRVAR(allocate_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000315"allocate_lock() -> lock object\n\
316(allocate() is an obsolete synonym)\n\
317\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000318Create a new lock object. See LockType.__doc__ for information about locks.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000319
Barry Warsawd0c10421996-12-17 00:05:22 +0000320static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000321thread_get_ident(PyObject *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000322{
323 long ident;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000324 ident = PyThread_get_thread_ident();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000325 if (ident == -1) {
Barry Warsawd0c10421996-12-17 00:05:22 +0000326 PyErr_SetString(ThreadError, "no current thread ident");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000327 return NULL;
328 }
Barry Warsawd0c10421996-12-17 00:05:22 +0000329 return PyInt_FromLong(ident);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000330}
331
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000332PyDoc_STRVAR(get_ident_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000333"get_ident() -> integer\n\
334\n\
335Return a non-zero integer that uniquely identifies the current thread\n\
336amongst other threads that exist simultaneously.\n\
337This may be used to identify per-thread resources.\n\
338Even though on some platforms threads identities may appear to be\n\
339allocated consecutive numbers starting at 1, this behavior should not\n\
340be relied upon, and the number should be seen purely as a magic cookie.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000341A thread's identity may be reused for another thread after it exits.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000342
Barry Warsawd0c10421996-12-17 00:05:22 +0000343static PyMethodDef thread_methods[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000344 {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread,
345 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000346 start_new_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000347 {"start_new", (PyCFunction)thread_PyThread_start_new_thread,
348 METH_VARARGS,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000349 start_new_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000350 {"allocate_lock", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000351 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000352 {"allocate", (PyCFunction)thread_PyThread_allocate_lock,
Neal Norwitz46321172002-03-26 14:52:00 +0000353 METH_NOARGS, allocate_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000354 {"exit_thread", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000355 METH_NOARGS, exit_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000356 {"exit", (PyCFunction)thread_PyThread_exit_thread,
Neal Norwitz46321172002-03-26 14:52:00 +0000357 METH_NOARGS, exit_doc},
Kurt B. Kaisera1ad5f62003-06-16 18:51:28 +0000358 {"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
Kurt B. Kaisera11e8462003-06-13 21:59:45 +0000359 METH_NOARGS, interrupt_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000360 {"get_ident", (PyCFunction)thread_get_ident,
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000361 METH_NOARGS, get_ident_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000362#ifndef NO_EXIT_PROG
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000363 {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
364 METH_VARARGS},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000365#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000366 {NULL, NULL} /* sentinel */
367};
368
369
370/* Initialization function */
371
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000372PyDoc_STRVAR(thread_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000373"This module provides primitive operations to write multi-threaded programs.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000374The 'threading' module provides a more convenient interface.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000375
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000376PyDoc_STRVAR(lock_doc,
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000377"A lock object is a synchronization primitive. To create a lock,\n\
Guido van Rossum65d5b571998-12-21 19:32:43 +0000378call the PyThread_allocate_lock() function. Methods are:\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000379\n\
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000380acquire() -- lock the lock, possibly blocking until it can be obtained\n\
381release() -- unlock of the lock\n\
382locked() -- test whether the lock is currently locked\n\
383\n\
384A lock is not owned by the thread that locked it; another thread may\n\
385unlock it. A thread attempting to lock a lock that it has already locked\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000386will block until another thread unlocks it. Deadlocks may ensue.");
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000387
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000388PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000389initthread(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000390{
Barry Warsawd0c10421996-12-17 00:05:22 +0000391 PyObject *m, *d;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000392
393 /* Create the module and add the functions */
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000394 m = Py_InitModule3("thread", thread_methods, thread_doc);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000395
396 /* Add a symbolic constant */
Barry Warsawd0c10421996-12-17 00:05:22 +0000397 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000398 ThreadError = PyErr_NewException("thread.error", NULL, NULL);
Barry Warsawd0c10421996-12-17 00:05:22 +0000399 PyDict_SetItemString(d, "error", ThreadError);
Guido van Rossum75e9fc31998-06-27 18:21:06 +0000400 Locktype.tp_doc = lock_doc;
401 Py_INCREF(&Locktype);
402 PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000403
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000404 /* Initialize the C thread library */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000405 PyThread_init_thread();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000406}