On Tue, Apr 19, 2022, 2:49 PM Daniel Lehman dlehman25@gmail.com wrote:
Signed-off-by: Daniel Lehman dlehman25@gmail.com
dlls/ntdll/tests/pipe.c | 11 +---------- dlls/ntdll/unix/file.c | 18 ++++++++++++++++-- server/async.c | 33 +++++++++++++++++++++++++++++++++ server/protocol.def | 4 ++++ 4 files changed, 54 insertions(+), 12 deletions(-)
diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c index 1298e7a37ae..cfad711a09d 100644 --- a/dlls/ntdll/tests/pipe.c +++ b/dlls/ntdll/tests/pipe.c @@ -574,11 +574,9 @@ static DWORD WINAPI synchronousio_thread(void *arg) U(iosb).Status = 0xdeadbabe; iosb.Information = 0xdeadbeef; res = listen_pipe(pipe, NULL, &iosb, FALSE);
- todo_wine { ok(res == STATUS_CANCELLED, "NtFsControlFile returned %lx\n", res); ok(U(iosb).Status == 0xdeadbabe, "wrong status %lx\n",
U(iosb).Status); ok(iosb.Information == 0xdeadbeef, "wrong info %Iu\n", iosb.Information);
- } return 0;
}
@@ -594,13 +592,10 @@ static void test_cancelsynchronousio(void)
/* bogus values */ res = pNtCancelSynchronousIoFile((HANDLE)0xdeadbeef, NULL, &iosb);
- todo_wine ok(res == STATUS_INVALID_HANDLE, "NtCancelSynchronousIoFile returned
%lx\n", res); res = pNtCancelSynchronousIoFile(GetCurrentThread(), NULL, NULL);
- todo_wine ok(res == STATUS_ACCESS_VIOLATION, "NtCancelSynchronousIoFile
returned %lx\n", res); res = pNtCancelSynchronousIoFile(GetCurrentThread(), NULL, (IO_STATUS_BLOCK*)0xdeadbeef);
- todo_wine ok(res == STATUS_ACCESS_VIOLATION, "NtCancelSynchronousIoFile
returned %lx\n", res); memset(&iosb, 0x55, sizeof(iosb)); res = pNtCancelSynchronousIoFile(GetCurrentThread(), (HANDLE)0xdeadbeef, &iosb); @@ -616,14 +611,12 @@ static void test_cancelsynchronousio(void) Sleep(100); memset(&iosb, 0x55, sizeof(iosb)); res = pNtCancelSynchronousIoFile(thread, NULL, &iosb);
- todo_wine { ok(res == STATUS_SUCCESS, "Failed to cancel I/O\n"); ok(U(iosb).Status == STATUS_SUCCESS, "iosb.Status got changed to
%lx\n", U(iosb).Status); ok(U(iosb).Information == 0, "iosb.Information got changed to %Iu\n", U(iosb).Information);
- }
- CloseHandle(pipe); WaitForSingleObject(thread, INFINITE); CloseHandle(thread);
CloseHandle(pipe);
/* asynchronous i/o */ res = create_pipe(&pipe, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 /*
OVERLAPPED */); @@ -635,11 +628,9 @@ static void test_cancelsynchronousio(void) ok(res == STATUS_PENDING, "NtFsControlFile returned %lx\n", res); memset(&iosb, 0x55, sizeof(iosb)); res = pNtCancelSynchronousIoFile(GetCurrentThread(), NULL, &iosb);
- todo_wine { ok(res == STATUS_NOT_FOUND, "NtCancelSynchronousIoFile returned
%lx\n", res); ok(U(iosb).Status == STATUS_NOT_FOUND, "iosb.Status got changed to %lx\n", U(iosb).Status); ok(U(iosb).Information == 0, "iosb.Information got changed to %Iu\n", U(iosb).Information);
- } ret = WaitForSingleObject(event, 0); ok(ret == WAIT_TIMEOUT, "wait returned %lx\n", ret); client = CreateFileW(testpipe, GENERIC_READ | GENERIC_WRITE, 0, 0,
OPEN_EXISTING, diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 6990f9b4719..d833a136357 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -5975,8 +5975,22 @@ NTSTATUS WINAPI NtCancelIoFileEx( HANDLE handle, IO_STATUS_BLOCK *io, IO_STATUS_ */ NTSTATUS WINAPI NtCancelSynchronousIoFile( HANDLE handle, IO_STATUS_BLOCK *io, IO_STATUS_BLOCK *io_status ) {
- FIXME( "(%p,%p,%p) stub\n", handle, io, io_status );
- return STATUS_NOT_IMPLEMENTED;
- NTSTATUS status;
- FIXME( "(%p %p %p),partial stub\n", handle, io, io_status );
- if (io) FIXME( "stub: unused IO_STATUS_BLOCK\n" );
If io is specified, it should never cancel any I/O operations other than the one specified by the parameter.
Better keep returning STATUS_NOT_IMPLEMENTED in this case?
+
- SERVER_START_REQ( cancel_sync )
- {
req->handle = wine_server_obj_handle( handle );
status = wine_server_call( req );
- }
- SERVER_END_REQ;
- io_status->u.Status = status;
- io_status->Information = 0;
- return status;
}
/****************************************************************** diff --git a/server/async.c b/server/async.c index a4fbeab555e..b78d3a0532a 100644 --- a/server/async.c +++ b/server/async.c @@ -588,6 +588,26 @@ restart: return woken; }
+static int cancel_blocking( struct process *process, struct thread *thread ) +{
- struct async *async;
- int woken = 0;
+restart:
- LIST_FOR_EACH_ENTRY( async, &process->asyncs, struct async,
process_entry )
- {
if (async->terminated || async->canceled) continue;
if ((async->thread == thread) && async->blocking)
{
async->canceled = 1;
fd_cancel_async( async->fd, async );
woken++;
goto restart;
}
- }
- return woken;
+}
void cancel_process_asyncs( struct process *process ) { cancel_async( process, NULL, NULL, 0 ); @@ -715,6 +735,19 @@ struct async *find_pending_async( struct async_queue *queue ) return NULL; }
+/* cancels sync I/O on a thread */ +DECL_HANDLER(cancel_sync) +{
- struct thread *thread = get_thread_from_handle( req->handle,
THREAD_TERMINATE );
- if (thread)
- {
if (!cancel_blocking( current->process, thread ))
set_error( STATUS_NOT_FOUND );
release_object( thread );
- }
+}
/* cancels all async I/O */ DECL_HANDLER(cancel_async) { diff --git a/server/protocol.def b/server/protocol.def index 9b7b99ae86a..52a1b7767ce 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2135,6 +2135,10 @@ enum message_type #define SERIALINFO_PENDING_WRITE 0x04 #define SERIALINFO_PENDING_WAIT 0x08
+/* Cancel all sync io on a thread */ +@REQ(cancel_sync)
- obj_handle_t handle; /* thread handle on which to cancel io */
+@END
/* Create an async I/O */ @REQ(register_async) -- 2.25.1