From: kosaki.motohiro@... Date: 2015-10-17T21:38:27+00:00 Subject: [ruby-dev:49306] [Ruby trunk - Bug #11060] load(fifo) blocks whole process Issue #11060 has been updated by Motohiro KOSAKI. 修正メモ r50887 はakrパッチにあったS_ISFIFO()のチェックが入っていないため、FIFOがemptyじゃなくなるまで待つが、待った後エラーになってしまいロードできていませんでした。 FIFOから正常にロードできるテストが存在しないのがよくないので、当該テスト足しました。 また、rb_file_load_ok()を修正するのは論理的におかしくて、rb_file_load_ok()でロードできるかどうか一度チェックしてから一旦クローズ、 再度 load_file_internal()で開き直す処理のため、load_file_internal()を手当しないとrace conditionがありました。 r52139 は単に、load時のすべてのopenをO_NONBLOCK付きに変えていますが、挙動が変わってしまうためNGだと考えています。よって、一旦O_NONBLOCKで開いてからfcntl()で O_NONBLOCK取り消し、かつFIFOのときのみopenしなおしという論理にしました。開く前にstatせずに、一旦oepn(O_NONBLOCK)で開いてからfstatするのはrace対策。 ---------------------------------------- Bug #11060: load(fifo) blocks whole process https://bugs.ruby-lang.org/issues/11060#change-54469 * Author: Akira Tanaka * Status: Closed * Priority: Normal * Assignee: * ruby -v: ruby 2.3.0dev (2015-04-12 trunk 50257) [x86_64-linux] * Backport: 2.0.0: WONTFIX, 2.1: DONE, 2.2: DONE ---------------------------------------- fifo を load しようとすると、プロセス全体がブロックします。 以下では、0.1 秒毎に表示を行うスレッドを作っていますが、 0.5 秒後に load が呼ばれると表示が途切れます。 ``` % mkfifo fifo.rb % ls -l fifo.rb prw-r--r-- 1 akr akr 0 Apr 12 17:13 fifo.rb % ./ruby -ve 'Thread.new { 0.step {|i| p i; sleep 0.1 } }; sleep 0.5; load "fifo.rb"' ruby 2.3.0dev (2015-04-12 trunk 50257) [x86_64-linux] 0 1 2 3 4 ^C5 -e:1:in `new': Interrupt from -e:1:in `load' from -e:1:in `
' ``` 当然、timeout も効きません。 ``` % ./ruby -rtimeout -ve 'Thread.new { 0.step {|i| p i; sleep 0.1 } }; sleep 0.5; timeout(1) { load "fifo.rb" }' ruby 2.3.0dev (2015-04-12 trunk 50257) [x86_64-linux] 0 1 2 3 4 ^C5 -e:1:in `new': Interrupt from -e:1:in `load' from -e:1:in `block in
' from /home/ruby/tst1/lib/ruby/2.3.0/timeout.rb:89:in `block in timeout' from /home/ruby/tst1/lib/ruby/2.3.0/timeout.rb:34:in `block in catch' from /home/ruby/tst1/lib/ruby/2.3.0/timeout.rb:34:in `catch' from /home/ruby/tst1/lib/ruby/2.3.0/timeout.rb:34:in `catch' from /home/ruby/tst1/lib/ruby/2.3.0/timeout.rb:104:in `timeout' from /home/ruby/tst1/lib/ruby/2.3.0/timeout.rb:125:in `timeout' from -e:1:in `
' ``` この挙動をバグと考えるべきかどうかはいまひとつ確信が持てないのですが、 いまのところバグであってもおかしくないと思っています。 ---Files-------------------------------- 0001-file.c-load-now-supports-reading-from-a-FIFO-file.patch (3.26 KB) -- https://bugs.ruby-lang.org/