diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2006-05-01 06:28:01 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2006-05-01 06:28:01 (GMT) |
commit | 8672519ac0617dcc0ec95ead7ee28ec6040f5741 (patch) | |
tree | 989c09952d82553038fc46efd4ac4f0985eae07f /Modules/_tkinter.c | |
parent | 6550f032163e2e9c8abf9e922322d7d4b97ea2cd (diff) | |
download | cpython-8672519ac0617dcc0ec95ead7ee28ec6040f5741.zip cpython-8672519ac0617dcc0ec95ead7ee28ec6040f5741.tar.gz cpython-8672519ac0617dcc0ec95ead7ee28ec6040f5741.tar.bz2 |
Work around deadlock risk. Will backport.
Diffstat (limited to 'Modules/_tkinter.c')
-rw-r--r-- | Modules/_tkinter.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index ebaf799..bbcbfa1 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -2619,21 +2619,32 @@ Tkapp_InterpAddr(PyObject *self, PyObject *args) static PyObject * Tkapp_TkInit(PyObject *self, PyObject *args) { + static int has_failed; Tcl_Interp *interp = Tkapp_Interp(self); Tk_Window main_window; const char * _tk_exists = NULL; - PyObject *res = NULL; int err; main_window = Tk_MainWindow(interp); + /* In all current versions of Tk (including 8.4.13), Tk_Init + deadlocks on the second call when the first call failed. + To avoid the deadlock, we just refuse the second call through + a static variable. */ + if (has_failed) { + PyErr_SetString(Tkinter_TclError, + "Calling Tk_Init again after a previous call failed might deadlock"); + return NULL; + } + /* We want to guard against calling Tk_Init() multiple times */ CHECK_TCL_APPARTMENT; ENTER_TCL err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version"); ENTER_OVERLAP if (err == TCL_ERROR) { - /* XXX: shouldn't we do something with res? */ - res = Tkinter_Error(self); + /* This sets an exception, but we cannot return right + away because we need to exit the overlap first. */ + Tkinter_Error(self); } else { _tk_exists = Tkapp_Result(self); } @@ -2644,6 +2655,7 @@ Tkapp_TkInit(PyObject *self, PyObject *args) if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) { if (Tk_Init(interp) == TCL_ERROR) { PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self))); + has_failed = 1; return NULL; } } |