diff options
author | Guido van Rossum <guido@python.org> | 1997-07-18 23:56:58 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1997-07-18 23:56:58 (GMT) |
commit | 2fca21f76280300201acf529527e58e2705ff6aa (patch) | |
tree | 58956bb1a49d02d54dbc226523c0a771cb48e05e /Python | |
parent | c864ad695f9831340d10b1b4161524a58780422f (diff) | |
download | cpython-2fca21f76280300201acf529527e58e2705ff6aa.zip cpython-2fca21f76280300201acf529527e58e2705ff6aa.tar.gz cpython-2fca21f76280300201acf529527e58e2705ff6aa.tar.bz2 |
PyEval_SaveThread() and PyEval_RestoreThread() now return/take a
PyThreadState pointer instead of a (frame) PyObject pointer. This
makes much more sense. It is backward incompatible, but that's no
problem, because (a) the heaviest users are the Py_{BEGIN,END}_
ALLOW_THREADS macros here, which have been fixed too; (b) there are
very few direct users; (c) those who use it are there will probably
appreciate the change.
Also, added new functions PyEval_AcquireThread() and
PyEval_ReleaseThread() which allows the threads created by the thread
module as well threads created by others (!) to set/reset the current
thread, and at the same time acquire/release the interpreter lock.
Much saner.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index ab1e90f..be4ffec 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -135,35 +135,57 @@ PyEval_InitThreads() dynamically loaded modules needn't be compiled separately for use with and without threads: */ -PyObject * +PyThreadState * PyEval_SaveThread() { #ifdef WITH_THREAD if (interpreter_lock) { PyThreadState *tstate = PyThreadState_Swap(NULL); - PyObject *res = tstate ? (PyObject *) (tstate->frame) : NULL; + if (tstate == NULL) + Py_FatalError("PyEval_SaveThread: NULL tstate"); release_lock(interpreter_lock); - return res; + return tstate; } #endif return NULL; } void -PyEval_RestoreThread(x) - PyObject *x; +PyEval_RestoreThread(tstate) + PyThreadState *tstate; { #ifdef WITH_THREAD if (interpreter_lock) { int err; err = errno; + if (tstate == NULL) + Py_FatalError("PyEval_RestoreThread: NULL tstate"); acquire_lock(interpreter_lock, 1); + PyThreadState_Swap(tstate); errno = err; - PyThreadState_Swap(x ? ((PyFrameObject *)x)->f_tstate : NULL); } #endif } +#ifdef WITH_THREAD +void +PyEval_AcquireThread(tstate) + PyThreadState *tstate; +{ + acquire_lock(interpreter_lock, 1); + if (PyThreadState_Swap(tstate) != NULL) + Py_FatalError("PyEval_AcquireThread: non-NULL old state"); +} + +void +PyEval_ReleaseThread(tstate) + PyThreadState *tstate; +{ + if (PyThreadState_Swap(NULL) != tstate) + Py_FatalError("PyEval_ReleaseThread: wrong thread state"); + release_lock(interpreter_lock); +} +#endif /* Mechanism whereby asynchronously executing callbacks (e.g. UNIX signal handlers or Mac I/O completion routines) can schedule calls |