[#36686] 1.1 < 61.1 - 60.0 — Shin-ichiro HARA <sinara@...>

原です。

19 messages 2002/12/06

[#36770] www.ruby-lang.orgリニューアル準備のお知らせ — TADA Tadashi <sho@...>

ruby-lang.orgのwebmasterチームでは、タイムリーな情報提供と使いやすい

11 messages 2002/12/16

[ruby-list:36659] Re: Gtk.main

From: Hiroshi IGARASHI <iga@...>
Date: 2002-12-03 15:28:29 UTC
List: ruby-list #36659
いがらしです。

Ruby/GTK内部の話なのでruby-gnome-devel-jaに振ります。

At Tue, 3 Dec 2002 23:11:06 +0900,
Masao Mutoh <mutoh@highway.ne.jp> wrote:
> 
> むとうです。
> 
> > なかだです。

> > シグナルでもmain_quitでもキューに貯めておくだけみたいで、問題な
> > さそうです。その後でGtk.mainを呼んでいるスレッドを起こす必要が
> > ありますが。
> > むとうさんの[ruby-list:36652]のサンプルに、puts "finished"の後
> > でGtk.main_quitとThread.main.runを追加すると処理が終ったところ
> > で終了するようになりました。
> 
> あぁ、Thread.main.runに思い至りませんでした。
> 
> でも、ここで、runするThreadを明示的に指定しないといけないのって
> なぜなのでしょうか。mainスレッドってずっと実行状態なのかなと
> 思ってたのですが、そういうものではないのでしょうか。
> #また、激しく勘違いしてそうなのですが.....。

実際にtraceしてないので間違ってるかもしれませんが、
だいたいこんな感じのcall stackになってるはずです
(RubyとCごちゃまぜ)。

mainスレッド
  Gtk.main
    gtk_main()
      ...
        rbgtk_poll()
          rb_thread_select() /* 重い処理スレッドに制御を渡す */
重い処理スレッド
  Gtk.main_quit
    gtk_main_quit()

gtk_main_quit()を呼んでも、mainスレッドはrb_thread_select()
内部で止まったままです。Thread.main.runでmainスレッドを
起こしてやると、rb_thread_select()からgtk_main()まで帰ってきて
main loop終了検出、さらにGtk.mainも終了という流れになります。

よくある使い方だと思うので、Gtk.main, Gtk.main_quitに
面倒を見させるようにしてみました(CVS HEADからの差分)。
深く考えていないので、何か問題があるかも知れません。
# たぶんあります。

--
五十嵐  宏  (Hiroshi IGARASHI)

Index: src/rbgtkmain.c
===================================================================
RCS file: /cvsroot/ruby-gnome/ruby-gnome/gtk/src/rbgtkmain.c,v
retrieving revision 1.5
diff -u -p -r1.5 rbgtkmain.c
--- src/rbgtkmain.c	4 Feb 2002 00:20:48 -0000	1.5
+++ src/rbgtkmain.c	3 Dec 2002 15:08:35 -0000
@@ -13,6 +13,8 @@
 
 #include "global.h"
 
+static VALUE rbgtk_main_threads = Qnil;
+
 static VALUE
 gtk_m_events_pending(self)
     VALUE self;
@@ -24,6 +26,7 @@ static VALUE
 gtk_m_main(self)
     VALUE self;
 {
+    rb_ary_push(rbgtk_main_threads, rb_thread_current());
     gtk_main();
     return Qnil;
 }
@@ -40,6 +43,7 @@ gtk_m_main_quit(self)
     VALUE self;
 {
     gtk_main_quit();
+    rb_thread_run(rb_ary_pop(rbgtk_main_threads));
     return Qnil;
 }
 
@@ -201,6 +205,8 @@ rbgtk_m_log_remove_handler(self, log_dom
 void Init_gtk_main()
 {
     rb_define_module_function(mGtk, "events_pending", gtk_m_events_pending, 0);
+    rb_global_variable(&rbgtk_main_threads);
+    rbgtk_main_threads = rb_ary_new();
     rb_define_module_function(mGtk, "main", gtk_m_main, 0);
     rb_define_module_function(mGtk, "main_level", gtk_m_main_level, 0);
     rb_define_module_function(mGtk, "main_quit", gtk_m_main_quit, 0);

In This Thread