From: matz@... (Yukihiro Matsumoto) Date: 2003-02-21T12:18:34+09:00 Subject: [ruby-dev:19629] Re: [ruby-cvs] ruby: * eval.c (rb_thread_remove): thread may die in the process of In message "[ruby-dev:19626] Re: [ruby-cvs] ruby: * eval.c (rb_thread_remove): thread may die in the process of" on 03/02/21, nobu.nakada@nifty.ne.jp writes: | |なかだです。 | |At Thu, 20 Feb 2003 10:09:32 +0000, |matz wrote: |> Log: |> * eval.c (rb_thread_remove): thread may die in the process of |> rb_thread_die(). this change was suggested by Rudi Cilibrasi |> . | |たぶんこれだと思うんですが、rb_thread_wait_other_threads()で無 |限ループになります。 | |$ ruby -e 'Thread.new {}' | |というか、そもそもrb_thread_die()はスレッドをTHREAD_KILLEDにす |るための関数なので、mayじゃなくてmustだろうと思うんですが、どう |いう指摘だったんでしょうか。 こんな感じ。MPI Rubyで動かないってことですね。でも、言われて みれば確かにそうですよねえ。 まつもと ゆきひろ /:|) In message "Thread bug + fix for ruby 1.8.0 CVS snapshot / MPI-Ruby fix" on 03/02/13, Rudi Cilibrasi writes: | | |Hi Matz, | |I must compliment you on your excellent language Ruby which I use |enthusiastically at work. I have noticed that there seems to be a |bug with thread scheduling and cleanup, and have found a fix which |may be useful to you. In particular, I am using MPI Ruby, which works |fine until the program cleans up ready to exit, and then segfaults. |I am working against the latest CVS snapshot, Ruby version 1.8.0. |After adding the two lines I detail below to eval.c, I find that MPI-Ruby |works fine as hoped. Please look for 'cilibrar' marker. | |Best regards, | |Rudi | |-------------------------------------------------------------------------- | |In eval.c, two lines are added; the first is in rb_thread_remove, |on line 7909: |static void |rb_thread_remove(th) | rb_thread_t th; |{ | if (th->status == THREAD_KILLED) return; | | rb_thread_ready(th); | rb_thread_die(th); | if (th->status == THREAD_KILLED) return; /* cilibrar */ | th->prev->next = th->next; | th->next->prev = th->prev; |} |This double check is necessary, because a thread may be killed extraneously. | |Secondly, on line 8937 in rb_thread_start_0: | rb_thread_schedule(); | exit(0); /* cilibrar */ | return 0;\\/* not reached */ | |This seems helpful because the not-reached part of code can be reached |on termination of last Ruby thread.