- priority: 5 --> 6
- assigned_to: nobody --> ghowlett
Hi,
I realized that blt::watch triggers PostCmdProc only for procedures/commands that do not call another procedure/command.
Cheers
Ersin Beyret
1) Script to replicate the problem, example_post.tcl:
proc test_proc {} {
set myvar myvalue
test_proc2
test_proc3
}
proc test_proc2 {} {
}
proc test_proc3 {} {
set myvar3 myvalue3
}
proc preCmd { level command argv } {
puts "PRE :> [string repeat - $level] $command | $argv <: PRE"
}
proc postCmd { level command argv retcode results } {
puts "POST:> [string repeat - $level] $command | $argv | $retcode | $results :<POST"
}
blt::watch create trace -postcmd postCmd -precmd preCmd
test_proc
2) Run it as bltsh example_post.tcl, and see this output:
PRE :> - test_proc
| test_proc <: PRE
PRE :> -- set myvar myvalue | set myvar myvalue <: PRE
POST:> -- set myvar myvalue | set myvar myvalue | OK | myvalue :<POST
PRE :> -- test_proc2 | test_proc2 <: PRE
POST:> -- test_proc2 | test_proc2 | OK | :<POST
PRE :> -- test_proc3 | test_proc3 <: PRE
PRE :> --- set myvar3 myvalue3 | set myvar3 myvalue3 <: PRE
POST:> --- set myvar3 myvalue3 | set myvar3 myvalue3 | OK | myvalue3 :<POST
3) Observations
Notice that command 'set' and procedure 'test_proc2' triggered POST, but 'test_proc3' and 'test_proc' did NOT.
4) Theory
I think this is happening because 'PreCmdProc' calls Tcl_AsyncMark:
/* Set the trigger for the "post" command procedure */
if (watchPtr->postCmd != NULL) {
Tcl_AsyncMark(watchPtr->asyncHandle);
}
So if proc A calls B, 'PreCmdProc' is invoked for A, then while A is being executed, 'PreCmdProc' is called for B. The last Tcl_AsyncMark call seems to override the previous one. So when B is done, it triggers POST. Then A is done but that does not trigger POST.
This implies that practically no procedure will trigger POST since they will have at least one call in them.
Internal commands should not have this problem (unless they internally call Tcl_Eval which would trigger a 'PreCmdProc').
I was planning to start a clock at 'PRE' and stop it at 'POST' so that i can measure the runtime of procedures and commands. It looks like i won't be able to do that for procedures.