| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Thread module */ | 
					
						
							|  |  |  | /* Interface to Sjoerd's portable C thread library */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | #ifndef WITH_THREAD
 | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | #error "Error!  The rest of Python is not compiled with thread support."
 | 
					
						
							| 
									
										
										
										
											2002-09-05 21:31:04 +00:00
										 |  |  | #error "Rerun configure, adding a --with-threads option."
 | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | #error "Then run `make clean' followed by `make'."
 | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-10-01 20:42:43 +00:00
										 |  |  | #include "pythread.h"
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | static PyObject *ThreadError; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Lock objects */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 	PyObject_HEAD | 
					
						
							| 
									
										
										
										
											1998-12-21 19:32:43 +00:00
										 |  |  | 	PyThread_type_lock lock_lock; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } lockobject; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-17 16:30:39 +00:00
										 |  |  | static PyTypeObject Locktype; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static lockobject * | 
					
						
							| 
									
										
										
										
											2000-07-21 06:00:07 +00:00
										 |  |  | newlockobject(void) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	lockobject *self; | 
					
						
							| 
									
										
										
										
											2000-05-03 23:44:39 +00:00
										 |  |  | 	self = PyObject_New(lockobject, &Locktype); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	if (self == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1998-12-21 19:32:43 +00:00
										 |  |  | 	self->lock_lock = PyThread_allocate_lock(); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	if (self->lock_lock == NULL) { | 
					
						
							| 
									
										
										
										
											2000-05-03 23:44:39 +00:00
										 |  |  | 		PyObject_Del(self); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 		self = NULL; | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 		PyErr_SetString(ThreadError, "can't allocate lock"); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return self; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2000-07-10 10:03:58 +00:00
										 |  |  | lock_dealloc(lockobject *self) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* Unlock the lock so it's safe to free it */ | 
					
						
							| 
									
										
										
										
											1998-12-21 19:32:43 +00:00
										 |  |  | 	PyThread_acquire_lock(self->lock_lock, 0); | 
					
						
							|  |  |  | 	PyThread_release_lock(self->lock_lock); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											1998-12-21 19:32:43 +00:00
										 |  |  | 	PyThread_free_lock(self->lock_lock); | 
					
						
							| 
									
										
										
										
											2000-05-03 23:44:39 +00:00
										 |  |  | 	PyObject_Del(self); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2000-07-10 10:03:58 +00:00
										 |  |  | lock_PyThread_acquire_lock(lockobject *self, PyObject *args) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2002-03-31 15:27:00 +00:00
										 |  |  | 	int i = 1; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-03-31 15:27:00 +00:00
										 |  |  | 	if (!PyArg_ParseTuple(args, "|i:acquire", &i)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 	Py_BEGIN_ALLOW_THREADS | 
					
						
							| 
									
										
										
										
											1998-12-21 19:32:43 +00:00
										 |  |  | 	i = PyThread_acquire_lock(self->lock_lock, i); | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 	Py_END_ALLOW_THREADS | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (args == NULL) { | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 		Py_INCREF(Py_None); | 
					
						
							|  |  |  | 		return Py_None; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							| 
									
										
										
										
											2002-04-07 06:32:21 +00:00
										 |  |  | 		return PyBool_FromLong((long)i); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | PyDoc_STRVAR(acquire_doc, | 
					
						
							| 
									
										
										
										
											2002-04-07 06:32:21 +00:00
										 |  |  | "acquire([wait]) -> None or bool\n\
 | 
					
						
							| 
									
										
										
										
											1998-12-21 19:32:43 +00:00
										 |  |  | (PyThread_acquire_lock() is an obsolete synonym)\n\ | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | \n\ | 
					
						
							|  |  |  | Lock the lock.  Without argument, this blocks if the lock is already\n\ | 
					
						
							|  |  |  | locked (even by the same thread), waiting for another thread to release\n\ | 
					
						
							| 
									
										
										
										
											2002-04-07 06:32:21 +00:00
										 |  |  | the lock, and return None once the lock is acquired.\n\ | 
					
						
							|  |  |  | With an argument, this will only block if the argument is true,\n\ | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | and the return value reflects whether the lock is acquired.\n\ | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | The blocking operation is not interruptible."); | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2002-03-25 20:46:46 +00:00
										 |  |  | lock_PyThread_release_lock(lockobject *self) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* Sanity check: the lock must be locked */ | 
					
						
							| 
									
										
										
										
											1998-12-21 19:32:43 +00:00
										 |  |  | 	if (PyThread_acquire_lock(self->lock_lock, 0)) { | 
					
						
							|  |  |  | 		PyThread_release_lock(self->lock_lock); | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 		PyErr_SetString(ThreadError, "release unlocked lock"); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-12-21 19:32:43 +00:00
										 |  |  | 	PyThread_release_lock(self->lock_lock); | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 	Py_INCREF(Py_None); | 
					
						
							|  |  |  | 	return Py_None; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | PyDoc_STRVAR(release_doc, | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | "release()\n\
 | 
					
						
							| 
									
										
										
										
											1998-12-21 19:32:43 +00:00
										 |  |  | (PyThread_release_lock() is an obsolete synonym)\n\ | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | \n\ | 
					
						
							|  |  |  | Release the lock, allowing another thread that is blocked waiting for\n\ | 
					
						
							|  |  |  | the lock to acquire the lock.  The lock must be in the locked state,\n\ | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | but it needn't be locked by the same thread that unlocks it."); | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2002-03-25 20:46:46 +00:00
										 |  |  | lock_locked_lock(lockobject *self) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1998-12-21 19:32:43 +00:00
										 |  |  | 	if (PyThread_acquire_lock(self->lock_lock, 0)) { | 
					
						
							|  |  |  | 		PyThread_release_lock(self->lock_lock); | 
					
						
							| 
									
										
										
										
											2002-04-07 06:32:21 +00:00
										 |  |  | 		return PyBool_FromLong(0L); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2002-04-07 06:32:21 +00:00
										 |  |  | 	return PyBool_FromLong(1L); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | PyDoc_STRVAR(locked_doc, | 
					
						
							| 
									
										
										
										
											2002-04-07 06:32:21 +00:00
										 |  |  | "locked() -> bool\n\
 | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | (locked_lock() is an obsolete synonym)\n\ | 
					
						
							|  |  |  | \n\ | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | Return whether the lock is in the locked state."); | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | static PyMethodDef lock_methods[] = { | 
					
						
							| 
									
										
										
										
											2000-08-03 02:34:44 +00:00
										 |  |  | 	{"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,  | 
					
						
							| 
									
										
										
										
											2002-03-31 15:27:00 +00:00
										 |  |  | 	 METH_VARARGS, acquire_doc}, | 
					
						
							| 
									
										
										
										
											2000-08-03 02:34:44 +00:00
										 |  |  | 	{"acquire",      (PyCFunction)lock_PyThread_acquire_lock,  | 
					
						
							| 
									
										
										
										
											2002-03-31 15:27:00 +00:00
										 |  |  | 	 METH_VARARGS, acquire_doc}, | 
					
						
							| 
									
										
										
										
											2000-08-03 02:34:44 +00:00
										 |  |  | 	{"release_lock", (PyCFunction)lock_PyThread_release_lock,  | 
					
						
							| 
									
										
										
										
											2002-03-25 20:46:46 +00:00
										 |  |  | 	 METH_NOARGS, release_doc}, | 
					
						
							| 
									
										
										
										
											2000-08-03 02:34:44 +00:00
										 |  |  | 	{"release",      (PyCFunction)lock_PyThread_release_lock,  | 
					
						
							| 
									
										
										
										
											2002-03-25 21:05:50 +00:00
										 |  |  | 	 METH_NOARGS, release_doc}, | 
					
						
							| 
									
										
										
										
											2000-08-03 02:34:44 +00:00
										 |  |  | 	{"locked_lock",  (PyCFunction)lock_locked_lock,   | 
					
						
							| 
									
										
										
										
											2002-03-25 20:46:46 +00:00
										 |  |  | 	 METH_NOARGS, locked_doc}, | 
					
						
							| 
									
										
										
										
											2000-08-03 02:34:44 +00:00
										 |  |  | 	{"locked",       (PyCFunction)lock_locked_lock,   | 
					
						
							| 
									
										
										
										
											2002-03-25 21:05:50 +00:00
										 |  |  | 	 METH_NOARGS, locked_doc}, | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | 	{NULL,           NULL}		/* sentinel */ | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2000-07-10 10:03:58 +00:00
										 |  |  | lock_getattr(lockobject *self, char *name) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 	return Py_FindMethod(lock_methods, (PyObject *)self, name); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | static PyTypeObject Locktype = { | 
					
						
							|  |  |  | 	PyObject_HEAD_INIT(&PyType_Type) | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | 	0,				/*ob_size*/ | 
					
						
							| 
									
										
										
										
											2001-12-08 18:02:58 +00:00
										 |  |  | 	"thread.lock",			/*tp_name*/ | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | 	sizeof(lockobject),		/*tp_size*/ | 
					
						
							|  |  |  | 	0,				/*tp_itemsize*/ | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	/* methods */ | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | 	(destructor)lock_dealloc,	/*tp_dealloc*/ | 
					
						
							|  |  |  | 	0,				/*tp_print*/ | 
					
						
							|  |  |  | 	(getattrfunc)lock_getattr,	/*tp_getattr*/ | 
					
						
							|  |  |  | 	0,				/*tp_setattr*/ | 
					
						
							|  |  |  | 	0,				/*tp_compare*/ | 
					
						
							|  |  |  | 	0,				/*tp_repr*/ | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Module functions */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | struct bootstate { | 
					
						
							|  |  |  | 	PyInterpreterState *interp; | 
					
						
							|  |  |  | 	PyObject *func; | 
					
						
							|  |  |  | 	PyObject *args; | 
					
						
							|  |  |  | 	PyObject *keyw; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2000-07-10 10:03:58 +00:00
										 |  |  | t_bootstrap(void *boot_raw) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | 	struct bootstate *boot = (struct bootstate *) boot_raw; | 
					
						
							| 
									
										
										
										
											1997-07-18 23:57:50 +00:00
										 |  |  | 	PyThreadState *tstate; | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | 	PyObject *res; | 
					
						
							| 
									
										
										
										
											1992-08-17 08:59:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | 	tstate = PyThreadState_New(boot->interp); | 
					
						
							| 
									
										
										
										
											1997-07-18 23:57:50 +00:00
										 |  |  | 	PyEval_AcquireThread(tstate); | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | 	res = PyEval_CallObjectWithKeywords( | 
					
						
							|  |  |  | 		boot->func, boot->args, boot->keyw); | 
					
						
							|  |  |  | 	Py_DECREF(boot->func); | 
					
						
							|  |  |  | 	Py_DECREF(boot->args); | 
					
						
							|  |  |  | 	Py_XDECREF(boot->keyw); | 
					
						
							|  |  |  | 	PyMem_DEL(boot_raw); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	if (res == NULL) { | 
					
						
							| 
									
										
										
										
											1998-05-28 04:35:12 +00:00
										 |  |  | 		if (PyErr_ExceptionMatches(PyExc_SystemExit)) | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 			PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											1995-03-17 10:42:27 +00:00
										 |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2000-10-20 20:02:37 +00:00
										 |  |  | 			PySys_WriteStderr("Unhandled exception in thread:\n"); | 
					
						
							| 
									
										
										
										
											1998-02-06 22:32:08 +00:00
										 |  |  | 			PyErr_PrintEx(0); | 
					
						
							| 
									
										
										
										
											1995-03-17 10:42:27 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1995-01-02 19:30:30 +00:00
										 |  |  | 	else | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 		Py_DECREF(res); | 
					
						
							| 
									
										
										
										
											1997-08-02 03:13:11 +00:00
										 |  |  | 	PyThreadState_Clear(tstate); | 
					
						
							| 
									
										
										
										
											2001-01-23 01:47:18 +00:00
										 |  |  | 	PyThreadState_DeleteCurrent(); | 
					
						
							| 
									
										
										
										
											1998-08-04 22:53:56 +00:00
										 |  |  | 	PyThread_exit_thread(); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2000-07-10 10:03:58 +00:00
										 |  |  | thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-09-01 20:47:58 +00:00
										 |  |  | 	PyObject *func, *args, *keyw = NULL; | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | 	struct bootstate *boot; | 
					
						
							| 
									
										
										
										
											2001-10-16 21:13:49 +00:00
										 |  |  | 	long ident; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-29 13:59:29 +00:00
										 |  |  | 	if (!PyArg_ParseTuple(fargs, "OO|O:start_new_thread", &func, &args, &keyw)) | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	if (!PyCallable_Check(func)) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  | 				"first arg must be callable"); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if (!PyTuple_Check(args)) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_TypeError, | 
					
						
							| 
									
										
										
										
											2000-09-01 20:47:58 +00:00
										 |  |  | 				"2nd arg must be a tuple"); | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (keyw != NULL && !PyDict_Check(keyw)) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  | 				"optional 3rd arg must be a dictionary"); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	boot = PyMem_NEW(struct bootstate, 1); | 
					
						
							|  |  |  | 	if (boot == NULL) | 
					
						
							|  |  |  | 		return PyErr_NoMemory(); | 
					
						
							| 
									
										
										
										
											1997-08-02 03:13:11 +00:00
										 |  |  | 	boot->interp = PyThreadState_Get()->interp; | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | 	boot->func = func; | 
					
						
							|  |  |  | 	boot->args = args; | 
					
						
							|  |  |  | 	boot->keyw = keyw; | 
					
						
							|  |  |  | 	Py_INCREF(func); | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 	Py_INCREF(args); | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | 	Py_XINCREF(keyw); | 
					
						
							|  |  |  | 	PyEval_InitThreads(); /* Start the interpreter's thread-awareness */ | 
					
						
							| 
									
										
										
										
											2001-10-16 21:13:49 +00:00
										 |  |  | 	ident = PyThread_start_new_thread(t_bootstrap, (void*) boot); | 
					
						
							|  |  |  | 	if (ident == -1) { | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 		PyErr_SetString(ThreadError, "can't start new thread\n"); | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | 		Py_DECREF(func); | 
					
						
							|  |  |  | 		Py_DECREF(args); | 
					
						
							|  |  |  | 		Py_XDECREF(keyw); | 
					
						
							|  |  |  | 		PyMem_DEL(boot); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-10-16 21:13:49 +00:00
										 |  |  | 	return PyInt_FromLong(ident); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | PyDoc_STRVAR(start_new_doc, | 
					
						
							| 
									
										
										
										
											2001-10-05 12:24:15 +00:00
										 |  |  | "start_new_thread(function, args[, kwargs])\n\
 | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | (start_new() is an obsolete synonym)\n\ | 
					
						
							|  |  |  | \n\ | 
					
						
							| 
									
										
										
										
											2001-10-16 21:13:49 +00:00
										 |  |  | Start a new thread and return its identifier.  The thread will call the\n\ | 
					
						
							|  |  |  | function with positional arguments from the tuple args and keyword arguments\n\ | 
					
						
							|  |  |  | taken from the optional dictionary kwargs.  The thread exits when the\n\ | 
					
						
							|  |  |  | function returns; the return value is ignored.  The thread will also exit\n\ | 
					
						
							|  |  |  | when the function raises an unhandled exception; a stack trace will be\n\ | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | printed unless the exception is SystemExit.\n"); | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2002-03-25 20:46:46 +00:00
										 |  |  | thread_PyThread_exit_thread(PyObject *self) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 	PyErr_SetNone(PyExc_SystemExit); | 
					
						
							| 
									
										
										
										
											1995-03-17 10:42:27 +00:00
										 |  |  | 	return NULL; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | PyDoc_STRVAR(exit_doc, | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | "exit()\n\
 | 
					
						
							| 
									
										
										
										
											1998-12-21 19:32:43 +00:00
										 |  |  | (PyThread_exit_thread() is an obsolete synonym)\n\ | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | \n\ | 
					
						
							|  |  |  | This is synonymous to ``raise SystemExit''.  It will cause the current\n\ | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | thread to exit silently unless the exception is caught."); | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | #ifndef NO_EXIT_PROG
 | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2000-07-10 10:03:58 +00:00
										 |  |  | thread_PyThread_exit_prog(PyObject *self, PyObject *args) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int sts; | 
					
						
							| 
									
										
										
										
											2002-03-31 15:27:00 +00:00
										 |  |  | 	if (!PyArg_ParseTuple(args, "i:exit_prog", &sts)) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1998-12-21 19:32:43 +00:00
										 |  |  | 	Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */ | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	for (;;) { } /* Should not be reached */ | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2002-03-25 20:46:46 +00:00
										 |  |  | thread_PyThread_allocate_lock(PyObject *self) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 	return (PyObject *) newlockobject(); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | PyDoc_STRVAR(allocate_doc, | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | "allocate_lock() -> lock object\n\
 | 
					
						
							|  |  |  | (allocate() is an obsolete synonym)\n\ | 
					
						
							|  |  |  | \n\ | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | Create a new lock object.  See LockType.__doc__ for information about locks."); | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2002-03-25 20:46:46 +00:00
										 |  |  | thread_get_ident(PyObject *self) | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	long ident; | 
					
						
							| 
									
										
										
										
											1998-12-21 19:32:43 +00:00
										 |  |  | 	ident = PyThread_get_thread_ident(); | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | 	if (ident == -1) { | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 		PyErr_SetString(ThreadError, "no current thread ident"); | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 	return PyInt_FromLong(ident); | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | PyDoc_STRVAR(get_ident_doc, | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | "get_ident() -> integer\n\
 | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | Return a non-zero integer that uniquely identifies the current thread\n\ | 
					
						
							|  |  |  | amongst other threads that exist simultaneously.\n\ | 
					
						
							|  |  |  | This may be used to identify per-thread resources.\n\ | 
					
						
							|  |  |  | Even though on some platforms threads identities may appear to be\n\ | 
					
						
							|  |  |  | allocated consecutive numbers starting at 1, this behavior should not\n\ | 
					
						
							|  |  |  | be relied upon, and the number should be seen purely as a magic cookie.\n\ | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | A thread's identity may be reused for another thread after it exits."); | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | static PyMethodDef thread_methods[] = { | 
					
						
							| 
									
										
										
										
											2000-08-03 02:06:16 +00:00
										 |  |  | 	{"start_new_thread",	(PyCFunction)thread_PyThread_start_new_thread, | 
					
						
							|  |  |  | 	                        METH_VARARGS, | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | 				start_new_doc}, | 
					
						
							| 
									
										
										
										
											2000-08-03 02:06:16 +00:00
										 |  |  | 	{"start_new",		(PyCFunction)thread_PyThread_start_new_thread,  | 
					
						
							|  |  |  | 	                        METH_VARARGS, | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | 				start_new_doc}, | 
					
						
							| 
									
										
										
										
											2000-08-03 02:34:44 +00:00
										 |  |  | 	{"allocate_lock",	(PyCFunction)thread_PyThread_allocate_lock,  | 
					
						
							| 
									
										
										
										
											2002-03-25 20:46:46 +00:00
										 |  |  | 	 METH_NOARGS, allocate_doc}, | 
					
						
							| 
									
										
										
										
											2000-08-03 02:34:44 +00:00
										 |  |  | 	{"allocate",		(PyCFunction)thread_PyThread_allocate_lock,  | 
					
						
							| 
									
										
										
										
											2002-03-26 14:52:00 +00:00
										 |  |  | 	 METH_NOARGS, allocate_doc}, | 
					
						
							| 
									
										
										
										
											2000-08-03 02:34:44 +00:00
										 |  |  | 	{"exit_thread",		(PyCFunction)thread_PyThread_exit_thread,  | 
					
						
							| 
									
										
										
										
											2002-03-25 20:46:46 +00:00
										 |  |  | 	 METH_NOARGS, exit_doc}, | 
					
						
							| 
									
										
										
										
											2000-08-03 02:34:44 +00:00
										 |  |  | 	{"exit",		(PyCFunction)thread_PyThread_exit_thread,  | 
					
						
							| 
									
										
										
										
											2002-03-26 14:52:00 +00:00
										 |  |  | 	 METH_NOARGS, exit_doc}, | 
					
						
							| 
									
										
										
										
											2000-08-03 02:34:44 +00:00
										 |  |  | 	{"get_ident",		(PyCFunction)thread_get_ident,  | 
					
						
							| 
									
										
										
										
											2002-03-25 20:46:46 +00:00
										 |  |  | 	 METH_NOARGS, get_ident_doc}, | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | #ifndef NO_EXIT_PROG
 | 
					
						
							| 
									
										
										
										
											2002-03-31 15:27:00 +00:00
										 |  |  | 	{"exit_prog",		(PyCFunction)thread_PyThread_exit_prog, | 
					
						
							|  |  |  | 	 METH_VARARGS}, | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	{NULL,			NULL}		/* sentinel */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Initialization function */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | PyDoc_STRVAR(thread_doc, | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | "This module provides primitive operations to write multi-threaded programs.\n\
 | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | The 'threading' module provides a more convenient interface."); | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | PyDoc_STRVAR(lock_doc, | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | "A lock object is a synchronization primitive.  To create a lock,\n\
 | 
					
						
							| 
									
										
										
										
											1998-12-21 19:32:43 +00:00
										 |  |  | call the PyThread_allocate_lock() function.  Methods are:\n\ | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | \n\ | 
					
						
							|  |  |  | acquire() -- lock the lock, possibly blocking until it can be obtained\n\ | 
					
						
							|  |  |  | release() -- unlock of the lock\n\ | 
					
						
							|  |  |  | locked() -- test whether the lock is currently locked\n\ | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | A lock is not owned by the thread that locked it; another thread may\n\ | 
					
						
							|  |  |  | unlock it.  A thread attempting to lock a lock that it has already locked\n\ | 
					
						
							| 
									
										
										
										
											2002-06-13 20:33:02 +00:00
										 |  |  | will block until another thread unlocks it.  Deadlocks may ensue."); | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-08-02 02:27:13 +00:00
										 |  |  | PyMODINIT_FUNC | 
					
						
							| 
									
										
										
										
											2000-07-21 06:00:07 +00:00
										 |  |  | initthread(void) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 	PyObject *m, *d; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Create the module and add the functions */ | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | 	m = Py_InitModule3("thread", thread_methods, thread_doc); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Add a symbolic constant */ | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 	d = PyModule_GetDict(m); | 
					
						
							| 
									
										
										
										
											1997-10-01 04:29:29 +00:00
										 |  |  | 	ThreadError = PyErr_NewException("thread.error", NULL, NULL); | 
					
						
							| 
									
										
										
										
											1996-12-17 00:05:22 +00:00
										 |  |  | 	PyDict_SetItemString(d, "error", ThreadError); | 
					
						
							| 
									
										
										
										
											1998-06-27 18:21:06 +00:00
										 |  |  | 	Locktype.tp_doc = lock_doc; | 
					
						
							|  |  |  | 	Py_INCREF(&Locktype); | 
					
						
							|  |  |  | 	PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Initialize the C thread library */ | 
					
						
							| 
									
										
										
										
											1998-12-21 19:32:43 +00:00
										 |  |  | 	PyThread_init_thread(); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } |