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/