Erich E. Hoover : server: Allow volume information queries to be asynchronous.

Alexandre Julliard julliard at winehq.org
Mon Feb 15 16:09:50 CST 2021


Module: wine
Branch: master
Commit: 61d7629ba498f5375e2c7b6dfbdd89ff295d1bc0
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=61d7629ba498f5375e2c7b6dfbdd89ff295d1bc0

Author: Erich E. Hoover <erich.e.hoover at gmail.com>
Date:   Sat May 23 21:39:41 2020 -0600

server: Allow volume information queries to be asynchronous.

Signed-off-by: Erich E. Hoover <erich.e.hoover at gmail.com>
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 include/wine/server_protocol.h |  7 +++++--
 server/console.c               |  5 +++--
 server/fd.c                    | 13 +++++++++----
 server/file.h                  |  4 ++--
 server/named_pipe.c            |  5 +++--
 server/protocol.def            |  2 ++
 server/request.h               |  8 +++++---
 server/trace.c                 |  4 +++-
 8 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index d2a361df26d..a7f1cdef053 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -1688,13 +1688,16 @@ struct get_volume_info_request
 {
     struct request_header __header;
     obj_handle_t handle;
+    async_data_t async;
     unsigned int info_class;
-    char __pad_20[4];
+    char __pad_60[4];
 };
 struct get_volume_info_reply
 {
     struct reply_header __header;
+    obj_handle_t wait;
     /* VARARG(data,bytes); */
+    char __pad_12[4];
 };
 
 
@@ -6266,7 +6269,7 @@ union generic_reply
 
 /* ### protocol_version begin ### */
 
-#define SERVER_PROTOCOL_VERSION 675
+#define SERVER_PROTOCOL_VERSION 676
 
 /* ### protocol_version end ### */
 
diff --git a/server/console.c b/server/console.c
index cd6076f0033..92bda51846c 100644
--- a/server/console.c
+++ b/server/console.c
@@ -99,7 +99,7 @@ static const struct object_ops console_ops =
 
 static enum server_fd_type console_get_fd_type( struct fd *fd );
 static void console_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class );
-static void console_get_volume_info( struct fd *fd, unsigned int info_class );
+static int console_get_volume_info( struct fd *fd, struct async *async, unsigned int info_class );
 static int console_read( struct fd *fd, struct async *async, file_pos_t pos );
 static int console_flush( struct fd *fd, struct async *async );
 static int console_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
@@ -480,7 +480,7 @@ static void console_get_file_info( struct fd *fd, obj_handle_t handle, unsigned
     set_error( STATUS_INVALID_DEVICE_REQUEST );
 }
 
-static void console_get_volume_info( struct fd *fd, unsigned int info_class )
+static int console_get_volume_info( struct fd *fd, struct async *async, unsigned int info_class )
 {
     switch (info_class)
     {
@@ -500,6 +500,7 @@ static void console_get_volume_info( struct fd *fd, unsigned int info_class )
     default:
         set_error( STATUS_NOT_IMPLEMENTED );
     }
+    return 0;
 }
 
 static struct object *create_console(void)
diff --git a/server/fd.c b/server/fd.c
index 2dcdd04a892..65a6f876e5c 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -2369,9 +2369,10 @@ void default_fd_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int
 }
 
 /* default get_volume_info() routine */
-void no_fd_get_volume_info( struct fd *fd, unsigned int info_class )
+int no_fd_get_volume_info( struct fd *fd, struct async *async, unsigned int info_class )
 {
     set_error( STATUS_OBJECT_TYPE_MISMATCH );
+    return 0;
 }
 
 /* default ioctl() routine */
@@ -2666,12 +2667,16 @@ DECL_HANDLER(get_file_info)
 DECL_HANDLER(get_volume_info)
 {
     struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
+    struct async *async;
 
-    if (fd)
+    if (!fd) return;
+
+    if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
     {
-        fd->fd_ops->get_volume_info( fd, req->info_class );
-        release_object( fd );
+        reply->wait = async_handoff( async, fd->fd_ops->get_volume_info( fd, async, req->info_class ), NULL, 1 );
+        release_object( async );
     }
+    release_object( fd );
 }
 
 /* open a file object */
diff --git a/server/file.h b/server/file.h
index 3b70799a3ec..fbfd1e4eec9 100644
--- a/server/file.h
+++ b/server/file.h
@@ -65,7 +65,7 @@ struct fd_ops
     /* query file info */
     void (*get_file_info)( struct fd *, obj_handle_t, unsigned int );
     /* query volume info */
-    void (*get_volume_info)( struct fd *, unsigned int );
+    int (*get_volume_info)( struct fd *, struct async *, unsigned int );
     /* perform an ioctl on the file */
     int (*ioctl)(struct fd *fd, ioctl_code_t code, struct async *async );
     /* queue an async operation */
@@ -114,7 +114,7 @@ extern int no_fd_write( struct fd *fd, struct async *async, file_pos_t pos );
 extern int no_fd_flush( struct fd *fd, struct async *async );
 extern void no_fd_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class );
 extern void default_fd_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class );
