From: "jorge santiago" <jorge.santiago / gmail.com>
Subject: Ruby Tk and Threads error
Date: Fri, 1 Dec 2006 02:08:56 +0900
Message-ID: <bb2bb0e80611300813u2234a087w5f387631aefa73bf / mail.gmail.com>
> 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)