[前][次][番号順一覧][スレッド一覧]

ruby-changes:35479

From: normal <ko1@a...>
Date: Sat, 13 Sep 2014 04:42:17 +0900 (JST)
Subject: [ruby-changes:35479] normal:r47561 (trunk): Process.detach: avoid singleton class creation

normal	2014-09-13 04:42:01 +0900 (Sat, 13 Sep 2014)

  New Revision: 47561

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47561

  Log:
    Process.detach: avoid singleton class creation
    
    * process.c (Init_process): subclass Thread as Process::Waiter
      (rb_detach_process): use Process::Waiter instead of singleton class
    
    * test/ruby/test_process.rb (test_process_detach): new test
    
    * inits.c (rb_call_inits): call Init_Thread before Init_process to
      ensure Process::Waiter may be a subclass of Thread
    
    Thanks to headius for reporting [Bug #10231]
    Thanks to nobu for review of my initial patch.

  Modified files:
    trunk/ChangeLog
    trunk/inits.c
    trunk/process.c
    trunk/test/ruby/test_process.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 47560)
+++ ChangeLog	(revision 47561)
@@ -1,3 +1,14 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Sep 13 04:40:04 2014  Eric Wong  <e@8...>
+
+	* process.c (Init_process): subclass Thread as Process::Waiter
+	  (rb_detach_process): use Process::Waiter instead of singleton class
+	  Thanks to headius and nobu. [Bug #10231]
+
+	* test/ruby/test_process.rb (test_process_detach): new test
+
+	* inits.c (rb_call_inits): call Init_Thread before Init_process to
+	  ensure Process::Waiter may be a subclass of Thread
+
 Fri Sep 12 18:14:28 2014  Eric Wong  <e@8...>
 
 	* vm.c (env_alloc): inline to avoid extra zeroing
Index: process.c
===================================================================
--- process.c	(revision 47560)
+++ process.c	(revision 47561)
@@ -1007,6 +1007,8 @@ proc_waitall(void) https://github.com/ruby/ruby/blob/trunk/process.c#L1007
     return result;
 }
 
+static VALUE rb_cWaiter;
+
 static inline ID
 id_pid(void)
 {
@@ -1038,7 +1040,7 @@ rb_detach_process(rb_pid_t pid) https://github.com/ruby/ruby/blob/trunk/process.c#L1040
 {
     VALUE watcher = rb_thread_create(detach_process_watcher, (void*)(VALUE)pid);
     rb_thread_local_aset(watcher, id_pid(), PIDT2NUM(pid));
-    rb_define_singleton_method(watcher, "pid", detach_process_pid, 0);
+    RBASIC_SET_CLASS(watcher, rb_cWaiter);
     return watcher;
 }
 
@@ -7516,6 +7518,11 @@ Init_process(void) https://github.com/ruby/ruby/blob/trunk/process.c#L7518
     rb_define_module_function(rb_mProcess, "waitall", proc_waitall, 0);
     rb_define_module_function(rb_mProcess, "detach", proc_detach, 1);
 
+    rb_cWaiter = rb_define_class_under(rb_mProcess, "Waiter", rb_cThread);
+    rb_undef_alloc_func(rb_cWaiter);
+    rb_undef_method(CLASS_OF(rb_cWaiter), "new");
+    rb_define_method(rb_cWaiter, "pid", detach_process_pid, 0);
+
     rb_cProcessStatus = rb_define_class_under(rb_mProcess, "Status", rb_cObject);
     rb_undef_method(CLASS_OF(rb_cProcessStatus), "new");
 
Index: inits.c
===================================================================
--- inits.c	(revision 47560)
+++ inits.c	(revision 47561)
@@ -46,7 +46,6 @@ rb_call_inits(void) https://github.com/ruby/ruby/blob/trunk/inits.c#L46
     CALL(Time);
     CALL(Random);
     CALL(signal);
-    CALL(process);
     CALL(load);
     CALL(Proc);
     CALL(Binding);
@@ -56,6 +55,7 @@ rb_call_inits(void) https://github.com/ruby/ruby/blob/trunk/inits.c#L55
     CALL(VM);
     CALL(ISeq);
     CALL(Thread);
+    CALL(process);
     CALL(Cont);
     CALL(Rational);
     CALL(Complex);
Index: test/ruby/test_process.rb
===================================================================
--- test/ruby/test_process.rb	(revision 47560)
+++ test/ruby/test_process.rb	(revision 47561)
@@ -1965,4 +1965,12 @@ EOS https://github.com/ruby/ruby/blob/trunk/test/ruby/test_process.rb#L1965
       runner.close
     end
   end if defined?(fork)
+
+  def test_process_detach
+    pid = fork {}
+    th = Process.detach(pid)
+    assert_equal pid, th.pid
+    status = th.value
+    assert status.success?, status.inspect
+  end if defined?(fork)
 end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]