]> granicus.if.org Git - python/commitdiff
Fix from Michael Stone for SF bug #660476 and #513033 (bogus thread
authorGuido van Rossum <guido@python.org>
Tue, 7 Jan 2003 20:34:19 +0000 (20:34 +0000)
committerGuido van Rossum <guido@python.org>
Tue, 7 Jan 2003 20:34:19 +0000 (20:34 +0000)
state swaps in readline).

Misc/ACKS
Misc/NEWS
Modules/readline.c

index a9773d8fb422cbb82f52eb1182839bf5833159ad..f3f5b8b64909ce86fe8e08b62a910782775b7f80 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -511,6 +511,7 @@ Frank Stajano
 Richard Stoakley
 Casper Stoel
 Peter Stoehr
+Michael Stone
 Ken Stox
 Daniel Stutzbach
 Paul Swartz
index e1456fe7dcd51996d85cf9ab5aa503b7c21d81eb..5f3f8476aba063ed7bc81d48050379caceb376de 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -21,6 +21,10 @@ Core and builtins
 Extension modules
 -----------------
 
+- Fixed broken threadstate swap in readline that could cause fatal
+  errors when a readline hook was being invoked while a background
+  thread was active.  (SF bugs #660476 and #513033.)
+
 - fcntl now exposes the strops.h I_* constants.
 
 - datetime changes:
index 972b5b2db361ffd1a6435f93cadea8a8af5a8850..2ae996c0765d4c717a9c839cb99037d502e99daa 100644 (file)
@@ -481,16 +481,14 @@ static struct PyMethodDef readline_methods[] =
 /* C function to call the Python hooks. */
 
 static int
-on_hook(PyObject *func, PyThreadState *tstate)
+on_hook(PyObject *func, PyThreadState **tstate)
 {
        int result = 0;
        if (func != NULL) {
                PyObject *r;
-               PyThreadState *save_tstate;
                /* Note that readline is called with the interpreter
                   lock released! */
-               save_tstate = PyThreadState_Swap(NULL);
-               PyEval_RestoreThread(tstate);
+               PyEval_RestoreThread(*tstate);
                r = PyObject_CallFunction(func, NULL);
                if (r == NULL)
                        goto error;
@@ -504,8 +502,7 @@ on_hook(PyObject *func, PyThreadState *tstate)
                PyErr_Clear();
                Py_XDECREF(r);
          done:
-               PyEval_SaveThread();
-               PyThreadState_Swap(save_tstate);
+               *tstate = PyEval_SaveThread();
        }
        return result;
 }
@@ -513,14 +510,14 @@ on_hook(PyObject *func, PyThreadState *tstate)
 static int
 on_startup_hook(void)
 {
-       return on_hook(startup_hook, startup_hook_tstate);
+       return on_hook(startup_hook, &startup_hook_tstate);
 }
 
 #ifdef HAVE_RL_PRE_INPUT_HOOK
 static int
 on_pre_input_hook(void)
 {
-       return on_hook(pre_input_hook, pre_input_hook_tstate);
+       return on_hook(pre_input_hook, &pre_input_hook_tstate);
 }
 #endif
 
@@ -533,10 +530,8 @@ on_completion(char *text, int state)
        char *result = NULL;
        if (completer != NULL) {
                PyObject *r;
-               PyThreadState *save_tstate;
                /* Note that readline is called with the interpreter
                   lock released! */
-               save_tstate = PyThreadState_Swap(NULL);
                PyEval_RestoreThread(completer_tstate);
                /* Don't use the default filename completion if we
                 * have a custom completion function... */
@@ -559,14 +554,13 @@ on_completion(char *text, int state)
                PyErr_Clear();
                Py_XDECREF(r);
          done:
-               PyEval_SaveThread();
-               PyThreadState_Swap(save_tstate);
+               completer_tstate = PyEval_SaveThread();
        }
        return result;
 }
 
 
-/* a more flexible constructor that saves the "begidx" and "endidx"
+/* A more flexible constructor that saves the "begidx" and "endidx"
  * before calling the normal completer */
 
 char **