Ephaeton at gmx dot net a person who's been away from Tcl for too long...Wiki stuff:
- Errx
- AtExit Handlers
- Some socket examples in Einfach Tcl
- pathentry
- block-select
- sizepanel
- multiple value set
- likes Toasting procs
- Simpletracer, with help from RS & MS
- onInit
- sizepanel
- Now a fossil
contributor
This will be moved to another page once I find a good name for it.
msw suchenwi: I managed to shape up the script which is giving me vwait problems* suchenwi can't look - busy with paywork .}msw have a look at wiki://MSW, there's code and output from a run showing what I'm getting mad about :)msw ...once you have time that is.msw with tclsh running you just don't get the code to fuck up ... with tk it's piece of cakemsw Suppose you'd need to tokenize each run with own target variable etc. so it doesn't try to be multiply in the same procmsw you others are well invited to have a look and tell me what I did wrong, too :)arjen I am sorry: ight now I have my own things to get mad about ;)msw oh, there's no pressure here, I've found a(n uberugly) workaround for my problemmsw Just for the usual cursing/"what's NOT possible"/things to avoid - notebook..suchenwi msw: maybe you should just disable thew button when clicked, and re-enable it when bexec is done...msw suchenwi: that's what I'm doing (a bit different, using a grab on a label saying have patience)suchenwi As a single global variable bexec_result holds the results, two "parallel" bexecs are only guaranteed to make trouble.msw suchenwi: but it's definitely a (n ugly) workaroundmsw suchenwi: that's why I'm lockingmsw suchenwi: and the locking is exposing the actual problem..msw suchenwi: after the command is done, and the vwait returns, the proc is twice at the same position - before the acquire-lock partsuchenwi Maybe just to use ::bexec_runs to signal whether bexec is ain progress: if $::bexec_runs returnmsw suchenwi: version #1 was doing that kind of ...suchenwi Initializi to 0, set to 1 in the first bexec call, reset to 0 after the vwait.msw if {$bexec_runs} then {vwait bexec_runs} ..msw I should maybe add after idle to the vwaitsuchenwi You can't vwait in two places for the same variable.msw that's the dilemma :)suchenwi But you can check its value and return early.msw so I need to tokenize if I want to have the stuff be able to run in parallelmsw like vwait [token-var], append result to [token-var] etc.suchenwi Yes - sort of like the http package does it.msw my manpage doesn't mention that you cannot vwait on the same var twice btw.msw (8.3)suchenwi Hm.. maybe you can, but it seems conceptually unclear to me - which vwait fires first, etc.* suchenwi meetingmsw basically it should be fifomsw but well, some core-savvy wants to comment ? :)msw 8.4 vwait man doesn't mention it eithernem vwaits stack - I would assume that it would be a filo - last vwait would fire before firstmsw well, event _queue_, would've supposed an append each time, but that doesn't matter ...msw I wouldn't care about the order ...msw if the events would be ok, but it seems broken (check the output on wiki.tcl.tk/msw, bottom of page)* dkf backsuchenwi Donal: can two vwaits wait for the same variable?dkf Yessuchenwi And in what order are they released?dkf Strict stack ordersuchenwi But with "parallel" events, is there a stack order?dkf There's always a stack orderdkf 'Cos we're all implemented in C...suchenwi Ah, right :)dkf The problem with msw's code is that it is trying to use stack-based operation with event handlingmsw I've the feeling all I need is a closure and it'll work :pdkf This is the sort of thing that http://wiki.tcl.tk/1255

