Andrey Turkin : server: Pass Information field from async I/O APCs.

Alexandre Julliard julliard at winehq.org
Thu Nov 15 07:45:06 CST 2007


Module: wine
Branch: master
Commit: 7a9210fa85c28dd1a5bba33c81beddbdd194e6ae
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7a9210fa85c28dd1a5bba33c81beddbdd194e6ae

Author: Andrey Turkin <andrey.turkin at gmail.com>
Date:   Sat Nov 10 01:12:16 2007 +0300

server: Pass Information field from async I/O APCs.

---

 dlls/ntdll/directory.c         |    4 ++--
 dlls/ntdll/file.c              |    8 ++++----
 dlls/ntdll/sync.c              |    3 ++-
 dlls/ntdll/tests/file.c        |    2 --
 dlls/ws2_32/socket.c           |    8 ++++----
 include/wine/server_protocol.h |    5 +++--
 server/async.c                 |    4 ++--
 server/file.h                  |    2 +-
 server/protocol.def            |    3 ++-
 server/thread.c                |    2 +-
 10 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 981d2a1..0be9942 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -2254,7 +2254,7 @@ static void WINAPI read_changes_user_apc( void *arg, IO_STATUS_BLOCK *io, ULONG
     RtlFreeHeap( GetProcessHeap(), 0, info );
 }
 
-static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status )
+static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status, ULONG_PTR *total )
 {
     struct read_changes_info *info = user;
     char path[PATH_MAX];
@@ -2299,7 +2299,7 @@ static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS st
     }
 
     iosb->u.Status = ret;
-    iosb->Information = len;
+    iosb->Information = *total = len;
     return ret;
 }
 
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index e84bc3d..b9a763f 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -338,7 +338,7 @@ NTSTATUS FILE_GetNtStatus(void)
 /***********************************************************************
  *             FILE_AsyncReadService      (INTERNAL)
  */
-static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status)
+static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status, ULONG_PTR *total)
 {
     async_fileio_read *fileio = user;
     int fd, needs_close, result;
@@ -389,7 +389,7 @@ static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATU
     if (status != STATUS_PENDING)
     {
         iosb->u.Status = status;
-        iosb->Information = fileio->already;
+        iosb->Information = *total = fileio->already;
     }
     return status;
 }
@@ -718,7 +718,7 @@ err:
 /***********************************************************************
  *             FILE_AsyncWriteService      (INTERNAL)
  */
-static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTATUS status)
+static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTATUS status, ULONG_PTR *total)
 {
     async_fileio_write *fileio = user;
     int result, fd, needs_close;
@@ -759,7 +759,7 @@ static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTAT
     if (status != STATUS_PENDING)
     {
         iosb->u.Status = status;
-        iosb->Information = fileio->already;
+        iosb->Information = *total = fileio->already;
     }
     return status;
 }
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index ec8aa59..fd7630f 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -786,7 +786,8 @@ static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result )
         result->type = call->type;
         result->async_io.status = call->async_io.func( call->async_io.user,
                                                        call->async_io.sb,
-                                                       call->async_io.status );
+                                                       call->async_io.status,
+                                                       &result->async_io.total );
         break;
     case APC_VIRTUAL_ALLOC:
         result->type = call->type;
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 5592711..8ea454c 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -524,9 +524,7 @@ static void test_iocp_fileio(HANDLE h)
         if (get_msg(h))
         {
             ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey );
-            todo_wine {
             ok( ioSb.Information == 3, "Invalid ioSb.Information: %ld\n", ioSb.Information );
-            }
             ok( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status);
             ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue );
         }
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index eab1550..3abb5a0 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -1118,7 +1118,7 @@ static int WS2_recv( int fd, struct iovec* iov, int count,
  *
  * Handler for overlapped recv() operations.
  */
-static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status)
+static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status, ULONG_PTR *total )
 {
     ws2_async* wsa = user;
     int result = 0, fd;
@@ -1155,7 +1155,7 @@ static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS stat
     if (status != STATUS_PENDING)
     {
         iosb->u.Status = status;
-        iosb->Information = result;
+        iosb->Information = *total = result;
     }
     return status;
 }
