Fix "runs a C function with the global lock unlocked and unlocks IO with the generic RUBY_UBF_IO" on Windows. (#7848)

* Enable borked spec.

* Ensure win32 wrappers are visible and used.

* Reorganise `read`/`write`/`pipe` in `thread_spec.c`.
This commit is contained in:
Samuel Williams 2023-05-24 22:45:34 +09:00 committed by GitHub
parent 85b4cd7cf8
commit 6d976eb534
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
Notes: git 2023-05-24 13:45:55 +00:00
Merged-By: ioquatix <samuel@codeotaku.com>
4 changed files with 46 additions and 32 deletions

View File

@ -148,8 +148,8 @@ typedef int clockid_t;
#define close(h) rb_w32_close(h)
#define fclose(f) rb_w32_fclose(f)
#define read(f, b, s) rb_w32_read(f, b, s, NULL)
#define write(f, b, s) rb_w32_write(f, b, s, NULL)
#define read(f, b, s) rb_w32_read(f, b, s)
#define write(f, b, s) rb_w32_write(f, b, s)
#define HAVE_PREAD
#define pread(f, b, s, o) rb_w32_pread(f, b, s, o)
@ -722,8 +722,8 @@ int rb_w32_wopen(const WCHAR *, int, ...);
int rb_w32_close(int);
int rb_w32_fclose(FILE*);
int rb_w32_pipe(int[2]);
ssize_t rb_w32_read(int, void *, size_t, rb_off_t *offset);
ssize_t rb_w32_write(int, const void *, size_t, rb_off_t *offset);
ssize_t rb_w32_read(int, void *, size_t);
ssize_t rb_w32_write(int, const void *, size_t);
ssize_t rb_w32_pread(int, void *, size_t, rb_off_t offset);
ssize_t rb_w32_pwrite(int, const void *, size_t, rb_off_t offset);
rb_off_t rb_w32_lseek(int, rb_off_t, int);

View File

@ -8,7 +8,10 @@
#include <unistd.h>
#endif
#if defined(_WIN32)
#define pipe(p) rb_w32_pipe(p)
#include "ruby/win32.h"
#define read rb_w32_read
#define write rb_w32_write
#define pipe rb_w32_pipe
#endif
#ifndef _WIN32

View File

@ -165,26 +165,23 @@ describe "C-API Thread function" do
end
end
# This test is disabled on Windows: https://bugs.ruby-lang.org/issues/16265
platform_is_not :mingw, :windows do
it "runs a C function with the global lock unlocked and unlocks IO with the generic RUBY_UBF_IO" do
thr = Thread.new do
@t.rb_thread_call_without_gvl_with_ubf_io
end
# Wait until it's blocking...
Thread.pass until thr.stop?
# The thread status is set to sleep by rb_thread_call_without_gvl(),
# but the thread might not be in the blocking read(2) yet, so wait a bit.
sleep 0.1
# Wake it up, causing the unblock function to be run.
thr.wakeup
# Make sure it stopped and we got a proper value
thr.value.should be_true
it "runs a C function with the global lock unlocked and unlocks IO with the generic RUBY_UBF_IO" do
thr = Thread.new do
@t.rb_thread_call_without_gvl_with_ubf_io
end
# Wait until it's blocking...
Thread.pass until thr.stop?
# The thread status is set to sleep by rb_thread_call_without_gvl(),
# but the thread might not be in the blocking read(2) yet, so wait a bit.
sleep 0.1
# Wake it up, causing the unblock function to be run.
thr.wakeup
# Make sure it stopped and we got a proper value
thr.value.should be_true
end
end
end

View File

@ -7265,8 +7265,8 @@ finish_overlapped(OVERLAPPED *ol, int fd, DWORD size, rb_off_t *_offset)
#undef read
/* License: Ruby's */
ssize_t
rb_w32_read(int fd, void *buf, size_t size, rb_off_t *offset)
static ssize_t
rb_w32_read_internal(int fd, void *buf, size_t size, rb_off_t *offset)
{
SOCKET sock = TO_SOCKET(fd);
DWORD read;
@ -7404,8 +7404,8 @@ rb_w32_read(int fd, void *buf, size_t size, rb_off_t *offset)
#undef write
/* License: Ruby's */
ssize_t
rb_w32_write(int fd, const void *buf, size_t size, rb_off_t *offset)
static ssize_t
rb_w32_write_internal(int fd, const void *buf, size_t size, rb_off_t *offset)
{
SOCKET sock = TO_SOCKET(fd);
DWORD written;
@ -7510,14 +7510,28 @@ rb_w32_write(int fd, const void *buf, size_t size, rb_off_t *offset)
return ret;
}
ssize_t rb_w32_pread(int descriptor, void *base, size_t size, rb_off_t offset)
ssize_t
rb_w32_read(int fd, void *buf, size_t size)
{
return rb_w32_read(descriptor, base, size, &offset);
return rb_w32_read_internal(fd, buf, size, NULL);
}
ssize_t rb_w32_pwrite(int descriptor, const void *base, size_t size, rb_off_t offset)
ssize_t
rb_w32_write(int fd, const void *buf, size_t size)
{
return rb_w32_write(descriptor, base, size, &offset);
return rb_w32_write_internal(fd, buf, size, NULL);
}
ssize_t
rb_w32_pread(int descriptor, void *base, size_t size, rb_off_t offset)
{
return rb_w32_read_internal(descriptor, base, size, &offset);
}
ssize_t
rb_w32_pwrite(int descriptor, const void *base, size_t size, rb_off_t offset)
{
return rb_w32_write_internal(descriptor, base, size, &offset);
}
/* License: Ruby's */