diff --git a/ext/-test-/win32/handle_count/depend b/ext/-test-/win32/handle_count/depend new file mode 100644 index 00000000000..798cac13470 --- /dev/null +++ b/ext/-test-/win32/handle_count/depend @@ -0,0 +1 @@ +handle_count.o: $(ruby_headers) $(hdrdir)/ruby/win32.h diff --git a/ext/-test-/win32/handle_count/extconf.rb b/ext/-test-/win32/handle_count/extconf.rb new file mode 100644 index 00000000000..75565a4741e --- /dev/null +++ b/ext/-test-/win32/handle_count/extconf.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: false +if $mingw or $mswin + create_makefile("-test-/win32/handle_count") +end diff --git a/ext/-test-/win32/handle_count/handle_count.c b/ext/-test-/win32/handle_count/handle_count.c new file mode 100644 index 00000000000..1759931bbd3 --- /dev/null +++ b/ext/-test-/win32/handle_count/handle_count.c @@ -0,0 +1,16 @@ +#include + +static VALUE +handle_count(VALUE self) +{ + DWORD count; + if (!GetProcessHandleCount(GetCurrentProcess(), &count)) rb_sys_fail("GetProcessHandleCount"); + return ULONG2NUM(count); +} + +void +Init_handle_count(void) +{ + VALUE m = rb_define_module_under(rb_define_module("Bug"), "Win32"); + rb_define_module_function(m, "handle_count", handle_count, 0); +} diff --git a/test/-ext-/win32/test_handle_count.rb b/test/-ext-/win32/test_handle_count.rb new file mode 100644 index 00000000000..a5632e01afc --- /dev/null +++ b/test/-ext-/win32/test_handle_count.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: false +require 'test/unit' + +module Bug + module Win32 + class TestHandleCount < Test::Unit::TestCase + def test_read_nonblock_on_empty_pipe + require '-test-/win32/handle_count' + IO.pipe do |r, w| + r.read_nonblock(1, exception: false) + before = Bug::Win32.handle_count + 1000.times {r.read_nonblock(1, exception: false)} + assert_operator(Bug::Win32.handle_count - before, :<, 100) + end + end + end + end +end if /mswin|mingw/ =~ RUBY_PLATFORM diff --git a/win32/win32.c b/win32/win32.c index 163e98e46a9..47017cac810 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -7433,6 +7433,7 @@ rb_w32_read_internal(int fd, void *buf, size_t size, rb_off_t *offset) err = GetLastError(); if (err == ERROR_NO_DATA && (_osfile(fd) & FPIPE)) { DWORD state; + CloseHandle(ol.hEvent); if (GetNamedPipeHandleState((HANDLE)_osfhnd(fd), &state, NULL, NULL, NULL, NULL, 0) && (state & PIPE_NOWAIT)) { errno = EWOULDBLOCK; }