mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 08:25:20 +08:00
win32: Fix a handle leak in rb_w32_read_internal
One of its early returns after `setup_overlapped` did not close the event. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4cd0b82a1b
commit
764d1d3a73
5 files changed
+40
Notes:
git
2026-10-25 02:58:06 +00:00
No files matched your search
@@ -0,0 +1 @@
|
||||
handle_count.o: $(ruby_headers) $(hdrdir)/ruby/win32.h
|
||||
@@ -0,0 +1,4 @@
|
||||
# frozen_string_literal: false
|
||||
if $mingw or $mswin
|
||||
create_makefile("-test-/win32/handle_count")
|
||||
end
|
||||
@@ -0,0 +1,16 @@
|
||||
#include <ruby.h>
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user