永井@知能.九工大です.

ThreadGroup に次の機能を加えるのはいかがでしょうか.
---------------------------------------
freeze された ThreadGroup {からの|への} Thread の所属変更を禁止する.
---------------------------------------
現状では $SAFE >= 4 の場合のみに変更が禁止されるようになってますが
(ですよね?),もう少し緩いセキュリティレベルでもそうした制約を使った
ThreadGroup 単位での管理ができると嬉しいかもという提案です.

# サブスレッドの所属を変更して,管理逃れをすることが難しくなる.
# 多分,C レベルでの操作でなければ無理なのでは?

このメールの末尾に patch を付けておきます.

freeze された ThreadGroup に新たな Thread が追加されるのは,
freeze 前からその ThreadGroup に含まれていた Thread が
新たな Thread を生成した場合のみです.
もちろん,その新しい Thread を別の ThreadGroup には移せません.

ご意見をお願いします.

Index: eval.c
===================================================================
RCS file: /src/ruby/eval.c,v
retrieving revision 1.479
diff -u -r1.479 eval.c
--- eval.c	11 Jul 2003 19:23:13 -0000	1.479
+++ eval.c	14 Jul 2003 04:50:18 -0000
@@ -7856,6 +7856,7 @@
     int abort;
     int priority;
     int gid;
+    int gfreeze;
 
     st_table *locals;
 
@@ -9188,6 +9189,7 @@
     th->abort = 0;\
     th->priority = 0;\
     th->gid = 1;\
+    th->gfreeze = 0;\
     th->locals = 0;\
 } while (0)
 
@@ -9301,6 +9303,7 @@
 	curr_thread->next = th;
 	th->priority = curr_thread->priority;
 	th->gid = curr_thread->gid;
+	th->gfreeze = curr_thread->gfreeze;
     }
 
     PUSH_TAG(PROT_THREAD);
@@ -9888,6 +9891,27 @@
     return ary;
 }
 
+VALUE
+thgroup_freeze(group)
+    VALUE group;
+{
+    struct thgroup *data;
+    rb_thread_t th;
+
+    rb_obj_freeze(group);
+
+    Data_Get_Struct(group, struct thgroup, data);
+
+    FOREACH_THREAD(th) {
+	if (th->gid == data->gid) {
+	  th->gfreeze = 1;
+	}
+    }
+    END_FOREACH(th);
+
+    return group;
+}
+
 static VALUE
 thgroup_add(group, thread)
     VALUE group, thread;
@@ -9897,6 +9921,13 @@
 
     rb_secure(4);
     th = rb_thread_check(thread);
+
+    if (th->gfreeze) {
+      rb_raise(rb_eThreadError, "can't move from the frozen thread group");
+    }
+    if (OBJ_FROZEN(group)) {
+      rb_raise(rb_eThreadError, "can't move to the frozen thread group");
+    }
     Data_Get_Struct(group, struct thgroup, data);
 
     th->gid = data->gid;
@@ -9970,6 +10001,7 @@
     cThGroup = rb_define_class("ThreadGroup", rb_cObject);
     rb_define_alloc_func(cThGroup, thgroup_s_alloc);
     rb_define_method(cThGroup, "list", thgroup_list, 0);
+    rb_define_method(cThGroup, "freeze", thgroup_freeze, 0);
     rb_define_method(cThGroup, "add", thgroup_add, 1);
     rb_define_const(cThGroup, "Default", rb_obj_alloc(cThGroup));
 }


-- 
                                         永井 秀利 (九工大 知能情報)
                                             nagai / ai.kyutech.ac.jp