Alexandre Julliard : server:
Add support for queuing a user APC upon async I/O completion.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Mar 28 06:41:42 CDT 2007
Module: wine
Branch: master
Commit: c16eb8efd942bfbb0bb7f3da4c740a2e483cce28
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c16eb8efd942bfbb0bb7f3da4c740a2e483cce28
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Mar 27 16:42:27 2007 +0200
server: Add support for queuing a user APC upon async I/O completion.
---
dlls/ntdll/directory.c | 11 +++--------
dlls/ntdll/file.c | 12 ++++++++----
include/wine/server_protocol.h | 4 +++-
server/async.c | 10 ++++++++++
server/protocol.def | 2 ++
server/trace.c | 4 ++--
6 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index e60dad7..697fd1a 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -2164,8 +2164,6 @@ done:
struct read_changes_info
{
HANDLE FileHandle;
- PIO_APC_ROUTINE ApcRoutine;
- PVOID ApcContext;
PVOID Buffer;
ULONG BufferSize;
};
@@ -2177,7 +2175,7 @@ static void WINAPI read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, ULONG st
NTSTATUS ret = STATUS_SUCCESS;
int len, action, i;
- TRACE("%p %p %p %08x\n", info, info->ApcContext, iosb, status);
+ TRACE("%p %p %08x\n", info, iosb, status);
/*
* FIXME: race me!
@@ -2266,9 +2264,6 @@ NtNotifyChangeDirectoryFile( HANDLE FileHandle, HANDLE Event,
if (CompletionFilter == 0 || (CompletionFilter & ~FILE_NOTIFY_ALL))
return STATUS_INVALID_PARAMETER;
- if (ApcRoutine)
- FIXME("parameters ignored %p %p\n", ApcRoutine, ApcContext );
-
info = RtlAllocateHeap( GetProcessHeap(), 0, sizeof *info );
if (!info)
return STATUS_NO_MEMORY;
@@ -2276,8 +2271,6 @@ NtNotifyChangeDirectoryFile( HANDLE FileHandle, HANDLE Event,
info->FileHandle = FileHandle;
info->Buffer = Buffer;
info->BufferSize = BufferSize;
- info->ApcRoutine = ApcRoutine;
- info->ApcContext = ApcContext;
SERVER_START_REQ( read_directory_changes )
{
@@ -2288,6 +2281,8 @@ NtNotifyChangeDirectoryFile( HANDLE FileHandle, HANDLE Event,
req->async.callback = read_changes_apc;
req->async.iosb = IoStatusBlock;
req->async.arg = info;
+ req->async.apc = ApcRoutine;
+ req->async.apc_arg = ApcContext;
req->async.event = Event;
status = wine_server_call( req );
}
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 6873e0e..89de3b3 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -922,7 +922,7 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
{
HANDLE internal_event = 0;
- if(!event)
+ if(!event && !apc)
{
io->u.Status = NtCreateEvent(&internal_event, EVENT_ALL_ACCESS, NULL, FALSE, FALSE);
if (io->u.Status != STATUS_SUCCESS) return io->u.Status;
@@ -933,12 +933,14 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
req->async.callback = pipe_completion_wait;
req->async.iosb = io;
req->async.arg = NULL;
+ req->async.apc = apc;
+ req->async.apc_arg = apc_context;
req->async.event = event ? event : internal_event;
io->u.Status = wine_server_call(req);
}
SERVER_END_REQ;
- if (!event && io->u.Status == STATUS_PENDING)
+ if (internal_event && io->u.Status == STATUS_PENDING)
{
while (NtWaitForSingleObject(internal_event, TRUE, NULL) == STATUS_USER_APC) /*nothing*/ ;
}
@@ -951,7 +953,7 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
HANDLE internal_event = 0;
FILE_PIPE_WAIT_FOR_BUFFER *buff = in_buffer;
- if(!event)
+ if(!event && !apc)
{
io->u.Status = NtCreateEvent(&internal_event, EVENT_ALL_ACCESS, NULL, FALSE, FALSE);
if (io->u.Status != STATUS_SUCCESS) return io->u.Status;
@@ -964,13 +966,15 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
req->async.callback = pipe_completion_wait;
req->async.iosb = io;
req->async.arg = NULL;
+ req->async.apc = apc;
+ req->async.apc_arg = apc_context;
req->async.event = event ? event : internal_event;
wine_server_add_data( req, buff->Name, buff->NameLength );
io->u.Status = wine_server_call( req );
}
SERVER_END_REQ;
- if (!event && io->u.Status == STATUS_PENDING)
+ if (internal_event && io->u.Status == STATUS_PENDING)
{
while (NtWaitForSingleObject(internal_event, TRUE, NULL) == STATUS_USER_APC) /*nothing*/ ;
}
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 1e21566..a254128 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -162,6 +162,8 @@ typedef struct
void *callback;
void *iosb;
void *arg;
+ void *apc;
+ void *apc_arg;
obj_handle_t event;
} async_data_t;
@@ -4660,6 +4662,6 @@ union generic_reply
struct allocate_locally_unique_id_reply allocate_locally_unique_id_reply;
};
-#define SERVER_PROTOCOL_VERSION 288
+#define SERVER_PROTOCOL_VERSION 289
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/async.c b/server/async.c
index aa4db4e..440cb2e 100644
--- a/server/async.c
+++ b/server/async.c
@@ -150,6 +150,16 @@ void async_set_result( struct object *obj, unsigned int status )
}
else
{
+ if (async->data.apc)
+ {
+ apc_call_t data;
+ data.type = APC_USER;
+ data.user.func = async->data.apc;
+ data.user.args[0] = (unsigned long)async->data.apc_arg;
+ data.user.args[1] = (unsigned long)async->data.iosb;
+ data.user.args[2] = 0;
+ thread_queue_apc( async->thread, NULL, &data );
+ }
if (async->event) set_event( async->event );
}
}
diff --git a/server/protocol.def b/server/protocol.def
index 5105fd6..ef20235 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -178,6 +178,8 @@ typedef struct
void *callback; /* client-side callback to call upon end of async */
void *iosb; /* I/O status block in client addr space */
void *arg; /* opaque user data to pass to callback */
+ void *apc; /* user apc to call */
+ void *apc_arg; /* argument for user apc */
obj_handle_t event; /* event to signal when done */
} async_data_t;
diff --git a/server/trace.c b/server/trace.c
index a332821..898998b 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -246,8 +246,8 @@ static void dump_apc_result( const apc_result_t *result )
static void dump_async_data( const async_data_t *data )
{
- fprintf( stderr, "{callback=%p,iosb=%p,arg=%p,event=%p}",
- data->callback, data->iosb, data->arg, data->event );
+ fprintf( stderr, "{callback=%p,iosb=%p,arg=%p,apc=%p,apc_arg=%p,event=%p}",
+ data->callback, data->iosb, data->arg, data->apc, data->apc_arg, data->event );
}
static void dump_luid( const luid_t *luid )
More information about the wine-cvs
mailing list