Forum: Ruby-core [ruby-trunk - Bug #7720][Open] Process.daemon does not clean up background Ruby threads, leading to

Posted by benweint (Ben Weintraub) (Guest)
on 2013-01-21 18:33
(Received via mailing list)
Issue #7720 has been reported by benweint (Ben Weintraub).

----------------------------------------
Bug #7720: Process.daemon does not clean up background Ruby threads, 
leading to hang at exit
https://bugs.ruby-lang.org/issues/7720

Author: benweint (Ben Weintraub)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:
ruby -v: ruby 1.9.3p327 (2012-11-10 revision 37606) 
[x86_64-darwin12.2.0]


Process.fork appears to make special considerations for Ruby background 
threads so that they are cleaned up in the child process after fork 
(since fork() only duplicates the calling thread). Process.daemon also 
relies on fork internally, but does not make the same considerations, 
leading to a hang at exit in a daemonized process that had multiple Ruby 
threads prior to calling Process.daemon.

The attached daemon.rb demonstrates the issue. It will call either 
Process.daemon (default) or Process.fork (if you pass 'fork' as the 
first arg).

If you pass nothing, causing it to call Process.daemon, the daemonized 
Ruby process will still think it has two threads, and will hang 
indefinitely on exit, in a loop in rb_thread_terminate_all. If you pass 
'fork' as the first argument, the forked child does not hang, and 
appears to have only one Ruby thread (the one that called Process.fork).

It looks like rb_thread_atfork() is the relevant call in the fork case 
that makes this work, but it doesn't appear to be called in the daemon 
case.
Posted by samg (Sam Goldstein) (Guest)
on 2013-01-23 02:49
(Received via mailing list)
Issue #7720 has been updated by samg (Sam Goldstein).


This seems to be the underlying cause of the bad interaction between 
resque and new relic described at 
https://github.com/defunkt/resque/issues/578
----------------------------------------
Bug #7720: Process.daemon does not clean up background Ruby threads, 
leading to hang at exit
https://bugs.ruby-lang.org/issues/7720#change-35535

Author: benweint (Ben Weintraub)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:
ruby -v: ruby 1.9.3p327 (2012-11-10 revision 37606) 
[x86_64-darwin12.2.0]


Process.fork appears to make special considerations for Ruby background 
threads so that they are cleaned up in the child process after fork 
(since fork() only duplicates the calling thread). Process.daemon also 
relies on fork internally, but does not make the same considerations, 
leading to a hang at exit in a daemonized process that had multiple Ruby 
threads prior to calling Process.daemon.

The attached daemon.rb demonstrates the issue. It will call either 
Process.daemon (default) or Process.fork (if you pass 'fork' as the 
first arg).

If you pass nothing, causing it to call Process.daemon, the daemonized 
Ruby process will still think it has two threads, and will hang 
indefinitely on exit, in a loop in rb_thread_terminate_all. If you pass 
'fork' as the first argument, the forked child does not hang, and 
appears to have only one Ruby thread (the one that called Process.fork).

It looks like rb_thread_atfork() is the relevant call in the fork case 
that makes this work, but it doesn't appear to be called in the daemon 
case.
Posted by ko1 (Koichi Sasada) (Guest)
on 2013-01-25 04:08
(Received via mailing list)
Issue #7720 has been updated by ko1 (Koichi Sasada).


Does this issue remain on trunk?
(Should we modify trunk before 2.0?)

----------------------------------------
Bug #7720: Process.daemon does not clean up background Ruby threads, 
leading to hang at exit
https://bugs.ruby-lang.org/issues/7720#change-35593

Author: benweint (Ben Weintraub)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:
ruby -v: ruby 1.9.3p327 (2012-11-10 revision 37606) 
[x86_64-darwin12.2.0]


Process.fork appears to make special considerations for Ruby background 
threads so that they are cleaned up in the child process after fork 
(since fork() only duplicates the calling thread). Process.daemon also 
relies on fork internally, but does not make the same considerations, 
leading to a hang at exit in a daemonized process that had multiple Ruby 
threads prior to calling Process.daemon.

The attached daemon.rb demonstrates the issue. It will call either 
Process.daemon (default) or Process.fork (if you pass 'fork' as the 
first arg).

If you pass nothing, causing it to call Process.daemon, the daemonized 
Ruby process will still think it has two threads, and will hang 
indefinitely on exit, in a loop in rb_thread_terminate_all. If you pass 
'fork' as the first argument, the forked child does not hang, and 
appears to have only one Ruby thread (the one that called Process.fork).

It looks like rb_thread_atfork() is the relevant call in the fork case 
that makes this work, but it doesn't appear to be called in the daemon 
case.
Posted by kosaki (Motohiro KOSAKI) (Guest)
on 2013-01-25 17:44
(Received via mailing list)
Issue #7720 has been updated by kosaki (Motohiro KOSAKI).


trunk doesn't have an issue. fork and daemon make the same result.

----------------------------------------
Bug #7720: Process.daemon does not clean up background Ruby threads, 
leading to hang at exit
https://bugs.ruby-lang.org/issues/7720#change-35636

Author: benweint (Ben Weintraub)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:
ruby -v: ruby 1.9.3p327 (2012-11-10 revision 37606) 
[x86_64-darwin12.2.0]


Process.fork appears to make special considerations for Ruby background 
threads so that they are cleaned up in the child process after fork 
(since fork() only duplicates the calling thread). Process.daemon also 
relies on fork internally, but does not make the same considerations, 
leading to a hang at exit in a daemonized process that had multiple Ruby 
threads prior to calling Process.daemon.

The attached daemon.rb demonstrates the issue. It will call either 
Process.daemon (default) or Process.fork (if you pass 'fork' as the 
first arg).

If you pass nothing, causing it to call Process.daemon, the daemonized 
Ruby process will still think it has two threads, and will hang 
indefinitely on exit, in a loop in rb_thread_terminate_all. If you pass 
'fork' as the first argument, the forked child does not hang, and 
appears to have only one Ruby thread (the one that called Process.fork).

It looks like rb_thread_atfork() is the relevant call in the fork case 
that makes this work, but it doesn't appear to be called in the daemon 
case.
Posted by usa (Usaku NAKAMURA) (Guest)
on 2013-01-30 10:45
(Received via mailing list)
Issue #7720 has been updated by usa (Usaku NAKAMURA).

Status changed from Open to Assigned
Assignee set to usa (Usaku NAKAMURA)

So, what's the difference?
----------------------------------------
Bug #7720: Process.daemon does not clean up background Ruby threads, 
leading to hang at exit
https://bugs.ruby-lang.org/issues/7720#change-35726

Author: benweint (Ben Weintraub)
Status: Assigned
Priority: Normal
Assignee: usa (Usaku NAKAMURA)
Category:
Target version:
ruby -v: ruby 1.9.3p327 (2012-11-10 revision 37606) 
[x86_64-darwin12.2.0]


Process.fork appears to make special considerations for Ruby background 
threads so that they are cleaned up in the child process after fork 
(since fork() only duplicates the calling thread). Process.daemon also 
relies on fork internally, but does not make the same considerations, 
leading to a hang at exit in a daemonized process that had multiple Ruby 
threads prior to calling Process.daemon.

The attached daemon.rb demonstrates the issue. It will call either 
Process.daemon (default) or Process.fork (if you pass 'fork' as the 
first arg).

If you pass nothing, causing it to call Process.daemon, the daemonized 
Ruby process will still think it has two threads, and will hang 
indefinitely on exit, in a loop in rb_thread_terminate_all. If you pass 
'fork' as the first argument, the forked child does not hang, and 
appears to have only one Ruby thread (the one that called Process.fork).

It looks like rb_thread_atfork() is the relevant call in the fork case 
that makes this work, but it doesn't appear to be called in the daemon 
case.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.