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 }