From: Keith Nash on
Hello All,

I realise that vwait, like update, is considered harmful -
http://wiki.tcl.tk/1255 states:

"Code that calls [update] doesn't know what any random event handler might
have done to its data while the [update] was in progress."

The same can be said for [vwait], because any event handler can fire during
the wait.

However, the script below is a particularly perverse example, because it is
hard to see why the interpreter's data changes, and I wonder whether anyone
can explain why it fails in the way that it does.

Interpreter $int1 cannot execute anything during the [vwait], because it has
hit its resource limits, and any attempt to do so would call newSecondsLimit
again: that does not occur. Yet the state of $int1 appears to have changed
when execution resumes, and this causes the error.

Keith.

##########

proc newSecondsLimit {iName} {
set elapsed [expr {([clock milliseconds] - $::t0)/1000.0}]
puts "NewSecondsLimit $iName $elapsed"
after 200 set ::ok 1
vwait ::ok

set newLimit [expr {[clock seconds] + $::secsMore}]
interp limit $iName time -seconds $newLimit -command [list
newSecondsLimit $iName]
return
}

set ::t0 [clock milliseconds]
set ::secsMore 2

set int1 [interp create]

newSecondsLimit $int1

interp eval $int1 {
for {set nloop 0} {$nloop < 10000000} {incr nloop} {
set result [expr {cos($nloop) * sin($nloop)}]
}
}

##########
$ tclsh8.5 worksheets/testInterpLimits.tcl
NewSecondsLimit interp0 0.018
NewSecondsLimit interp0 1.932
can't use empty string as operand of "*"
while executing
"expr {cos($nloop) * sin($nloop)}"
invoked from within
"interp eval $int1 {
for {set nloop 0} {$nloop < 10000000} {incr nloop} {
set result [expr {cos($nloop) * sin($nloop)}]
}
}"
(file "worksheets/testInterpLimits.tcl" line 20)