diff options
author | Guido van Rossum <guido@python.org> | 1997-05-05 20:56:21 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1997-05-05 20:56:21 (GMT) |
commit | a027efa5bfa7911b5c4b522b6a0698749a6f2e4a (patch) | |
tree | 7027609cb66223aba0355957599aa7629fce7e53 /Modules | |
parent | 73237c54b40c345813fa6b7831a32b10fa4671b5 (diff) | |
download | cpython-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')
-rw-r--r-- | Modules/threadmodule.c | 91 |
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}, |