Fix Window private file mapping unlink EACCES issue. (#9358)
* Don't return early. * Add missing `mapping` assignment. * Make debug logs conditional.
This commit is contained in:
parent
b1f67cf08e
commit
e5a4f757bd
18
io_buffer.c
18
io_buffer.c
@ -42,6 +42,8 @@ enum {
|
|||||||
|
|
||||||
// This is used to validate the flags given by the user.
|
// This is used to validate the flags given by the user.
|
||||||
RB_IO_BUFFER_FLAGS_MASK = RB_IO_BUFFER_EXTERNAL | RB_IO_BUFFER_INTERNAL | RB_IO_BUFFER_MAPPED | RB_IO_BUFFER_SHARED | RB_IO_BUFFER_LOCKED | RB_IO_BUFFER_PRIVATE | RB_IO_BUFFER_READONLY,
|
RB_IO_BUFFER_FLAGS_MASK = RB_IO_BUFFER_EXTERNAL | RB_IO_BUFFER_INTERNAL | RB_IO_BUFFER_MAPPED | RB_IO_BUFFER_SHARED | RB_IO_BUFFER_LOCKED | RB_IO_BUFFER_PRIVATE | RB_IO_BUFFER_READONLY,
|
||||||
|
|
||||||
|
RB_IO_BUFFER_DEBUG = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rb_io_buffer {
|
struct rb_io_buffer {
|
||||||
@ -113,6 +115,7 @@ io_buffer_map_file(struct rb_io_buffer *buffer, int descriptor, size_t size, rb_
|
|||||||
}
|
}
|
||||||
|
|
||||||
HANDLE mapping = CreateFileMapping(file, NULL, protect, 0, 0, NULL);
|
HANDLE mapping = CreateFileMapping(file, NULL, protect, 0, 0, NULL);
|
||||||
|
if (RB_IO_BUFFER_DEBUG) fprintf(stderr, "io_buffer_map_file:CreateFileMapping -> %p\n", mapping);
|
||||||
if (!mapping) rb_sys_fail("io_buffer_map_descriptor:CreateFileMapping");
|
if (!mapping) rb_sys_fail("io_buffer_map_descriptor:CreateFileMapping");
|
||||||
|
|
||||||
void *base = MapViewOfFile(mapping, access, (DWORD)(offset >> 32), (DWORD)(offset & 0xFFFFFFFF), size);
|
void *base = MapViewOfFile(mapping, access, (DWORD)(offset >> 32), (DWORD)(offset & 0xFFFFFFFF), size);
|
||||||
@ -213,9 +216,13 @@ io_buffer_initialize(VALUE self, struct rb_io_buffer *buffer, void *base, size_t
|
|||||||
buffer->size = size;
|
buffer->size = size;
|
||||||
buffer->flags = flags;
|
buffer->flags = flags;
|
||||||
RB_OBJ_WRITE(self, &buffer->source, source);
|
RB_OBJ_WRITE(self, &buffer->source, source);
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
buffer->mapping = NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
io_buffer_free(struct rb_io_buffer *buffer)
|
io_buffer_free(struct rb_io_buffer *buffer)
|
||||||
{
|
{
|
||||||
if (buffer->base) {
|
if (buffer->base) {
|
||||||
@ -247,18 +254,17 @@ io_buffer_free(struct rb_io_buffer *buffer)
|
|||||||
buffer->size = 0;
|
buffer->size = 0;
|
||||||
buffer->flags = 0;
|
buffer->flags = 0;
|
||||||
buffer->source = Qnil;
|
buffer->source = Qnil;
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
if (buffer->mapping) {
|
if (buffer->mapping) {
|
||||||
CloseHandle(buffer->mapping);
|
if (RB_IO_BUFFER_DEBUG) fprintf(stderr, "io_buffer_free:CloseHandle -> %p\n", buffer->mapping);
|
||||||
|
if (!CloseHandle(buffer->mapping)) {
|
||||||
|
fprintf(stderr, "io_buffer_free:GetLastError -> %d\n", GetLastError());
|
||||||
|
}
|
||||||
buffer->mapping = NULL;
|
buffer->mapping = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -521,10 +521,7 @@ class TestIOBuffer < Test::Unit::TestCase
|
|||||||
def test_private
|
def test_private
|
||||||
Tempfile.create(%w"buffer .txt") do |file|
|
Tempfile.create(%w"buffer .txt") do |file|
|
||||||
file.write("Hello World")
|
file.write("Hello World")
|
||||||
file.close
|
|
||||||
assert_separately(["-W0", "-", file.path], "#{<<-"begin;"}\n#{<<-'end;'}")
|
|
||||||
begin;
|
|
||||||
file = File.open(ARGV[0], "r+")
|
|
||||||
buffer = IO::Buffer.map(file, nil, 0, IO::Buffer::PRIVATE)
|
buffer = IO::Buffer.map(file, nil, 0, IO::Buffer::PRIVATE)
|
||||||
begin
|
begin
|
||||||
assert buffer.private?
|
assert buffer.private?
|
||||||
@ -538,7 +535,6 @@ class TestIOBuffer < Test::Unit::TestCase
|
|||||||
ensure
|
ensure
|
||||||
buffer&.free
|
buffer&.free
|
||||||
end
|
end
|
||||||
end;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user