@@ -1222,7 +1222,7 @@ static int WS2_send( int fd, struct iovec* iov, int count,
  *
  * Handler for overlapped send() operations.
  */
-static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status)
+static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status, ULONG_PTR *total )
 {
     ws2_async* wsa = user;
     int result = 0, fd;
@@ -1262,7 +1262,7 @@ static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS statu
     if (status != STATUS_PENDING)
     {
         iosb->u.Status = status;
-        iosb->Information = result;
+        iosb->Information = *total = result;
     }
     return status;
 }
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 8598aef..9c56089 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -271,7 +271,7 @@ typedef union
     struct
     {
         enum apc_type    type;
-        unsigned int   (*func)(void*, void*, unsigned int);
+        unsigned int   (*func)(void*, void*, unsigned int, unsigned long *);
         void            *user;
         void            *sb;
         unsigned int     status;
@@ -356,6 +356,7 @@ typedef union
     {
         enum apc_type    type;
         unsigned int     status;
+        unsigned long    total;
     } async_io;
     struct
     {
@@ -4904,6 +4905,6 @@ union generic_reply
     struct add_fd_completion_reply add_fd_completion_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 330
+#define SERVER_PROTOCOL_VERSION 331
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/async.c b/server/async.c
index 98d6075..acf61d8 100644
--- a/server/async.c
+++ b/server/async.c
@@ -231,7 +231,7 @@ void async_set_timeout( struct async *async, timeout_t timeout, unsigned int sta
 }
 
 /* store the result of the client-side async callback */
-void async_set_result( struct object *obj, unsigned int status )
+void async_set_result( struct object *obj, unsigned int status, unsigned long total )
 {
     struct async *async = (struct async *)obj;
 
@@ -256,7 +256,7 @@ void async_set_result( struct object *obj, unsigned int status )
         async->timeout = NULL;
         async->status = status;
         if (async->data.cvalue && async->queue && async->queue->fd)
-            fd_add_completion( async->queue->fd, async->data.cvalue, status, 0 ); /* TODO pass Information field */
+            fd_add_completion( async->queue->fd, async->data.cvalue, status, total );
         if (async->data.apc)
         {
             apc_call_t data;
diff --git a/server/file.h b/server/file.h
index dbf0930..1c659be 100644
--- a/server/file.h
+++ b/server/file.h
@@ -136,7 +136,7 @@ extern void free_async_queue( struct async_queue *queue );
 extern struct async *create_async( struct thread *thread, struct async_queue *queue,
                                    const async_data_t *data );
 extern void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status );
-extern void async_set_result( struct object *obj, unsigned int status );
+extern void async_set_result( struct object *obj, unsigned int status, unsigned long total );
 extern int async_waiting( struct async_queue *queue );
 extern void async_terminate( struct async *async, unsigned int status );
 extern void async_wake_up( struct async_queue *queue, unsigned int status );
diff --git a/server/protocol.def b/server/protocol.def
index cf3ffa1..dfb5d48 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -287,7 +287,7 @@ typedef union
     struct
     {
         enum apc_type    type;     /* APC_ASYNC_IO */
-        unsigned int   (*func)(void*, void*, unsigned int);
+        unsigned int   (*func)(void*, void*, unsigned int, unsigned long *);
         void            *user;     /* user pointer */
         void            *sb;       /* status block */
         unsigned int     status;   /* I/O status */
@@ -372,6 +372,7 @@ typedef union
     {
         enum apc_type    type;      /* APC_ASYNC_IO */
         unsigned int     status;    /* new status of async operation */
+        unsigned long    total;     /* bytes transferred */
     } async_io;
     struct
     {
diff --git a/server/thread.c b/server/thread.c
index 99cf896..6eb43ee 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -1199,7 +1199,7 @@ DECL_HANDLER(select)
         }
         else if (apc->result.type == APC_ASYNC_IO)
         {
-            if (apc->owner) async_set_result( apc->owner, apc->result.async_io.status );
+            if (apc->owner) async_set_result( apc->owner, apc->result.async_io.status, apc->result.async_io.total );
         }
         wake_up( &apc->obj, 0 );
         close_handle( current->process, req->prev_apc );




More information about the wine-cvs mailing list