[Python-checkins] r45834 - in python/branches/release24-maint: Misc/NEWS Modules/_tkinter.c
martin.v.loewis
python-checkins at python.org
Mon May 1 08:29:07 CEST 2006
Author: martin.v.loewis
Date: Mon May 1 08:29:06 2006
New Revision: 45834
Modified:
python/branches/release24-maint/Misc/NEWS
python/branches/release24-maint/Modules/_tkinter.c
Log:
Work around deadlock risk.
Modified: python/branches/release24-maint/Misc/NEWS
==============================================================================
--- python/branches/release24-maint/Misc/NEWS (original)
+++ python/branches/release24-maint/Misc/NEWS Mon May 1 08:29:06 2006
@@ -15,6 +15,9 @@
Extension Modules
-----------------
+- Calling Tk_Init twice is refused if the first call failed as that
+ may deadlock.
+
- Patch #1191065: Fix preprocessor problems on systems where recvfrom
is a macro.
Modified: python/branches/release24-maint/Modules/_tkinter.c
==============================================================================
--- python/branches/release24-maint/Modules/_tkinter.c (original)
+++ python/branches/release24-maint/Modules/_tkinter.c Mon May 1 08:29:06 2006
@@ -2609,20 +2609,32 @@
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) {
- 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);
}
@@ -2633,6 +2645,7 @@
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;
}
}
More information about the Python-checkins
mailing list