Dangerous update command



Dear all,

In my Coccinella app I have code that transfer files back and forth
and I have until now been using 'update' or 'update idletasks' to keep
the GUI responsive, but was getting errors that the recursion limit
was reached. This was nothing but the "Update considered harmful"
http://wiki.tcl.tk/1255 problem, and I now understand how stupid it
is. I just want to have some feedback how to use the trick 'after idle
[list after 0 [list ...]]' in a situation with fileevents.

My code looked roughly like:

fileevent $sock readable [list Readable $sock]

proc Readable {sock} {
if {[catch {eof $sock} iseof] || $iseof} {
...
} else {
set data [read $sock]

# Write to file etc.
...
update_progress_window $data

# WRONG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if {[string equal $::tcl_platform(platform) "windows"]} {
update
} else {
update idletasks
}
}

Rewritten it looks like:

proc Readable {sock} {

fileevent $sock readable {}
if {[catch {eof $sock} iseof] || $iseof} {
...
} else {
set data [read $sock]

# Write to file etc.
...
update_progress_window $data
after idle [list after 0 [list SetReadable $sock]]
}
}

proc SetReadable {sock} {

# We could have been closed since this event comes async.
if {[lsearch [file channels] $sock] >= 0} {
fileevent $sock readable [list Readable $sock]
}
}

In short, I switch off fileevent for each callback, and then
reschedule it to be switched on again when the UI events finished.
Some testing shows that this makes a fast and responsive UI, but is
this the right way? Any pitfalls? Then similar code for 'fileevent
writable'.

Personally I'd like to see a updateEventObjCmd from http://wiki.tcl.tk/1252

/Mats
.



Relevant Pages

  • Network client using non-blocking I/O
    ... I/O on all channels, including stdin. ... the socket output fileevent. ... fileevent $sock writable ... set mainevent putsfailure ...
    (comp.lang.tcl)
  • Re: work with socket
    ... Tcl seems untrue to the fileevent ... set exception [catch {gets $sock line} data] ... puts "* EOF" ... set mainevent sockclosed ...
    (comp.lang.tcl)
  • Re: Who maintains Tclhttpd?
    ... the new TCL 8.5 [chan pending] command, ... set data [gets $sock] ...
    (comp.lang.tcl)