Mercurial > cpython-lru_cache-weakref
diff Modules/threadmodule.c @ 5405:b7871ca930ad legacy-trunk
Massive changes for separate thread state management.
All per-thread globals are moved into a struct which is manipulated
separately.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Mon, 05 May 1997 20:56:21 +0000 |
| parents | 528c319c6e7f |
| children | ff9c0110079b |
line wrap: on
line diff
--- a/Modules/threadmodule.c Mon May 05 20:53:25 1997 +0000 +++ b/Modules/threadmodule.c Mon May 05 20:56:21 1997 +0000 @@ -35,14 +35,13 @@ #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 @@ /* Module functions */ -static void -t_bootstrap(args_raw) - void *args_raw; -{ - PyObject *args = (PyObject *) args_raw; - PyObject *func, *arg, *res; +struct bootstate { + PyInterpreterState *interp; + PyObject *func; + PyObject *args; + PyObject *keyw; +}; - _PyThread_Started++; +static void +t_bootstrap(boot_raw) + void *boot_raw; +{ + 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; - Py_INCREF(args); - /* Initialize the interpreter's stack save/restore mechanism */ - PyEval_InitThreads(); - if (!start_new_thread(t_bootstrap, (void*) args)) { - Py_DECREF(args); - PyErr_SetString(ThreadError, "can't start new thread\n"); + 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; } - /* Otherwise the DECREF(args) is done by t_bootstrap */ + 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); + 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; + } Py_INCREF(Py_None); return Py_None; } @@ -294,8 +331,8 @@ } 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},
