Skip to content

Commit afa512d

Browse files
author
normal
committed
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 ruby#10231] Thanks to nobu for review of my initial patch. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47561 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent 5311e0a commit afa512d

File tree

4 files changed

+28
-2
lines changed

4 files changed

+28
-2
lines changed

ChangeLog

+11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
Sat Sep 13 04:40:04 2014 Eric Wong <[email protected]>
2+
3+
* process.c (Init_process): subclass Thread as Process::Waiter
4+
(rb_detach_process): use Process::Waiter instead of singleton class
5+
Thanks to headius and nobu. [Bug #10231]
6+
7+
* test/ruby/test_process.rb (test_process_detach): new test
8+
9+
* inits.c (rb_call_inits): call Init_Thread before Init_process to
10+
ensure Process::Waiter may be a subclass of Thread
11+
112
Fri Sep 12 18:14:28 2014 Eric Wong <[email protected]>
213

314
* vm.c (env_alloc): inline to avoid extra zeroing

inits.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ rb_call_inits(void)
4646
CALL(Time);
4747
CALL(Random);
4848
CALL(signal);
49-
CALL(process);
5049
CALL(load);
5150
CALL(Proc);
5251
CALL(Binding);
@@ -56,6 +55,7 @@ rb_call_inits(void)
5655
CALL(VM);
5756
CALL(ISeq);
5857
CALL(Thread);
58+
CALL(process);
5959
CALL(Cont);
6060
CALL(Rational);
6161
CALL(Complex);

process.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,8 @@ proc_waitall(void)
10071007
return result;
10081008
}
10091009

1010+
static VALUE rb_cWaiter;
1011+
10101012
static inline ID
10111013
id_pid(void)
10121014
{
@@ -1038,7 +1040,7 @@ rb_detach_process(rb_pid_t pid)
10381040
{
10391041
VALUE watcher = rb_thread_create(detach_process_watcher, (void*)(VALUE)pid);
10401042
rb_thread_local_aset(watcher, id_pid(), PIDT2NUM(pid));
1041-
rb_define_singleton_method(watcher, "pid", detach_process_pid, 0);
1043+
RBASIC_SET_CLASS(watcher, rb_cWaiter);
10421044
return watcher;
10431045
}
10441046

@@ -7516,6 +7518,11 @@ Init_process(void)
75167518
rb_define_module_function(rb_mProcess, "waitall", proc_waitall, 0);
75177519
rb_define_module_function(rb_mProcess, "detach", proc_detach, 1);
75187520

7521+
rb_cWaiter = rb_define_class_under(rb_mProcess, "Waiter", rb_cThread);
7522+
rb_undef_alloc_func(rb_cWaiter);
7523+
rb_undef_method(CLASS_OF(rb_cWaiter), "new");
7524+
rb_define_method(rb_cWaiter, "pid", detach_process_pid, 0);
7525+
75197526
rb_cProcessStatus = rb_define_class_under(rb_mProcess, "Status", rb_cObject);
75207527
rb_undef_method(CLASS_OF(rb_cProcessStatus), "new");
75217528

test/ruby/test_process.rb

+8
Original file line numberDiff line numberDiff line change
@@ -1965,4 +1965,12 @@ def test_deadlock_by_signal_at_forking
19651965
runner.close
19661966
end
19671967
end if defined?(fork)
1968+
1969+
def test_process_detach
1970+
pid = fork {}
1971+
th = Process.detach(pid)
1972+
assert_equal pid, th.pid
1973+
status = th.value
1974+
assert status.success?, status.inspect
1975+
end if defined?(fork)
19681976
end

0 commit comments

Comments
 (0)