I'm very sorry for bothering you.
# Before this mail, a direct mail might be sent you.
# The mail rejected by ruby-talk ML because of mail size.
# So, I send this to ML for other ML members.
···
From: Juju SL <jujusl@free.fr>
Subject: Re: Tk : non blocking Tk.mainloop
Date: Fri, 6 May 2011 05:11:23 +0900
Message-ID: <a300236309b957f16fc5b649fa48ea9b@ruby-forum.com>
> You don't need manual patch. Please use "patch" command.
That's what I did, but it rejected 2 chunks, so I had no other choice...
> # Or, packaged version of tk.rb is not a normal one of ruby192p0?
> # If so, please tell me the version of your package.
Debian Squeeze comes with 1.9.1 packages, but Ruby version is 1.9.2p0
I see. I made a new diff from libtcltk-ruby1.9.1_1.9.2.0-2.
> I want to know when and how Tk.mainloop exits.
> Could you send me a *FULL* debug log with tk.rb (patched by previous
> (ruby-talk:382536) patch) patched by the following?
Good news ! This patch applied with the previous one works ;Tk.mainloop
works as expected and waits after "log008" (I attached the log file)
It may be not so good news. Because, It shows that the problem may
depend on severe timing of thread switching.
I made a new patch to force to run the eventloop just before waiting a
condition variable.
Could you try it both of with and without $DEBUG (-d) option?
If not work, please send me the full log.
If work, please remove all debug log "log???" lines in mainloop method
and try it. (Probably, I'm too worried about changing timing of thread
switching by checking $DEBUG variable.)
--- tk.rb.deb-libtcltk-ruby1.9.1_1.9.2.0-2 2010-11-01 17:54:54.000000000 +0900
+++ tk.rb 2011-05-07 06:25:42.000000000 +0900
@@ -1236,6 +1236,9 @@
raise e
end
+ interp.mainloop_abort_on_exception = true
+ Thread.current.instance_variable_set("@interp", interp)
+
status = [nil]
def status.value
self[0]
@@ -1271,19 +1274,23 @@
}
set __initial_state_of_rubytk__ 1
trace add variable __initial_state_of_rubytk__ unset __startup_rbtk_mainloop__
+
+# complete initializing
+ruby {TkCore::INTERP_THREAD[:interp] = TkCore::INTERP_THREAD.instance_variable_get('@interp')}
EOS
begin
begin
#TclTkLib.mainloop_abort_on_exception = false
#Thread.current[:status].value = TclTkLib.mainloop(true)
- interp.mainloop_abort_on_exception = true
- Thread.current[:interp] = interp
+ #interp.mainloop_abort_on_exception = true
+ #Thread.current[:interp] = interp
Thread.current[:status].value = interp.mainloop(true)
rescue SystemExit=>e
Thread.current[:status].value = e
rescue Exception=>e
Thread.current[:status].value = e
+ p e if $DEBUG
retry if interp.has_mainwindow?
ensure
INTERP_MUTEX.synchronize{ INTERP_ROOT_CHECK.broadcast }
@@ -1300,12 +1307,20 @@
end
}
+ # check a Tcl/Tk interpreter is initialized
until INTERP_THREAD[:interp]
- Thread.pass
+ # Thread.pass
+ INTERP_THREAD.run
end
+
# INTERP_THREAD.run
raise INTERP_THREAD[:interp] if INTERP_THREAD[:interp].kind_of? Exception
+ # check an eventloop is running
+ while INTERP_THREAD.alive? && TclTkLib.mainloop_thread?.nil?
+ INTERP_THREAD.run
+ end
+
INTERP = INTERP_THREAD[:interp]
INTERP_THREAD_STATUS = INTERP_THREAD[:status]
@@ -1316,6 +1331,9 @@
INTERP_THREAD.kill
end
}
+
+ # (for safety's sake) force the eventloop to run
+ INTERP_THREAD.run
end
def INTERP.__getip
@@ -1834,32 +1852,63 @@
TclTkLib.mainloop(check_root)
else ### Ruby 1.9 !!!!!
+p :log001 if $DEBUG
unless TkCore::INTERP.default_master?
# [MultiTkIp] slave interp ?
return TkCore::INTERP._thread_tkwait('window', '.') if check_root
end
+p :log002 if $DEBUG
# like as 1.8, withdraw a root widget before calling Tk.mainloop
+p :log003 if $DEBUG
TkCore::INTERP._eval_without_enc('catch {unset __initial_state_of_rubytk__}')
+p :log004 if $DEBUG
INTERP_THREAD.run
begin
+p :log005 if $DEBUG
TclTkLib.set_eventloop_window_mode(true)
+
+p :log006 if $DEBUG
+ # force run the eventloop
+ TkCore::INTERP._eval_without_enc('update')
+p :log007 if $DEBUG
+ TkCore::INTERP._eval_without_enc('catch {set __initial_state_of_rubytk__}')
+p :log008 if $DEBUG
+ INTERP_THREAD.run
if check_root
+p :log009 if $DEBUG
INTERP_MUTEX.synchronize{
+p :log010 if $DEBUG
INTERP_ROOT_CHECK.wait(INTERP_MUTEX)
+p :log011 if $DEBUG
status = INTERP_THREAD_STATUS.value
+p [:log012, status] if $DEBUG
if status && TkCore::INTERP.default_master?
INTERP_THREAD_STATUS.value = nil if $SAFE < 4
+p :log013 if $DEBUG
raise status if status.kind_of?(Exception)
end
+p :log014 if $DEBUG
}
else
- INTERP_THREAD.value
+p :log015 if $DEBUG
+ # INTERP_THREAD.value
+ begin
+ INTERP_THREAD.value
+ rescue Exception => e
+p [:log016, e] if $DEBUG
+ raise e
+ end
end
+ rescue Exception => e
+p [:log017, e] if $DEBUG
+ raise e
ensure
+p :log018 if $DEBUG
TclTkLib.set_eventloop_window_mode(false)
end
+p :log019 if $DEBUG
end
end
================================================================
--
Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
Department of Artificial Intelligence, Kyushu Institute of Technology