Skip to content

Commit c5f5d55

Browse files
committed
Fix race conditions for non-threaded Tcl when passing data to/from it
1 parent ad65d09 commit c5f5d55

File tree

1 file changed

+43
-30
lines changed

1 file changed

+43
-30
lines changed

Modules/_tkinter.c

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ static PyThreadState *tcl_tstate = NULL;
216216
#define ENTER_OVERLAP \
217217
Py_END_ALLOW_THREADS
218218

219+
#define LEAVE_OVERLAP \
220+
Py_BEGIN_ALLOW_THREADS
221+
219222
#define LEAVE_OVERLAP_TCL \
220223
tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
221224

@@ -239,6 +242,7 @@ static PyThreadState *tcl_tstate = NULL;
239242
#define ENTER_TCL
240243
#define LEAVE_TCL
241244
#define ENTER_OVERLAP
245+
#define LEAVE_OVERLAP
242246
#define LEAVE_OVERLAP_TCL
243247
#define ENTER_PYTHON
244248
#define LEAVE_PYTHON
@@ -1644,24 +1648,28 @@ Tkapp_Call(PyObject *selfptr, PyObject *args)
16441648
#endif
16451649
{
16461650

1651+
ENTER_TCL
1652+
ENTER_OVERLAP
1653+
16471654
objv = Tkapp_CallArgs(args, objStore, &objc);
1648-
if (!objv)
1649-
return NULL;
16501655

1651-
ENTER_TCL
1656+
if (objv) {
16521657

1653-
i = Tcl_EvalObjv(self->interp, objc, objv, flags);
1658+
LEAVE_OVERLAP
16541659

1655-
ENTER_OVERLAP
1660+
i = Tcl_EvalObjv(self->interp, objc, objv, flags);
16561661

1657-
if (i == TCL_ERROR)
1658-
Tkinter_Error(selfptr);
1659-
else
1660-
res = Tkapp_CallResult(self);
1662+
ENTER_OVERLAP
16611663

1662-
LEAVE_OVERLAP_TCL
1664+
if (i == TCL_ERROR)
1665+
Tkinter_Error(selfptr);
1666+
else
1667+
res = Tkapp_CallResult(self);
16631668

1664-
Tkapp_CallDeallocArgs(objv, objStore, objc);
1669+
Tkapp_CallDeallocArgs(objv, objStore, objc);
1670+
1671+
}
1672+
LEAVE_OVERLAP_TCL
16651673
}
16661674
return res;
16671675
}
@@ -1952,19 +1960,20 @@ SetVar(PyObject *self, PyObject *args, int flags)
19521960
if (!PyArg_ParseTuple(args, "O&O:setvar",
19531961
varname_converter, &name1, &newValue))
19541962
return NULL;
1955-
/* XXX Acquire tcl lock??? */
1956-
newval = AsObj(newValue);
1957-
if (newval == NULL)
1958-
return NULL;
19591963
ENTER_TCL
1960-
ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
1961-
newval, flags);
19621964
ENTER_OVERLAP
1963-
if (!ok)
1964-
Tkinter_Error(self);
1965-
else {
1966-
res = Py_None;
1967-
Py_INCREF(res);
1965+
newval = AsObj(newValue);
1966+
if (newval) {
1967+
LEAVE_OVERLAP
1968+
ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
1969+
newval, flags);
1970+
ENTER_OVERLAP
1971+
if (!ok)
1972+
Tkinter_Error(self);
1973+
else {
1974+
res = Py_None;
1975+
Py_INCREF(res);
1976+
}
19681977
}
19691978
LEAVE_OVERLAP_TCL
19701979
break;
@@ -1974,16 +1983,20 @@ SetVar(PyObject *self, PyObject *args, int flags)
19741983
return NULL;
19751984
CHECK_STRING_LENGTH(name1);
19761985
CHECK_STRING_LENGTH(name2);
1977-
/* XXX must hold tcl lock already??? */
1978-
newval = AsObj(newValue);
19791986
ENTER_TCL
1980-
ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
19811987
ENTER_OVERLAP
1982-
if (!ok)
1983-
Tkinter_Error(self);
1984-
else {
1985-
res = Py_None;
1986-
Py_INCREF(res);
1988+
newval = AsObj(newValue);
1989+
if (newval) {
1990+
LEAVE_OVERLAP
1991+
ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2,
1992+
newval, flags);
1993+
ENTER_OVERLAP
1994+
if (!ok)
1995+
Tkinter_Error(self);
1996+
else {
1997+
res = Py_None;
1998+
Py_INCREF(res);
1999+
}
19872000
}
19882001
LEAVE_OVERLAP_TCL
19892002
break;

0 commit comments

Comments
 (0)