-extern void no_fd_get_volume_info( struct fd *fd, unsigned int info_class );
+extern int no_fd_get_volume_info( struct fd *fd, struct async *async, unsigned int info_class );
 extern int no_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
 extern int default_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
 extern void no_fd_queue_async( struct fd *fd, struct async *async, int type, int count );
diff --git a/server/named_pipe.c b/server/named_pipe.c
index 2e80ef3b1aa..a3ce9d463f1 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -146,7 +146,7 @@ static WCHAR *pipe_end_get_full_name( struct object *obj, data_size_t *len );
 static int pipe_end_read( struct fd *fd, struct async *async, file_pos_t pos );
 static int pipe_end_write( struct fd *fd, struct async *async_data, file_pos_t pos );
 static int pipe_end_flush( struct fd *fd, struct async *async );
-static void pipe_end_get_volume_info( struct fd *fd, unsigned int info_class );
+static int pipe_end_get_volume_info( struct fd *fd, struct async *async, unsigned int info_class );
 static void pipe_end_reselect_async( struct fd *fd, struct async_queue *queue );
 static void pipe_end_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class );
 
@@ -742,7 +742,7 @@ static WCHAR *pipe_end_get_full_name( struct object *obj, data_size_t *len )
     return pipe_end->pipe->obj.ops->get_full_name( &pipe_end->pipe->obj, len );
 }
 
-static void pipe_end_get_volume_info( struct fd *fd, unsigned int info_class )
+static int pipe_end_get_volume_info( struct fd *fd, struct async *async, unsigned int info_class )
 {
     switch (info_class)
     {
@@ -762,6 +762,7 @@ static void pipe_end_get_volume_info( struct fd *fd, unsigned int info_class )
     default:
         set_error( STATUS_NOT_IMPLEMENTED );
     }
+    return 0;
 }
 
 static void message_queue_read( struct pipe_end *pipe_end, struct iosb *iosb )
diff --git a/server/protocol.def b/server/protocol.def
index f85826cc277..8ba8bc85b82 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1392,8 +1392,10 @@ enum server_fd_type
 /* Query volume information */
 @REQ(get_volume_info)
     obj_handle_t handle;        /* handle to the file */
+    async_data_t async;         /* async I/O parameters */
     unsigned int info_class;    /* queried information class */
 @REPLY
+    obj_handle_t wait;          /* handle to wait on for blocking read */
     VARARG(data,bytes);         /* volume info data */
 @END
 
diff --git a/server/request.h b/server/request.h
index d1bfd746f39..e7ea5b0bdd6 100644
--- a/server/request.h
+++ b/server/request.h
@@ -1032,9 +1032,11 @@ C_ASSERT( FIELD_OFFSET(struct get_file_info_request, info_class) == 16 );
 C_ASSERT( sizeof(struct get_file_info_request) == 24 );
 C_ASSERT( sizeof(struct get_file_info_reply) == 8 );
 C_ASSERT( FIELD_OFFSET(struct get_volume_info_request, handle) == 12 );
-C_ASSERT( FIELD_OFFSET(struct get_volume_info_request, info_class) == 16 );
-C_ASSERT( sizeof(struct get_volume_info_request) == 24 );
-C_ASSERT( sizeof(struct get_volume_info_reply) == 8 );
+C_ASSERT( FIELD_OFFSET(struct get_volume_info_request, async) == 16 );
+C_ASSERT( FIELD_OFFSET(struct get_volume_info_request, info_class) == 56 );
+C_ASSERT( sizeof(struct get_volume_info_request) == 64 );
+C_ASSERT( FIELD_OFFSET(struct get_volume_info_reply, wait) == 8 );
+C_ASSERT( sizeof(struct get_volume_info_reply) == 16 );
 C_ASSERT( FIELD_OFFSET(struct lock_file_request, handle) == 12 );
 C_ASSERT( FIELD_OFFSET(struct lock_file_request, offset) == 16 );
 C_ASSERT( FIELD_OFFSET(struct lock_file_request, count) == 24 );
diff --git a/server/trace.c b/server/trace.c
index 5265cc69a15..842715e2836 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1993,12 +1993,14 @@ static void dump_get_file_info_reply( const struct get_file_info_reply *req )
 static void dump_get_volume_info_request( const struct get_volume_info_request *req )
 {
     fprintf( stderr, " handle=%04x", req->handle );
+    dump_async_data( ", async=", &req->async );
     fprintf( stderr, ", info_class=%08x", req->info_class );
 }
 
 static void dump_get_volume_info_reply( const struct get_volume_info_reply *req )
 {
-    dump_varargs_bytes( " data=", cur_size );
+    fprintf( stderr, " wait=%04x", req->wait );
+    dump_varargs_bytes( ", data=", cur_size );
 }
 
 static void dump_lock_file_request( const struct lock_file_request *req )




More information about the wine-cvs mailing list