Bug #8616

Process.daemon messes up threads

Added by Aaron Patterson 9 months ago. Updated 3 months ago.

[ruby-core:55886]
Status:Closed
Priority:Normal
Assignee:-
Category:-
Target version:-
ruby -v:ruby 2.1.0dev (2013-07-10 trunk 41870) [x86_64-darwin12.4.0] Backport:1.9.3: DONE, 2.0.0: DONE

Description

=begin
Hi,

When I daemonize a process, it somehow messes up threads from the parent process. Here is a script to reproduce the problem:

r1, w1 = IO.pipe
r2, w2 = IO.pipe

t = Thread.new {
puts "start"
w1.write "x"
IO.select([r2])
puts "alive"
}

IO.select([r1])
Process.daemon true, true # comment this line out and everything works
puts Process.pid
w2.write "x"
t.join
puts "done"

If you run this program, there will be a ruby process in the background that never dies. If you comment out the "Process.daemon" line, the script finishes.
=end

History

#1 Updated by Akira Tanaka 9 months ago

2013/7/10 tenderlovemaking (Aaron Patterson) aaron@tenderlovemaking.com:

Bug #8616: Process.daemon messes up threads
https://bugs.ruby-lang.org/issues/8616

Process.daemon cannot preserve threads because
it uses fork and fork doesn't copy other threads.

Maybe, Process.daemon should raise an exception when
multi threads.

#2 Updated by Evan Phoenix 9 months ago

No, it shouldn't raise an exception. Process.daemon and fork both use
after_fork() in C. That function should iterate all the threads and mark
them as KILLED since they are all dead.

On Tue, Jul 9, 2013 at 6:14 PM, Tanaka Akira akr@fsij.org wrote:

2013/7/10 tenderlovemaking (Aaron Patterson) aaron@tenderlovemaking.com:

Bug #8616: Process.daemon messes up threads
https://bugs.ruby-lang.org/issues/8616

Process.daemon cannot preserve threads because
it uses fork and fork doesn't copy other threads.

Maybe, Process.daemon should raise an exception when
multi threads.

#3 Updated by Ben Weintraub 7 months ago

I agree with Evan. The behavior he describes would be consistent with how threads are handled when a process forks via Process.fork in Ruby.

See this example for a demonstration: https://gist.github.com/benweint/6692546

#4 Updated by Ben Weintraub 7 months ago

Actually, it looks like this is fixed in Ruby 2.1.0-preview1 (Thread#alive? returns false for background threads spawned before a call to Process.daemon), but still broken in 2.0.0-p247. Any chance of a backport?

#5 Updated by Ben Weintraub 7 months ago

FWIW, it looks like the relevant change that fixed it for 2.1.0-preview1 was https://github.com/ruby/ruby/commit/300b7c80e

#6 Updated by Tomoyuki Chikanaga 6 months ago

  • Backport changed from 1.9.3: UNKNOWN, 2.0.0: UNKNOWN to 1.9.3: UNKNOWN, 2.0.0: REQUIRED

I'll check r41910 to be backported later.

This ticket can be closed (for trunk)?

#7 Updated by Tomoyuki Chikanaga 6 months ago

  • Status changed from Open to Closed

I'll backport r41886, r41903 and r41910 to ruby20_0.

Thank you for your notice!

#8 Updated by Tomoyuki Chikanaga 6 months ago

  • Backport changed from 1.9.3: UNKNOWN, 2.0.0: REQUIRED to 1.9.3: UNKNOWN, 2.0.0: DONE

... and r40534 to resolve conflict.
merged r40534,r 41886 r41903, r41910 to ruby20_0 at r43142.

#9 Updated by Usaku NAKAMURA 3 months ago

  • Backport changed from 1.9.3: UNKNOWN, 2.0.0: DONE to 1.9.3: DONE, 2.0.0: DONE

backported into ruby19_3 at r44766.

Also available in: Atom PDF