Name: freeMem
Description: Spawn a Tcl interpreter using a Tcl pipe, evaluate some code, and get all the memory back.
Parameters: code - arbitrary tcl code
Usage:
set mid [ freeMem { puts foo! } ]
vwait $mid ;## since we are waiting on the KEY.
(when you are through do "unset $mid")
or
set mid [ freeMem "return foo!" ]
vwait $mid
set retval [ eval [ set $mid ] ]
unset $mid
Comments: This is slow due to the initialization overhead, but is convenient if you have a long running process that occasionally needs to do something that is memory intensive and would otherwise cause all the memory on the machine to wind up on the heap of the current process.
If the code being evaluated here needs to do anything in the caller's scope the value returned by freeMem should be eval'd by the caller. Otherwise it is just
set to dereference it.
proc freeMem { code } {
set uniqueid [ clock clicks -milliseconds ]
set ::$uniqueid [ list ]
;## internal callback
proc __freeMem__ { fid uniqueid } {
if { [ catch {
set ::$uniqueid [ read $fid ]
close $fid
} err ] } {
return -code error $err
}
}
;## handle return values (including return -codes)
regsub -all {return .+} $code "puts {&}" code
if { [ catch {
set fid [ open |tclsh w+ ]
fconfigure $fid -blocking off
fconfigure $fid -buffering line
puts $fid $code
fileevent $fid readable "__freeMem__ $fid $uniqueid"
} err ] } {
catch { close $fid }
return -code error $err
}
return ::$uniqueid
}
--
Phil Ehrens