summaryrefslogtreecommitdiffstats
path: root/generic/tclInterp.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2004-05-20 13:04:10 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2004-05-20 13:04:10 (GMT)
commitdd73a7d278b7721922e373f9310c04f301fdbcac (patch)
tree32f0081a587e4d9bb0b35b8d472cb716b9364393 /generic/tclInterp.c
parentea59419c25449100febc3fb0ed1f7fee1b9c7e8a (diff)
downloadtcl-dd73a7d278b7721922e373f9310c04f301fdbcac.zip
tcl-dd73a7d278b7721922e373f9310c04f301fdbcac.tar.gz
tcl-dd73a7d278b7721922e373f9310c04f301fdbcac.tar.bz2
Delete limit callbacks properly when the interpreters involved are deleted.
Diffstat (limited to 'generic/tclInterp.c')
-rw-r--r--generic/tclInterp.c76
1 files changed, 75 insertions, 1 deletions
diff --git a/generic/tclInterp.c b/generic/tclInterp.c
index 35efdd3..0354f5e 100644
--- a/generic/tclInterp.c
+++ b/generic/tclInterp.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclInterp.c,v 1.31 2004/05/19 21:56:37 dkf Exp $
+ * RCS: @(#) $Id: tclInterp.c,v 1.32 2004/05/20 13:04:11 dkf Exp $
*/
#include "tclInt.h"
@@ -2849,6 +2849,80 @@ Tcl_LimitRemoveHandler(interp, type, handlerProc, clientData)
}
}
+void
+TclLimitRemoveAllHandlers(interp)
+ Tcl_Interp *interp;
+{
+ Interp *iPtr = (Interp *) interp;
+ LimitHandler *handlerPtr, *nextHandlerPtr;
+
+ /*
+ * Delete all command-limit handlers.
+ */
+
+ for (handlerPtr=iPtr->limit.cmdHandlers, iPtr->limit.cmdHandlers=NULL;
+ handlerPtr!=NULL; handlerPtr=nextHandlerPtr) {
+ nextHandlerPtr = handlerPtr->nextPtr;
+
+ /*
+ * Do not delete here if it has already been marked for deletion.
+ */
+
+ if (handlerPtr->flags & LIMIT_HANDLER_DELETED) {
+ continue;
+ }
+ handlerPtr->flags |= LIMIT_HANDLER_DELETED;
+ handlerPtr->prevPtr = NULL;
+ handlerPtr->nextPtr = NULL;
+
+ /*
+ * If nothing is currently executing the handler, delete its
+ * client data and the overall handler structure now.
+ * Otherwise it will all go away when the handler returns.
+ */
+
+ if (!(handlerPtr->flags & LIMIT_HANDLER_ACTIVE)) {
+ if (handlerPtr->deleteProc != NULL) {
+ (handlerPtr->deleteProc)(handlerPtr->clientData);
+ }
+ ckfree((char *) handlerPtr);
+ }
+ }
+
+ /*
+ * Delete all time-limit handlers.
+ */
+
+ for (handlerPtr=iPtr->limit.timeHandlers, iPtr->limit.timeHandlers=NULL;
+ handlerPtr!=NULL; handlerPtr=nextHandlerPtr) {
+ nextHandlerPtr = handlerPtr->nextPtr;
+
+ /*
+ * Do not delete here if it has already been marked for deletion.
+ */
+
+ if (handlerPtr->flags & LIMIT_HANDLER_DELETED) {
+ continue;
+ }
+ handlerPtr->flags |= LIMIT_HANDLER_DELETED;
+ handlerPtr->prevPtr = NULL;
+ handlerPtr->nextPtr = NULL;
+
+ /*
+ * If nothing is currently executing the handler, delete its
+ * client data and the overall handler structure now.
+ * Otherwise it will all go away when the handler returns.
+ */
+
+ if (!(handlerPtr->flags & LIMIT_HANDLER_ACTIVE)) {
+ if (handlerPtr->deleteProc != NULL) {
+ (handlerPtr->deleteProc)(handlerPtr->clientData);
+ }
+ ckfree((char *) handlerPtr);
+ }
+ }
+}
+
int
Tcl_LimitTypeEnabled(interp, type)
Tcl_Interp *interp;