forked from Mirrors/wine-wine
ntdll: Perform fsync() in client for files and directories.
Fixes stuttering in Assetto Corsa Competizione (multiplayer mode). Signed-off-by: Paul Gofman <pgofman@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>feature/deterministic
parent
39a585ef8c
commit
3078f10d43
|
@ -3584,7 +3584,15 @@ NTSTATUS WINAPI NtFlushBuffersFile( HANDLE hFile, IO_STATUS_BLOCK *io )
|
||||||
if (ret == STATUS_ACCESS_DENIED)
|
if (ret == STATUS_ACCESS_DENIED)
|
||||||
ret = unix_funcs->server_get_unix_fd( hFile, FILE_APPEND_DATA, &fd, &needs_close, &type, NULL );
|
ret = unix_funcs->server_get_unix_fd( hFile, FILE_APPEND_DATA, &fd, &needs_close, &type, NULL );
|
||||||
|
|
||||||
if (!ret && type == FD_TYPE_SERIAL)
|
if (!ret && (type == FD_TYPE_FILE || type == FD_TYPE_DIR))
|
||||||
|
{
|
||||||
|
if (fsync(fd))
|
||||||
|
ret = FILE_GetNtStatus();
|
||||||
|
|
||||||
|
io->u.Status = ret;
|
||||||
|
io->Information = 0;
|
||||||
|
}
|
||||||
|
else if (!ret && type == FD_TYPE_SERIAL)
|
||||||
{
|
{
|
||||||
ret = COMM_FlushBuffersFile( fd );
|
ret = COMM_FlushBuffersFile( fd );
|
||||||
}
|
}
|
||||||
|
|
|
@ -4860,14 +4860,26 @@ static void test_flush_buffers_file(void)
|
||||||
status = pNtFlushBuffersFile(hfile, (IO_STATUS_BLOCK *)0xdeadbeaf);
|
status = pNtFlushBuffersFile(hfile, (IO_STATUS_BLOCK *)0xdeadbeaf);
|
||||||
ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %#x.\n", status);
|
ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %#x.\n", status);
|
||||||
|
|
||||||
|
io_status_block.Information = 0xdeadbeef;
|
||||||
|
io_status_block.Status = 0xdeadbeef;
|
||||||
status = pNtFlushBuffersFile(hfile, &io_status_block);
|
status = pNtFlushBuffersFile(hfile, &io_status_block);
|
||||||
ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x.\n", status);
|
ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x.\n", status);
|
||||||
|
ok(io_status_block.Status == STATUS_SUCCESS, "Got unexpected io_status_block.Status %#x.\n",
|
||||||
|
io_status_block.Status);
|
||||||
|
ok(!io_status_block.Information, "Got unexpected io_status_block.Information %#lx.\n",
|
||||||
|
io_status_block.Information);
|
||||||
|
|
||||||
status = pNtFlushBuffersFile(hfileread, &io_status_block);
|
status = pNtFlushBuffersFile(hfileread, &io_status_block);
|
||||||
ok(status == STATUS_ACCESS_DENIED, "expected STATUS_ACCESS_DENIED, got %#x.\n", status);
|
ok(status == STATUS_ACCESS_DENIED, "expected STATUS_ACCESS_DENIED, got %#x.\n", status);
|
||||||
|
|
||||||
|
io_status_block.Information = 0xdeadbeef;
|
||||||
|
io_status_block.Status = 0xdeadbeef;
|
||||||
status = pNtFlushBuffersFile(NULL, &io_status_block);
|
status = pNtFlushBuffersFile(NULL, &io_status_block);
|
||||||
ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %#x.\n", status);
|
ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %#x.\n", status);
|
||||||
|
ok(io_status_block.Status == 0xdeadbeef, "Got unexpected io_status_block.Status %#x.\n",
|
||||||
|
io_status_block.Status);
|
||||||
|
ok(io_status_block.Information == 0xdeadbeef, "Got unexpected io_status_block.Information %#lx.\n",
|
||||||
|
io_status_block.Information);
|
||||||
|
|
||||||
CloseHandle(hfileread);
|
CloseHandle(hfileread);
|
||||||
CloseHandle(hfile);
|
CloseHandle(hfile);
|
||||||
|
@ -4878,6 +4890,15 @@ static void test_flush_buffers_file(void)
|
||||||
status = pNtFlushBuffersFile(hfile, &io_status_block);
|
status = pNtFlushBuffersFile(hfile, &io_status_block);
|
||||||
ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x.\n", status);
|
ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x.\n", status);
|
||||||
|
|
||||||
|
io_status_block.Information = 0xdeadbeef;
|
||||||
|
io_status_block.Status = 0xdeadbeef;
|
||||||
|
status = pNtFlushBuffersFile((HANDLE)0xdeadbeef, &io_status_block);
|
||||||
|
ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %#x.\n", status);
|
||||||
|
ok(io_status_block.Status == 0xdeadbeef, "Got unexpected io_status_block.Status %#x.\n",
|
||||||
|
io_status_block.Status);
|
||||||
|
ok(io_status_block.Information == 0xdeadbeef, "Got unexpected io_status_block.Information %#lx.\n",
|
||||||
|
io_status_block.Information);
|
||||||
|
|
||||||
CloseHandle(hfile);
|
CloseHandle(hfile);
|
||||||
DeleteFileA(buffer);
|
DeleteFileA(buffer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,6 @@ static struct list *file_get_kernel_obj_list( struct object *obj );
|
||||||
static void file_destroy( struct object *obj );
|
static void file_destroy( struct object *obj );
|
||||||
|
|
||||||
static int file_get_poll_events( struct fd *fd );
|
static int file_get_poll_events( struct fd *fd );
|
||||||
static int file_flush( struct fd *fd, struct async *async );
|
|
||||||
static enum server_fd_type file_get_fd_type( struct fd *fd );
|
static enum server_fd_type file_get_fd_type( struct fd *fd );
|
||||||
|
|
||||||
static const struct object_ops file_ops =
|
static const struct object_ops file_ops =
|
||||||
|
@ -108,7 +107,7 @@ static const struct fd_ops file_fd_ops =
|
||||||
file_get_fd_type, /* get_fd_type */
|
file_get_fd_type, /* get_fd_type */
|
||||||
no_fd_read, /* read */
|
no_fd_read, /* read */
|
||||||
no_fd_write, /* write */
|
no_fd_write, /* write */
|
||||||
file_flush, /* flush */
|
no_fd_flush, /* flush */
|
||||||
default_fd_get_file_info, /* get_file_info */
|
default_fd_get_file_info, /* get_file_info */
|
||||||
no_fd_get_volume_info, /* get_volume_info */
|
no_fd_get_volume_info, /* get_volume_info */
|
||||||
default_fd_ioctl, /* ioctl */
|
default_fd_ioctl, /* ioctl */
|
||||||
|
@ -296,17 +295,6 @@ static int file_get_poll_events( struct fd *fd )
|
||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int file_flush( struct fd *fd, struct async *async )
|
|
||||||
{
|
|
||||||
int unix_fd = get_unix_fd( fd );
|
|
||||||
if (unix_fd != -1 && fsync( unix_fd ) == -1)
|
|
||||||
{
|
|
||||||
file_set_error();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum server_fd_type file_get_fd_type( struct fd *fd )
|
static enum server_fd_type file_get_fd_type( struct fd *fd )
|
||||||
{
|
{
|
||||||
struct file *file = get_fd_user( fd );
|
struct file *file = get_fd_user( fd );
|
||||||
|
|
Loading…
Reference in New Issue