From: KOSAKI Motohiro Date: 2010-01-15T17:23:52+09:00 Subject: [ruby-dev:40101] Re: [Bug #2603] NetBSD 5.0以降でpthreadの処理に由来する不具合 こんにちは > こんにちは。 > > In message <20100115091546.6EC3.A69D9226@jp.fujitsu.com> > on Fri, 15 Jan 2010 09:26:02 +0900, > KOSAKI Motohiro wrote: > >> で、thread_timer()から脱出できなくなる問題が解決するところまで確認した > >> 状況で、全部のパターンを追えたというわけではありません。つまり、 > >> > >> > それと、fork()して作られた子供のrubyはruby threadを作れない、あるいは > >> > 作れても動作は異なるということでしょうか? > >> といったケースはテストも何もしていませんねぇ。 > > > > すいません、よくわかっていないので、本件の方針を確認させてもらえませんか? > 私が理解している範囲で、想定できるケースは以下の3つではないかと思います。 > > 1. fork(2)した子プロセスがexec(3)する場合 > 2. プロセス自身がfork(2)せずにexec(3)する場合 > 3. fork(2)した子プロセスがexec(3)せずに動作を続ける場合 > > 今回は1.と2.について取り上げ、redmineに登録したpatch-1ではとにかく1.だ > けを、patch2では2.のケースも考慮した修正を行ったつもりです。 > > 1.については、fork(2)した子プロセスがpthread_*()な関数の呼び出しを避け > るようにしたつもりです。 > > 2.については、fork(2)した子プロセスがpthread_*()な関数の呼び出しを避け > つつ、fork(2)せずにexec(3)する場合は稼働しているpthreadの後始末を行う > ようにしたつもりです。 > > 3.についてはテストすら行っていません。(test caseがないとも言えます。) > ただ、C言語等でpthreadを使用したプログラミングでも、fork(2)と混ぜるこ > とは本質的な危険性を伴うため、どこまで3.のようなケースが必要なのか若干 > の疑問を感じるところもあります。 > > というわけで、3.はともかく1.や2.は修正しないとまずいだろうというのが > 私の要望です。 三浦さんと同じく2の必要性に疑問が・・・ (根拠も同じです) > なお、patch-1とpatch-2のいずれかを適用しないと、fork(2)すらしないケース > でも、timer_threadが待ち続ける状況も発生することに後から気付きました。 > > >> (1) fork(2)した子プロセスは非同期シグナルに対して安全な関数だけを使用でき、 > >> pthread_*()な関数も使用できません(非同期シグナルに対して安全でない)。 > > > > という所なんですが、そもそもmalloc()を呼ばないことを保証できないような > > 構造にすでになっているので、規格的な観点で絶対safeといえる実装に変更する事は > > 困難と予想しています。 > 次元が違いますが、GNU iconvを前提とした //translit を使ったプログラム > と同様な状態にRuby自体がなっているとも考えられます。 > > 長期的には、pthreadに対して安全な構造にした方が良いと思いますが、短期 > 的には難しいでしょう。 僕、iconvの件は単に//translitをrubyの仕様から落とせばええやん。と思ってました。 これがないと困る人っているんですか?(聞く相手が違う気もします。すいません) > > > NetBSDの仕様(何をしたら刺さるか)を確認し、そこだけを避けるように変更する。 > > という方針だと思ってよいのでしょうか? > 「NetBSDの仕様」ではなく、あくまでもfork(2)/pthread(3)の仕様を守るよう > にして欲しいというのが「要望」です。 > > とは言うものの、現実的なところとして、 > > o 明らかにpthread(3)関係の関数呼び出しはまずい。 > o 間接的にpthread関係の関数呼び出しもまずい。 > o 非同期シグナルに対して安全でない関数でも、pthreadのデータ構造等に > 直接関与しなければ案外大丈夫かもしれない。 ええと、一般論の話をするならlibcレベルでもreentrantじゃないけどスレッドセーフな関数は わりと一杯あって、それは要するに内部でpthread_mutexかそれに類似したロックを 取っているということで、誰かがそういうロックを取っている最中に forkすると、以後libcのスレッドセーフな関数を呼ぶと刺さるという結果に なる可能性があります。 NetBSDの話をしているなら、きっと神戸さんが正しいと思います あ、↑にコミットを反対する意図はありません。一応明言しておこう