|
|
|
|
@ -788,8 +788,12 @@ namespace eval shellthread::manager {
|
|
|
|
|
foreach workertid $subscriberless_workers { |
|
|
|
|
if {$workertid ni $shuttingdown_workers} { |
|
|
|
|
if {$workertid ni $free_threads && $workertid ne "noop"} { |
|
|
|
|
#JMN |
|
|
|
|
thread::send $workertid {set ::shellthread::worker::settings $::shellthread::worker::settings_defaults} |
|
|
|
|
#Must be async: unsubscribe is on the exit/quit teardown path and a worker whose |
|
|
|
|
#event loop has stopped servicing events (G-036: Tcl 9 console+udp worker wedge) |
|
|
|
|
#would block a synchronous send forever, freezing the shell. Async is safe - |
|
|
|
|
#sends to a thread are processed FIFO, so a later reuse via new_worker sees the |
|
|
|
|
#settings reset applied before anything it sends. |
|
|
|
|
thread::send -async $workertid {set ::shellthread::worker::settings $::shellthread::worker::settings_defaults} |
|
|
|
|
#todo - log freeing up of thread |
|
|
|
|
lappend free_threads $workertid |
|
|
|
|
} |
|
|
|
|
@ -812,7 +816,10 @@ namespace eval shellthread::manager {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
proc get_tag_config {tag} { |
|
|
|
|
#review |
|
|
|
|
#review - bare synchronous thread::send: blocks forever if the worker's event loop is |
|
|
|
|
#wedged (G-036 hazard class). Reached from new_worker when a tag already has a live |
|
|
|
|
#worker. Needs a result so can't simply go async - convert to async + vwait-with-timeout |
|
|
|
|
#if this path shows up in a hang. |
|
|
|
|
variable workers |
|
|
|
|
if {![dict exists $workers $tag]} { |
|
|
|
|
error "shellthread::manager::get_tag_config error no existing tag $tag" |
|
|
|
|
@ -858,10 +865,13 @@ namespace eval shellthread::manager {
|
|
|
|
|
set timedout 1 |
|
|
|
|
break |
|
|
|
|
} else { |
|
|
|
|
after cancel $timeout_timer |
|
|
|
|
#Do not cancel the timeout timer until all awaited workers have responded - |
|
|
|
|
#cancelling on the first response left later vwait iterations unbounded, so a |
|
|
|
|
#wedged worker (G-036) after a healthy one hung shutdown forever. |
|
|
|
|
lappend ended $::shellthread::waitfor |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
after cancel $timeout_timer |
|
|
|
|
} |
|
|
|
|
set free_threads [list] |
|
|
|
|
return [dict create existed $waiting_for ended $ended timedout $timedout allthreads [thread::names]] |
|
|
|
|
@ -963,7 +973,7 @@ namespace eval shellthread::manager {
|
|
|
|
|
|
|
|
|
|
package provide shellthread [namespace eval shellthread { |
|
|
|
|
variable version |
|
|
|
|
set version 1.6.2 |
|
|
|
|
set version 1.6.3 |
|
|
|
|
}] |
|
|
|
|
|
|
|
|
|
|