Skip to content

Commit ae0ff08

Browse files
committed
[IO] Add IREE_IO_FILE_MODE_SHARE_READ to internal read-only callers
On Windows, opening the same file for reading from multiple places fails with ERROR_SHARING_VIOLATION. Fix internal callers to pass IREE_IO_FILE_MODE_SHARE_READ when opening files for reading. Fixed callers: - file_contents.c: iree_io_file_contents_read, iree_io_file_contents_map - parameter_util.c: parameter file loading (preload and mmap modes) Add a test that opens the same file twice for reading concurrently, validating the fix on all platforms. Signed-off-by: Jorn <jorn.tuyls@gmail.com>
1 parent 9c65a28 commit ae0ff08

File tree

3 files changed

+46
-7
lines changed

3 files changed

+46
-7
lines changed

runtime/src/iree/io/file_contents.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,9 @@ IREE_API_EXPORT iree_status_t iree_io_file_contents_read(
213213
// Open the file for reading.
214214
iree_io_file_handle_t* handle = NULL;
215215
IREE_RETURN_AND_END_ZONE_IF_ERROR(
216-
z0, iree_io_file_handle_open(IREE_IO_FILE_MODE_READ, path, host_allocator,
217-
&handle));
216+
z0, iree_io_file_handle_open(
217+
IREE_IO_FILE_MODE_READ | IREE_IO_FILE_MODE_SHARE_READ, path,
218+
host_allocator, &handle));
218219

219220
// Get an stdio FILE* for the handle.
220221
// This will need to be closed as its lifetime is separate from our file
@@ -300,7 +301,8 @@ IREE_API_EXPORT iree_status_t iree_io_file_contents_map(
300301
*out_contents = NULL;
301302
IREE_TRACE_ZONE_BEGIN(z0);
302303

303-
iree_io_file_mode_t mode = IREE_IO_FILE_MODE_READ;
304+
iree_io_file_mode_t mode =
305+
IREE_IO_FILE_MODE_READ | IREE_IO_FILE_MODE_SHARE_READ;
304306
if (iree_all_bits_set(access, IREE_IO_FILE_ACCESS_WRITE)) {
305307
mode |= IREE_IO_FILE_MODE_WRITE;
306308
}

runtime/src/iree/io/file_contents_test.cc

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,41 @@ TEST(FileContents, ReadWriteContentsMmap) {
130130
iree_io_file_contents_free(read_contents);
131131
}
132132

133+
// Tests that a file opened for reading can be opened again concurrently.
134+
// Validates FILE_SHARE_READ behavior on Windows — without it, the second
135+
// open fails with ERROR_SHARING_VIOLATION.
136+
TEST(FileContents, ConcurrentReadOpens) {
137+
constexpr const char* kUniqueName = "ConcurrentReadOpens";
138+
auto path = GetUniquePath(kUniqueName);
139+
140+
// Write a file to open.
141+
auto contents = GetUniqueContents(kUniqueName, 4096);
142+
IREE_ASSERT_OK(iree_io_file_contents_write(
143+
iree_make_string_view(path.data(), path.size()),
144+
iree_make_const_byte_span(contents.data(), contents.size()),
145+
iree_allocator_system()));
146+
147+
// Open the file twice for reading — both should succeed.
148+
iree_io_file_contents_t* read1 = NULL;
149+
IREE_ASSERT_OK(iree_io_file_contents_map(
150+
iree_make_string_view(path.data(), path.size()), IREE_IO_FILE_ACCESS_READ,
151+
iree_allocator_system(), &read1));
152+
153+
iree_io_file_contents_t* read2 = NULL;
154+
IREE_ASSERT_OK(iree_io_file_contents_map(
155+
iree_make_string_view(path.data(), path.size()), IREE_IO_FILE_ACCESS_READ,
156+
iree_allocator_system(), &read2));
157+
158+
// Both should have the same contents.
159+
EXPECT_EQ(read1->const_buffer.data_length, read2->const_buffer.data_length);
160+
EXPECT_EQ(memcmp(read1->const_buffer.data, read2->const_buffer.data,
161+
read1->const_buffer.data_length),
162+
0);
163+
164+
iree_io_file_contents_free(read2);
165+
iree_io_file_contents_free(read1);
166+
}
167+
133168
} // namespace
134169
} // namespace io
135170
} // namespace iree

runtime/src/iree/tooling/parameter_util.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ static iree_status_t iree_io_open_parameter_file(
3737
iree_status_t status = iree_ok_status();
3838
iree_io_file_handle_t* file_handle = NULL;
3939
if (strcmp(FLAG_parameter_mode, "preload") == 0) {
40-
status = iree_io_file_handle_preload(IREE_IO_FILE_MODE_READ, path,
41-
host_allocator, &file_handle);
40+
status = iree_io_file_handle_preload(
41+
IREE_IO_FILE_MODE_READ | IREE_IO_FILE_MODE_SHARE_READ, path,
42+
host_allocator, &file_handle);
4243
} else if (strcmp(FLAG_parameter_mode, "file") == 0) {
43-
status = iree_io_file_handle_open(IREE_IO_FILE_MODE_READ, path,
44-
host_allocator, &file_handle);
44+
status = iree_io_file_handle_open(
45+
IREE_IO_FILE_MODE_READ | IREE_IO_FILE_MODE_SHARE_READ, path,
46+
host_allocator, &file_handle);
4547
} else {
4648
status = iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
4749
"unrecognized --parameter_mode= value '%s'",

0 commit comments

Comments
 (0)