From: KOSAKI Motohiro Date: 2010-05-06T21:50:11+09:00 Subject: [ruby-dev:41197] Re: MonitorMixin::ConditionVariable#wait timeout kosakiです えーと。はい。そうですね。 つらつらと考えてみたところakrさんのほうが正しそうです。 >> +1 => ないとまずい >> >> 一般論としていうと、原因不明でも実装できるのはリトライが安全なケースに限られると思っていて >> Cond#waitの場合、Cond#signalされたあともう一回waitすると寝てしまうので >> 「できるかぼけ」と壁を叩くケースが出るんじゃないかな > > たとえ wait が ETIMEDOUT で返って来たとしても、 > signal されていないことは保証されないのではないかと思うんですがどうでしょう? 正しいです。 posix_cond_wait()レベルでどちらの実装も許しているという認識です。 # 実際に*BSDとLinuxとで挙動が違うケースがあった気がするけど、細かい条件は # 思い出せず。。。 # すいません > wait がタイムアウトで諦めた後、mutex をロックする前に、 > 他のスレッドにコンテキストスイッチして signal が起こることは無いんでしょうか。 > > もし有るとすると、ETIMEDOUT でリトライすると、寝てしまって永久に起きない、 > という上記で懸念されている状況に結局なり得るのではないかと思うんですが。 そのとおりですね。今のインターフェースだと、どのみちCV#signalスレッドとCV#wait するスレッドは、起床条件にたいしてある種の合意があるはずで、 CV#waitする側のスレッドがCV#waitする直前に条件が満たされているかチェックすることにより 問題はおきない。と というわけで、先の発言は撤回します。考慮が足りなくてすいません。 あと、ちょっと脱線なのですが、使う側から見ると原因を切り分けたいのって二種類ある気がしますね。 1) タイムアウトとCV#sinal 2) タイムアウトとspurious wakeup 1は今の議論でpredicateを呼び出し側がチェックするはずだから考慮不要という結論になったと 思います。2はどうしましょう?今のインターフェースだとCV#waitの戻り値はselfなので、 判定不可能ですよね?