Bug #5812

test-all is stuck on Windows

Added by Usaku NAKAMURA over 3 years ago. Updated about 3 years ago.

[ruby-dev:45051]
Status:Closed
Priority:Normal
Assignee:Usaku NAKAMURA
ruby -v:ruby 2.0.0dev (2011-12-26 trunk 34131) [x64-mswin64_100] Backport:

Description

以下の2つのテストがWindowsで刺さります。
test/ruby/test_thread.rb TestThreadGroup#test_thread_timer_and_interrupt
test/thread/test_queue.rb TestQueue#test_thr_kill

要するにIO#read中にThread#killしても終わらないことがあるというわけですが、
しばらく頑張ってみたものの(thread_pthread.cからsignal_thread_listの仕組みを
持ってきてみるとか)修正できていないので、忘れないようにチケット化しておきます。
このままだと越年コース。

ちなみにtrunkのみならず1.9系全般で起きています。
今までテストがなかったのがいけないんですな。

thread_signal.patch Magnifier (3.85 KB) Hiroshi Shirosaki, 01/23/2012 11:47 AM

Associated revisions

Revision 34387
Added by shirosaki about 3 years ago

  • test/zlib/test_zlib.rb (TestZlibGzipReader#test_reader_wrap): set binmode explicitly for fixing test error on Windows. This is consistent with r34243. [Bug #5812]

Revision 34387
Added by shirosaki about 3 years ago

  • test/zlib/test_zlib.rb (TestZlibGzipReader#test_reader_wrap): set binmode explicitly for fixing test error on Windows. This is consistent with r34243. [Bug #5812]

Revision 34388
Added by shirosaki about 3 years ago

  • thread_win32.c (rb_w32_wait_events_blocking): use
    ruby_thread_from_native() instead of GET_THREAD() because
    GET_THREAD() doesn't always return the current thread and
    WaitForMultipleObjects() at rb_w32_read() doesn't return by
    Thread#kill. This fixes TestQueue#test_thr_kill failure on
    Windows.

  • thread_win32.c (rb_w32_wait_events): use ruby_thread_from_native()
    instead of GET_THREAD() for consistency with the above change.

  • thread_win32.c (rb_w32_sleep): ditto.

  • thread_win32.c (rb_w32_Sleep): ditto.
    [Bug #5812]

Revision 34388
Added by shirosaki about 3 years ago

  • thread_win32.c (rb_w32_wait_events_blocking): use
    ruby_thread_from_native() instead of GET_THREAD() because
    GET_THREAD() doesn't always return the current thread and
    WaitForMultipleObjects() at rb_w32_read() doesn't return by
    Thread#kill. This fixes TestQueue#test_thr_kill failure on
    Windows.

  • thread_win32.c (rb_w32_wait_events): use ruby_thread_from_native()
    instead of GET_THREAD() for consistency with the above change.

  • thread_win32.c (rb_w32_sleep): ditto.

  • thread_win32.c (rb_w32_Sleep): ditto.
    [Bug #5812]

Revision 34389
Added by shirosaki about 3 years ago

  • test/ruby/test_thread.rb
    (TestThreadGroup#test_thread_timer_and_interrupt): skip exit status
    assertion because we cannot get signal status on Windows.

  • win32/win32.c (CreateChild): create process group to receive the
    signal by GenerateConsoleCtrlEvent().

  • win32/win32.c (kill): use CTRL_BREAK_EVENT instead of CTRL_C_EVENT
    if a process group is specified. CTRL_C_EVENT signal cannot be
    generated for process groups for the specification.
    [Bug #5812]

Revision 34389
Added by shirosaki about 3 years ago

  • test/ruby/test_thread.rb
    (TestThreadGroup#test_thread_timer_and_interrupt): skip exit status
    assertion because we cannot get signal status on Windows.

  • win32/win32.c (CreateChild): create process group to receive the
    signal by GenerateConsoleCtrlEvent().

  • win32/win32.c (kill): use CTRL_BREAK_EVENT instead of CTRL_C_EVENT
    if a process group is specified. CTRL_C_EVENT signal cannot be
    generated for process groups for the specification.
    [Bug #5812]

Revision 34390
Added by shirosaki about 3 years ago

  • win32/win32.c (rb_w32_read): fix an issue that $stdin.read doesn't terminate by CTRL-C on Windows. [Bug #5812]

Revision 34390
Added by shirosaki about 3 years ago

  • win32/win32.c (rb_w32_read): fix an issue that $stdin.read doesn't terminate by CTRL-C on Windows. [Bug #5812]

History

#1 Updated by Hiroshi Shirosaki over 3 years ago

Windowsのtest-allのパッチを作ってみました。検討をお願いします。

  • TestThreadGroup#test_thread_timer_and_interrupt GenerateConsoleCtrlEventのCTRL_C_EVENTで0でないprocess groupを指定した場合は、CTRL+C signalは無視されるようです。

http://msdn.microsoft.com/en-us/library/windows/desktop/ms683155%28v=vs.85%29.aspx
Generates a CTRL+C signal. This signal cannot be generated for process groups. If dwProcessGroupId is nonzero, this function will succeed, but the CTRL+C signal will not be received by processes within the specified process group.

かわりに、CTRL_BREAK_EVENTにして、process groupを指定するようにしました。
CTRL_BREAK_EVENTもSIGINTに対応するのではないかというコメントがありました。
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/18096

s.exited?, s.signaled?, s.stopped? は、windowsではunixのように取れないようなので、その部分のテストを修正しました。

http://bugs.ruby-lang.org/projects/ruby-trunk/repository/entry/win32/win32.c#L3893
if (stat_loc) *stat_loc = exitcode << 8;

statusの下位8bitは常に0になるように見えます。

  • TestQueue#test_thr_kill
    Thread.newの中のreadのrb_w32_wait_events_blockingを実行した時、GET_THREAD()でmain threadが取れることがあります。
    そのため、killに反応しないようです。
    かわりにruby_thread_from_native()を使った場合は、うまく動作しました。
    他のGET_THREAD()もruby_thread_from_native()に変えてみました。

  • ruby -e '$stdin.read'としたとき、CTRL-Cを押してもrubyが終了しません。
    CTRL-Cを2回押すか、CTRL-C + Enterだと終了します。
    これはテストにはないのですが、test_thread_timer_and_interruptと関連するのではないかと思います。

CTRL-Cを押したとき、ReadFileのエラーで、ERROR_OPERATION_ABORTEDになるので、そのときはretryしないようにしました。

trunkにこのパッチを当てて、mingw on Windows7でmake test, make test-allを確認しました。
make testは成功、make test-allのエラーは増えていませんでした。

#2 Updated by Usaku NAKAMURA about 3 years ago

すばらしい!
commitしてください。

#3 Updated by Anonymous about 3 years ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r34387.
Usaku, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • test/zlib/test_zlib.rb (TestZlibGzipReader#test_reader_wrap): set binmode explicitly for fixing test error on Windows. This is consistent with r34243. [Bug #5812]

Also available in: Atom PDF