Skip to content
7 changes: 3 additions & 4 deletions Modules/_tkinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -3356,7 +3356,9 @@ static int stdin_ready = 0;
static void
MyFileProc(void *clientData, int mask)
{
int *tfile = clientData;
stdin_ready = 1;
Tcl_DeleteFileHandler(*tfile);
Comment on lines +3336 to +3338
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int *tfile = clientData;
stdin_ready = 1;
Tcl_DeleteFileHandler(*tfile);
int tfile = (int)(Py_intptr_t)clientData;
stdin_ready = 1;
Tcl_DeleteFileHandler(tfile);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this. This is an important point.

The while-loop in EventHook can only be exited if either stdin_ready is 1 or errorInCmd is 1.
stdin_ready is set to 1 only in MyFileProc, which also calls Tcl_DeleteFileHandler. As the file handler is deleted, there won't be a dangling pointer.

But I was missing a call to Tcl_DeleteFileHandler for the case in which errorInCmd is 1, and MyFileProc was never called. Then then file handler will stay alive and will keep a dangling pointer to tfile after EventHook exits.

I fixed this by adding a call to Tcl_DeleteFileHandler to the if (errorInCmd) {... to ensure that the file handler is deleted before EventHook exits, and no pointer to tfile remains,

}
#endif

Expand All @@ -3373,7 +3375,7 @@ EventHook(void)
errorInCmd = 0;
#ifndef MS_WINDOWS
tfile = fileno(stdin);
Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, &tfile);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, &tfile);
Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, (void *)(Py_intptr_t)tfile);

#endif
while (!errorInCmd && !stdin_ready) {
int result;
Expand All @@ -3398,9 +3400,6 @@ EventHook(void)
if (result < 0)
break;
}
#ifndef MS_WINDOWS
Tcl_DeleteFileHandler(tfile);
#endif
if (errorInCmd) {
errorInCmd = 0;
PyErr_SetRaisedException(excInCmd);
Expand Down
Loading