From: Hidetoshi NAGAI Date: 2006-12-01T16:24:19+09:00 Subject: Re: Ruby Tk and Threads error From: "jorge santiago" Subject: Ruby Tk and Threads error Date: Fri, 1 Dec 2006 02:08:56 +0900 Message-ID: > The problem is when I click the "stop drawing" button which is bound > to a "proc { @drawing_thread.exit }" I *often* (not always) get the > following error: > > /usr/local/rubytk/lib/ruby/1.8/tk.rb:1537:in `mainloop': killed thread > (ThreadError) Probably, that is a bug which depends on timing of callback operation. Please try the following patch. Index: ext/tk/tcltklib.c =================================================================== RCS file: /var/cvs/src/ruby/ext/tk/tcltklib.c,v retrieving revision 1.40.2.13 diff -u -r1.40.2.13 tcltklib.c --- ext/tk/tcltklib.c 10 Jul 2006 09:51:30 -0000 1.40.2.13 +++ ext/tk/tcltklib.c 1 Dec 2006 07:20:02 -0000 @@ -4,7 +4,7 @@ * Oct. 24, 1997 Y. Matsumoto */ -#define TCLTKLIB_RELEASE_DATE "2006-07-10" +#define TCLTKLIB_RELEASE_DATE "2006-12-01" #include "ruby.h" #include "rubysig.h" @@ -5526,10 +5526,15 @@ *(q->done) = -1; /* back to caller */ - DUMP2("back to caller (caller thread:%lx)", q->thread); - DUMP2(" (current thread:%lx)", rb_thread_current()); - rb_thread_run(q->thread); - DUMP1("finish back to caller"); + if (RTEST(rb_funcall(q->thread, ID_alive_p, 0, 0))) { + DUMP2("back to caller (caller thread:%lx)", q->thread); + DUMP2(" (current thread:%lx)", rb_thread_current()); + rb_thread_run(q->thread); + DUMP1("finish back to caller"); + } else { + DUMP2("caller is dead (caller thread:%lx)", q->thread); + DUMP2(" (current thread:%lx)", rb_thread_current()); + } /* end of handler : remove it */ return 1; @@ -5844,10 +5849,15 @@ *(q->done) = -1; /* back to caller */ - DUMP2("back to caller (caller thread:%lx)", q->thread); - DUMP2(" (current thread:%lx)", rb_thread_current()); - rb_thread_run(q->thread); - DUMP1("finish back to caller"); + if (RTEST(rb_funcall(q->thread, ID_alive_p, 0, 0))) { + DUMP2("back to caller (caller thread:%lx)", q->thread); + DUMP2(" (current thread:%lx)", rb_thread_current()); + rb_thread_run(q->thread); + DUMP1("finish back to caller"); + } else { + DUMP2("caller is dead (caller thread:%lx)", q->thread); + DUMP2(" (current thread:%lx)", rb_thread_current()); + } /* end of handler : remove it */ return 1; @@ -6921,10 +6931,15 @@ *(q->done) = -1; /* back to caller */ - DUMP2("back to caller (caller thread:%lx)", q->thread); - DUMP2(" (current thread:%lx)", rb_thread_current()); - rb_thread_run(q->thread); - DUMP1("finish back to caller"); + if (RTEST(rb_funcall(q->thread, ID_alive_p, 0, 0))) { + DUMP2("back to caller (caller thread:%lx)", q->thread); + DUMP2(" (current thread:%lx)", rb_thread_current()); + rb_thread_run(q->thread); + DUMP1("finish back to caller"); + } else { + DUMP2("caller is dead (caller thread:%lx)", q->thread); + DUMP2(" (current thread:%lx)", rb_thread_current()); + } /* end of handler : remove it */ return 1; -- Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)