summaryrefslogtreecommitdiffstats
path: root/Modules/threadmodule.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1997-05-05 20:56:21 (GMT)
committerGuido van Rossum <guido@python.org>1997-05-05 20:56:21 (GMT)
commita027efa5bfa7911b5c4b522b6a0698749a6f2e4a (patch)
tree7027609cb66223aba0355957599aa7629fce7e53 /Modules/threadmodule.c
parent73237c54b40c345813fa6b7831a32b10fa4671b5 (diff)
downloadcpython-a027efa5bfa7911b5c4b522b6a0698749a6f2e4a.zip
cpython-a027efa5bfa7911b5c4b522b6a0698749a6f2e4a.tar.gz
cpython-a027efa5bfa7911b5c4b522b6a0698749a6f2e4a.tar.bz2
Massive changes for separate thread state management.
All per-thread globals are moved into a struct which is manipulated separately.
Diffstat (limited to 'Modules/threadmodule.c')
-rw-r--r--Modules/threadmodule.c91
1 files changed, 64 insertions, 27 deletions
diff --git a/Modules/threadmodule.c b/Modules/threadmodule.c
index 461953e..99ca4af 100644
--- a/Modules/threadmodule.c
+++ b/Modules/threadmodule.c
@@ -35,14 +35,13 @@ PERFORMANCE OF THIS SOFTWARE.
#include "Python.h"
#ifndef WITH_THREAD
-Error! The rest of Python is not compiled with thread support.
-Rerun configure, adding a --with-thread option.
+#error "Error! The rest of Python is not compiled with thread support."
+#error "Rerun configure, adding a --with-thread option."
+#error "Then run `make clean' followed by `make'."
#endif
#include "thread.h"
-extern int _PyThread_Started;
-
static PyObject *ThreadError;
@@ -192,52 +191,90 @@ static PyTypeObject Locktype = {
/* Module functions */
+struct bootstate {
+ PyInterpreterState *interp;
+ PyObject *func;
+ PyObject *args;
+ PyObject *keyw;
+};
+
static void
-t_bootstrap(args_raw)
- void *args_raw;
+t_bootstrap(boot_raw)
+ void *boot_raw;
{
- PyObject *args = (PyObject *) args_raw;
- PyObject *func, *arg, *res;
-
- _PyThread_Started++;
+ struct bootstate *boot = (struct bootstate *) boot_raw;
+ PyThreadState *alttstate, *tstate;
+ PyObject *res;
+ tstate = PyThreadState_New(boot->interp);
PyEval_RestoreThread((void *)NULL);
- func = PyTuple_GetItem(args, 0);
- arg = PyTuple_GetItem(args, 1);
- res = PyEval_CallObject(func, arg);
- Py_DECREF(args); /* Matches the INCREF(args) in thread_start_new_thread */
+ alttstate = PyThreadState_Swap(tstate);
+ 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);
if (res == NULL) {
if (PyErr_Occurred() == PyExc_SystemExit)
PyErr_Clear();
else {
fprintf(stderr, "Unhandled exception in thread:\n");
- PyErr_Print(); /* From pythonmain.c */
+ PyErr_Print();
}
}
else
Py_DECREF(res);
- (void) PyEval_SaveThread(); /* Should always be NULL */
+ (void) PyThreadState_Swap(alttstate);
+ (void) PyEval_SaveThread();
+ PyThreadState_Delete(tstate);
exit_thread();
}
static PyObject *
-thread_start_new_thread(self, args)
+thread_start_new_thread(self, fargs)
PyObject *self; /* Not used */
- PyObject *args;
+ PyObject *fargs;
{
- PyObject *func, *arg;
+ PyObject *func, *args = NULL, *keyw = NULL;
+ struct bootstate *boot;
- if (!PyArg_Parse(args, "(OO)", &func, &arg))
+ if (!PyArg_ParseTuple(fargs, "OO|O", &func, &args, &keyw))
+ return NULL;
+ if (!PyCallable_Check(func)) {
+ PyErr_SetString(PyExc_TypeError,
+ "first arg must be callable");
return NULL;
+ }
+ if (!PyTuple_Check(args)) {
+ PyErr_SetString(PyExc_TypeError,
+ "optional 2nd arg must be a tuple");
+ 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();
+ boot->interp = PyThreadState_Get()->interpreter_state;
+ boot->func = func;
+ boot->args = args;
+ boot->keyw = keyw;
+ Py_INCREF(func);
Py_INCREF(args);
- /* Initialize the interpreter's stack save/restore mechanism */
- PyEval_InitThreads();
- if (!start_new_thread(t_bootstrap, (void*) args)) {
- Py_DECREF(args);
+ Py_XINCREF(keyw);
+ PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
+ if (!start_new_thread(t_bootstrap, (void*) boot)) {
PyErr_SetString(ThreadError, "can't start new thread\n");
+ Py_DECREF(func);
+ Py_DECREF(args);
+ Py_XDECREF(keyw);
+ PyMem_DEL(boot);
return NULL;
}
- /* Otherwise the DECREF(args) is done by t_bootstrap */
Py_INCREF(Py_None);
return Py_None;
}
@@ -294,8 +331,8 @@ thread_get_ident(self, args)
}
static PyMethodDef thread_methods[] = {
- {"start_new_thread", (PyCFunction)thread_start_new_thread},
- {"start_new", (PyCFunction)thread_start_new_thread},
+ {"start_new_thread", (PyCFunction)thread_start_new_thread, 1},
+ {"start_new", (PyCFunction)thread_start_new_thread, 1},
{"allocate_lock", (PyCFunction)thread_allocate_lock},
{"allocate", (PyCFunction)thread_allocate_lock},
{"exit_thread", (PyCFunction)thread_exit_thread},