From: Yusuke Endoh Date: 2012-07-02T20:14:33+09:00 Subject: [ruby-dev:45893] Re: 非同期割り込みに対する対処案(日本語版) 遠藤です。 2012/06/26 SASADA Koichi : >>> begin >>> > # 何か処理 >>> > ensure >>> > Thread.mask_interrupt(Exception, :uninterruptible) do >>> > # 一度全部割り込み禁止にして >>> > Thread.mask_interrupt(SignalException, :blocking_interruptible) >>> > do >>> > # シグナルだけ割り込みを許して >>> > # リソース解放処理 >>> > end >>> > end >>> > end >> 外側が :immediate_interruptible であるとすると、これは race がありますよね。 >> >> 「何か処理」で例外が起きて、ensure 節に入った後、 >> Thread.mask_interrupt(Exception, :uninterruptible) を呼び出す前に >> 非同期イベントによる例外が起きると、リソース開放処理がスキップされます。 >> >> 実装上はそこでは例外は起きないのかもしれませんが... > >  確かに,仰るとおりです.寝ぼけた頭では,とりあえず > > (1) 「実装上はそこでは例外は起きない」ことを仕様にする > (2) ensure に細工する(あまりやりたくない) > (3) 利用者が immediate にしない > > が考えられると思います.どれがいいでしょう.または,他の選択肢はあるで > しょうか. 以下のようにすれば現状の API で問題ないと思うのですが、 何か見落としているでしょうか。 # (1) と (2) の間の割り込みを防ぐために Thread.mask_interrupt(Exception, :blocking_interruptible) do # (0) begin # begin 〜 ensure 内での割り込みはいつでも許す Thread.mask_interrupt(Exception, :immediate_interruptible) do # 何か処理 end ensure # (1) # (0) のおかげでこの間に割り込まれることはない Thread.mask_interrupt(Exception, :uninterruptible) do (2) # 一度全部割り込み禁止にして Thread.mask_interrupt(SignalException, :blocking_interruptible) do # シグナルだけ割り込みを許して # リソース解放処理 end end end end -- Yusuke Endoh