Squeak
s := Semaphore new. m := Monitor new. [ m critical: [ [ p := Processor activeProcess. s signal. (Delay forSeconds: 1) wait. ] ensure: [ m critical: [ Transcript show: 'OK?'; cr. ]. ]. ]. ] fork. s wait. p terminate.
ensure: とか ifCurtailed: とか。
保護ブロックが殺されたとき、例外ブロックはそれを殺したプロセスで実行される。
こんなことはか〜〜〜なり最初のころに勉強したはずなのに、すっかり忘れていた。
というわけで、上のようなコードはデッドロックを招くのだ。
2回目のcritical:で保護したい何かは、
他のプロセスに於いても同一のMonitorで保護されている限り、
プロセスに対して安全であることが既に最初のcritical:で保証されているはずなので、
そういう場合には2回目のcritical:は不要。
ただ、今回の場合のように明らかにMonitor>>critical:がネストしていると分かる場合は稀。
critical:がネストしているかどうか、ifCurtailed:とかの例外ブロックからコールされる可能性が無いか、
そういうことを考えなくてはならないなら、再突入可能なcritical:だなんて謳えないのではないかと思ったり。
否、まぁ、同一プロセスで再突入可能というのは確かにそうなのだから、別に悪くはないのか。
とにかく、難しいなぁ、ってこと。