Skip to content

Commit bf35e14

Browse files
committed
Fix new specs for rb_io_maybe_wait_writable and rb_io_maybe_wait on Windows
1 parent c884c42 commit bf35e14

1 file changed

Lines changed: 94 additions & 24 deletions

File tree

optional/capi/io_spec.rb

Lines changed: 94 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -355,23 +355,58 @@
355355
end
356356
end
357357

358-
it "can be interrupted" do
359-
IOSpec.exhaust_write_buffer(@w_io)
360-
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
358+
platform_is_not :windows do
359+
it "can be interrupted" do
360+
IOSpec.exhaust_write_buffer(@w_io)
361+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
361362

362-
t = Thread.new do
363-
@o.rb_io_maybe_wait_writable(Errno::EAGAIN::Errno, @w_io, 10)
363+
t = Thread.new do
364+
@o.rb_io_maybe_wait_writable(Errno::EAGAIN::Errno, @w_io, 10)
364365

365-
# ensure the call was blocking and was really interrupted
366-
flunk "not reached"
366+
# ensure the call was blocking and was really interrupted
367+
flunk "not reached"
368+
end
369+
370+
Thread.pass until t.stop?
371+
t.kill
372+
t.join
373+
374+
finish = Process.clock_gettime(Process::CLOCK_MONOTONIC)
375+
(finish - start).should < 9
367376
end
377+
end
368378

369-
Thread.pass until t.stop?
370-
t.kill
371-
t.join
379+
platform_is :windows do
380+
# Windows select/poll wrapper (rb_w32_select) treats write descriptors of non-sockets
381+
# (such as pipe writers) as always writable. Thus it immediately returns IO::WRITABLE
382+
# instead of timing out or blocking. So use sockets instead.
383+
it "can be interrupted" do
384+
require 'socket'
385+
r_sock, w_sock = Socket.pair(Socket::AF_INET, Socket::SOCK_STREAM, 0)
386+
begin
387+
r_sock.close_write
388+
w_sock.close_read
389+
IOSpec.exhaust_write_buffer(w_sock)
390+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
391+
392+
t = Thread.new do
393+
@o.rb_io_maybe_wait_writable(Errno::EAGAIN::Errno, w_sock, 10)
394+
395+
# ensure the call was blocking and was really interrupted
396+
flunk "not reached"
397+
end
372398

373-
finish = Process.clock_gettime(Process::CLOCK_MONOTONIC)
374-
(finish - start).should < 9
399+
Thread.pass until t.stop?
400+
t.kill
401+
t.join
402+
403+
finish = Process.clock_gettime(Process::CLOCK_MONOTONIC)
404+
(finish - start).should < 9
405+
ensure
406+
r_sock.close unless r_sock.closed?
407+
w_sock.close unless w_sock.closed?
408+
end
409+
end
375410
end
376411
end
377412

@@ -573,23 +608,58 @@
573608
(finish - start).should < 9
574609
end
575610

576-
it "can be interrupted when waiting for WRITABLE event" do
577-
IOSpec.exhaust_write_buffer(@w_io)
578-
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
611+
platform_is_not :windows do
612+
it "can be interrupted when waiting for WRITABLE event" do
613+
IOSpec.exhaust_write_buffer(@w_io)
614+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
579615

580-
t = Thread.new do
581-
@o.rb_io_maybe_wait(Errno::EAGAIN::Errno, @w_io, IO::WRITABLE, 10)
616+
t = Thread.new do
617+
@o.rb_io_maybe_wait(Errno::EAGAIN::Errno, @w_io, IO::WRITABLE, 10)
582618

583-
# ensure the call was blocking and was really interrupted
584-
flunk "not reached"
619+
# ensure the call was blocking and was really interrupted
620+
flunk "not reached"
621+
end
622+
623+
Thread.pass until t.stop?
624+
t.kill
625+
t.join
626+
627+
finish = Process.clock_gettime(Process::CLOCK_MONOTONIC)
628+
(finish - start).should < 9
585629
end
630+
end
586631

587-
Thread.pass until t.stop?
588-
t.kill
589-
t.join
632+
platform_is :windows do
633+
# Windows select/poll wrapper (rb_w32_select) treats write descriptors of non-sockets
634+
# (such as pipe writers) as always writable. Thus it immediately returns IO::WRITABLE
635+
# instead of timing out or blocking. So use sockets instead.
636+
it "can be interrupted when waiting for WRITABLE event" do
637+
require 'socket'
638+
r_sock, w_sock = Socket.pair(Socket::AF_INET, Socket::SOCK_STREAM, 0)
639+
begin
640+
r_sock.close_write
641+
w_sock.close_read
642+
IOSpec.exhaust_write_buffer(w_sock)
643+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
590644

591-
finish = Process.clock_gettime(Process::CLOCK_MONOTONIC)
592-
(finish - start).should < 9
645+
t = Thread.new do
646+
@o.rb_io_maybe_wait(Errno::EAGAIN::Errno, w_sock, IO::WRITABLE, 10)
647+
648+
# ensure the call was blocking and was really interrupted
649+
flunk "not reached"
650+
end
651+
652+
Thread.pass until t.stop?
653+
t.kill
654+
t.join
655+
656+
finish = Process.clock_gettime(Process::CLOCK_MONOTONIC)
657+
(finish - start).should < 9
658+
ensure
659+
r_sock.close unless r_sock.closed?
660+
w_sock.close unless w_sock.closed?
661+
end
662+
end
593663
end
594664
end
595665

0 commit comments

Comments
 (0)