Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Properly clean up, when a (Tcl 8.6) thread is canceled. (Backported from Tk 8.6) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | core-8-5-branch |
Files: | files | file ages | folders |
SHA1: |
9f6ef8e5dae68c6db252184beea6f446 |
User & Date: | jan.nijtmans 2013-03-27 14:06:11 |
Original Comment: | Properly clean up, when a (Tcl 8.6) thread is canceled. |
Context
2013-03-28
| ||
07:36 | Easier solution, with proper protection and configure warnings. check-in: 6af7f840 user: jan.nijtmans tags: core-8-5-branch | |
2013-03-27
| ||
14:11 | merge-mark check-in: 16ea6a46 user: jan.nijtmans tags: trunk | |
14:06 | Properly clean up, when a (Tcl 8.6) thread is canceled. (Backported from Tk 8.6) check-in: 9f6ef8e5 user: jan.nijtmans tags: core-8-5-branch | |
13:07 | Make compiling/running Tk8.5 against 8.6 headers work on Windows as well. In dynamic builds, Tcl_FindExecutable should always be taken from the stub table, even though the 8.6 headers tell otherwise. That's why in Tcl 8.6, the Tcl_FindExecutable() call moved from Tk_MainEx to the Tk_Main() macro. check-in: f7c61c80 user: jan.nijtmans tags: core-8-5-branch | |
Changes
Changes to generic/tkCmds.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #include "tkWinInt.h" #elif defined(MAC_OSX_TK) #include "tkMacOSXInt.h" #else #include "tkUnixInt.h" #endif /* * Forward declarations for functions defined later in this file: */ static TkWindow * GetTopHierarchy(Tk_Window tkwin); static char * WaitVariableProc(ClientData clientData, Tcl_Interp *interp, const char *name1, | > > > > > > > > > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #include "tkWinInt.h" #elif defined(MAC_OSX_TK) #include "tkMacOSXInt.h" #else #include "tkUnixInt.h" #endif #if (TCL_MAJOR_VERSION==8) && (TCL_MINOR_VERSION<6) # if defined(STATIC_BUILD) # define Tcl_Canceled(interp, flags) (TCL_OK) # else # define Tcl_Canceled \ (tclStubsPtr->tclCanceled) /* 581 */ # endif #endif /* * Forward declarations for functions defined later in this file: */ static TkWindow * GetTopHierarchy(Tk_Window tkwin); static char * WaitVariableProc(ClientData clientData, Tcl_Interp *interp, const char *name1, |
︙ | ︙ | |||
909 910 911 912 913 914 915 916 917 918 919 920 921 922 | ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_Window tkwin = (Tk_Window) clientData; int done, index; static const char *optionStrings[] = { "variable", "visibility", "window", NULL }; enum options { TKWAIT_VARIABLE, TKWAIT_VISIBILITY, TKWAIT_WINDOW }; | > | 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 | ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_Window tkwin = (Tk_Window) clientData; int done, index; int code = TCL_OK; static const char *optionStrings[] = { "variable", "visibility", "window", NULL }; enum options { TKWAIT_VARIABLE, TKWAIT_VISIBILITY, TKWAIT_WINDOW }; |
︙ | ︙ | |||
935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 | if (Tcl_TraceVar(interp, Tcl_GetString(objv[2]), TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, WaitVariableProc, (ClientData) &done) != TCL_OK) { return TCL_ERROR; } done = 0; while (!done) { Tcl_DoOneEvent(0); } Tcl_UntraceVar(interp, Tcl_GetString(objv[2]), TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, WaitVariableProc, (ClientData) &done); break; case TKWAIT_VISIBILITY: { Tk_Window window; window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin); if (window == NULL) { return TCL_ERROR; } Tk_CreateEventHandler(window, VisibilityChangeMask|StructureNotifyMask, WaitVisibilityProc, (ClientData) &done); done = 0; while (!done) { Tcl_DoOneEvent(0); } | > > > > > > > > | | 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 | if (Tcl_TraceVar(interp, Tcl_GetString(objv[2]), TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, WaitVariableProc, (ClientData) &done) != TCL_OK) { return TCL_ERROR; } done = 0; while (!done) { if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) { code = TCL_ERROR; break; } Tcl_DoOneEvent(0); } Tcl_UntraceVar(interp, Tcl_GetString(objv[2]), TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, WaitVariableProc, (ClientData) &done); break; case TKWAIT_VISIBILITY: { Tk_Window window; window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin); if (window == NULL) { return TCL_ERROR; } Tk_CreateEventHandler(window, VisibilityChangeMask|StructureNotifyMask, WaitVisibilityProc, (ClientData) &done); done = 0; while (!done) { if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) { code = TCL_ERROR; break; } Tcl_DoOneEvent(0); } if ((done != 0) && (done != 1)) { /* * Note that we do not delete the event handler because it was * deleted automatically when the window was destroyed. */ Tcl_ResetResult(interp); Tcl_AppendResult(interp, "window \"", Tcl_GetString(objv[2]), |
︙ | ︙ | |||
984 985 986 987 988 989 990 991 992 993 994 | if (window == NULL) { return TCL_ERROR; } Tk_CreateEventHandler(window, StructureNotifyMask, WaitWindowProc, (ClientData) &done); done = 0; while (!done) { Tcl_DoOneEvent(0); } /* | > > > > | | > > > > > | > > > | | 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 | if (window == NULL) { return TCL_ERROR; } Tk_CreateEventHandler(window, StructureNotifyMask, WaitWindowProc, (ClientData) &done); done = 0; while (!done) { if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) { code = TCL_ERROR; break; } Tcl_DoOneEvent(0); } /* * Note: normally there's no need to delete the event handler. It was * deleted automatically when the window was destroyed; however, if * the wait operation was canceled, we need to delete it. */ if (done == 0) { Tk_DeleteEventHandler(window, StructureNotifyMask, WaitWindowProc, &done); } break; } } /* * Clear out the interpreter's result, since it may have been set by event * handlers. This is skipped if an error occurred above, such as the wait * operation being canceled. */ if (code == TCL_OK) Tcl_ResetResult(interp); return code; } /* ARGSUSED */ static char * WaitVariableProc( ClientData clientData, /* Pointer to integer to set to 1. */ Tcl_Interp *interp, /* Interpreter containing variable. */ |
︙ | ︙ | |||
1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 | Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { static const char *updateOptions[] = {"idletasks", NULL}; int flags, index; TkDisplay *dispPtr; if (objc == 1) { flags = TCL_DONT_WAIT; } else if (objc == 2) { if (Tcl_GetIndexFromObj(interp, objv[1], updateOptions, "option", 0, &index) != TCL_OK) { return TCL_ERROR; | > | 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 | Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { static const char *updateOptions[] = {"idletasks", NULL}; int flags, index; TkDisplay *dispPtr; int code = TCL_OK; if (objc == 1) { flags = TCL_DONT_WAIT; } else if (objc == 2) { if (Tcl_GetIndexFromObj(interp, objv[1], updateOptions, "option", 0, &index) != TCL_OK) { return TCL_ERROR; |
︙ | ︙ | |||
1100 1101 1102 1103 1104 1105 1106 | * possible that the entire application could be destroyed by an event * handler that occurs during the update. Thus, don't use any information * from tkwin after calling Tcl_DoOneEvent. */ while (1) { while (Tcl_DoOneEvent(flags) != 0) { | > > > > > | > > > | > > > > > > > > > > > > > > > | > > > | | 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 | * possible that the entire application could be destroyed by an event * handler that occurs during the update. Thus, don't use any information * from tkwin after calling Tcl_DoOneEvent. */ while (1) { while (Tcl_DoOneEvent(flags) != 0) { if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) { code = TCL_ERROR; break; } } /* * If event processing was canceled proceed no further. */ if (code == TCL_ERROR) break; for (dispPtr = TkGetDisplayList(); dispPtr != NULL; dispPtr = dispPtr->nextPtr) { XSync(dispPtr->display, False); } /* * Check again if event processing has been canceled because the inner * loop (above) may not have checked (i.e. no events were processed and * the loop body was skipped). */ if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) { code = TCL_ERROR; break; } if (Tcl_DoOneEvent(flags) == 0) { break; } } /* * Must clear the interpreter's result because event handlers could have * executed commands. This is skipped if an error occurred above, such as * the wait operation being canceled. */ if (code == TCL_OK) Tcl_ResetResult(interp); return code; } /* *---------------------------------------------------------------------- * * Tk_WinfoObjCmd -- * |
︙ | ︙ |