MSW (broken) version
set ::bexec_runs 0 set ::bexec_result "" set ::bnum 0 proc bexec what { global bexec_runs bexec_result bnum incr bnum set fname [file join $::env(HOME) tmp cmd_run_lock_$::env(USER)_[pid]] while {[catch {set fp [open $fname {WRONLY CREAT EXCL}]}]} { puts stderr "($bnum) Lock busy, will retry." after 200 "set ::retry 0" vwait ::retry } puts stderr "($bnum)Got the Lock for \"[string range $what 0 99]...\"." # reset results set ::bexec_result "" puts stderr "Executing $what..." set bexec_runs 1 set f [open |$what] #fconfigure $f -translation none fileevent $f readable [list bexec_read $f] vwait bexec_runs file delete -force [file join $::env(HOME) tmp cmd_run_lock_$::env(USER)_[pid]] puts stderr "($bnum)Released the Lock for \"[string range $what 0 99]...\"." return $bexec_result } proc bexec_read {f} { set data [read $f] if [eof $f] { close $f set ::bexec_runs 0 } append ::bexec_result $data } # demo1: set tfile [open tst.sh w] puts $tfile {#!/bin/sh echo "output1" sleep 3 echo "output2"} close $tfile puts [bexec "sh tst.sh"] puts [bexec "sh tst.sh"] ;# <-- this one will wait. # demo2: pack [button .b -text "run" -command {puts [bexec "sh tst.sh"]}] -expand 1 -fill bothOutput:
(1)Got the Lock for "sh tst.sh...". (1)Executing sh tst.sh... (1)Released the Lock for "sh tst.sh...". output1 output2 (2)Got the Lock for "sh tst.sh...". (2)Executing sh tst.sh... (2)Released the Lock for "sh tst.sh...". output1 output2 (3)Got the Lock for "sh tst.sh...". (3)Executing sh tst.sh... (3)Released the Lock for "sh tst.sh...". output1 output2 (4)Got the Lock for "sh tst.sh...". (4)Executing sh tst.sh... (5) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. (6) Lock busy, will retry. # ad infitum... lockfile never goes away.DKF VERSION
set ::bexec_runs 0 set ::bexec_result "" set ::bnum 0 proc bexec {what handler {uid -1}} { global bexec_accum bnum if {$uid == -1} { set uid [incr bnum] } set fname [file join ~ tmp cmd_run_lock_[pid]] if {[catch {open $fname {WRONLY CREAT EXCL}} fp]} { puts stderr "($uid) Lock busy, will retry." after 200 [list bexec $what $handler $uid] return } set f [open |$what] set bexec_accum($uid) {} fileevent $f readable [list bexec_read $f $uid $fname $handler] } proc bexec_read {f uid fname handler} { global bexec_accum if {[gets $f line] == -1} { close $f file delete -force $fname uplevel #0 $handler [list $bexec_accum($uid)] unset bexec_accum($uid) return } append bexec_accum($uid) $line \n } # demo1: set tfile [open tst.sh w] puts $tfile {#!/bin/sh echo "output1" sleep 3 echo "output2"} close $tfile bexec "sh tst.sh" puts bexec "sh tst.sh" puts ;# <-- this one will wait. # demo2: pack [button .b -text "run" -command {bexec "sh tst.sh" puts}] -expand 1 -fill bothOutput:
(2) Lock busy, will retry. (2) Lock busy, will retry. (2) Lock busy, will retry. (2) Lock busy, will retry. (2) Lock busy, will retry. (2) Lock busy, will retry. (2) Lock busy, will retry. (2) Lock busy, will retry. (2) Lock busy, will retry. (2) Lock busy, will retry. (2) Lock busy, will retry. (2) Lock busy, will retry. (2) Lock busy, will retry. (2) Lock busy, will retry. (2) Lock busy, will retry. output1 output2 output1 output2 (4) Lock busy, will retry. (4) Lock busy, will retry. (4) Lock busy, will retry. (4) Lock busy, will retry. (4) Lock busy, will retry. (4) Lock busy, will retry. (4) Lock busy, will retry. (4) Lock busy, will retry. (4) Lock busy, will retry. (4) Lock busy, will retry. (4) Lock busy, will retry. (4) Lock busy, will retry. (4) Lock busy, will retry. (4) Lock busy, will retry. output1 output2 (5) Lock busy, will retry. (5) Lock busy, will retry. (5) Lock busy, will retry. output1 output2 output1 output2