# -*- tcl -*- # Maintenance Instruction: leave the 999999.xxx.x as is and use 'pmix make' or src/make.tcl to update from -buildversion.txt # # Please consider using a BSD or MIT style license for greatest compatibility with the Tcl ecosystem. # Code using preferred Tcl licenses can be eligible for inclusion in Tcllib, Tklib and the punk package repository. # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ # (C) 2023 # # @@ Meta Begin # Application zzzload 999999.0a1.0 # Meta platform tcl # Meta license BSD # @@ Meta End # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ ## Requirements ##e.g package require frobz package require Thread # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ namespace eval zzzload { variable loader_tid "" ;#thread id proc stacktrace {} { set stack "Stack trace:\n" for {set i 1} {$i < [info level]} {incr i} { set lvl [info level -$i] set pname [lindex $lvl 0] append stack [string repeat " " $i]$pname if {![catch {info args $pname} pargs]} { foreach value [lrange $lvl 1 end] arg $pargs { if {$value eq ""} { if {$arg != 0} { info default $pname $arg value } } append stack " $arg='$value'" } } else { append stack " !unknown vars for $pname" } append stack \n } return $stack } proc pkg_require {pkgname args} { variable loader_tid if {[set ver [package provide twapi]] ne ""} { #skip the whole shebazzle if it's already loaded return $ver } if {$loader_tid eq ""} { set loader_tid [thread::create -joinable -preserved] } if {![tsv::exists zzzload_pkg $pkgname]} { #puts stderr "zzzload pkg_require $pkgname" #puts [stacktrace] tsv::set zzzload_pkg $pkgname "loading" tsv::set zzzload_pkg_mutex $pkgname [thread::mutex create] set cond [thread::cond create] tsv::set zzzload_pkg_cond $pkgname $cond thread::send -async $loader_tid [string map [list $pkgname $cond] { if {![catch {package require } returnver]} { tsv::set zzzload_pkg $returnver } else { tsv::set zzzload_pkg "failed" } thread::cond notify }] return "loading" } else { return [tsv::get zzzload_pkg $pkgname] } } proc pkg_wait {pkgname} { if {[set ver [package provide twapi]] ne ""} { return $ver } set pkgstate [tsv::get zzzload_pkg $pkgname] if {$pkgstate eq "loading"} { set mutex [tsv::get zzzload_pkg_mutex $pkgname] thread::mutex lock $mutex set cond [tsv::get zzzload_pkg_cond $pkgname] while {[tsv::get zzzload_pkg $pkgname] eq "loading"} { thread::cond wait $cond $mutex 3000 } set result [tsv::get zzzload_pkg $pkgname] thread::mutex unlock $mutex return $result } else { return $pkgstate } } proc shutdown {} { variable loader_tid if {[thread::exists $loader_tid]} { thread::release $loader_tid thread::join $loader_tid set loader_tid "" } } } # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ ## Ready package provide zzzload [namespace eval zzzload { variable version set version 999999.0a1.0 }] return