From 860091d2fd7d5aa08e471af494d74bbc46d1806b Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 5 May 2015 12:23:08 +0900 Subject: [PATCH] server: Add an async structure to the flush request to follow the common pattern. --- dlls/ntdll/file.c | 12 ++++++++---- include/wine/server_protocol.h | 15 ++++++++------- server/fd.c | 14 +++++--------- server/file.c | 5 +++-- server/file.h | 4 ++-- server/named_pipe.c | 20 ++++++++++++-------- server/protocol.def | 5 +++-- server/request.h | 13 +++++++------ server/trace.c | 13 +++++++------ 9 files changed, 55 insertions(+), 46 deletions(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 041720a4d23..d25c792c96f 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -3145,17 +3145,21 @@ NTSTATUS WINAPI NtFlushBuffersFile( HANDLE hFile, IO_STATUS_BLOCK* IoStatusBlock } else { - SERVER_START_REQ( flush_file ) + SERVER_START_REQ( flush ) { - req->handle = wine_server_obj_handle( hFile ); + req->blocking = 1; /* always blocking */ + req->async.handle = wine_server_obj_handle( hFile ); + req->async.iosb = wine_server_client_ptr( IoStatusBlock ); ret = wine_server_call( req ); hEvent = wine_server_ptr_handle( reply->event ); } SERVER_END_REQ; - if (!ret && hEvent) + + if (hEvent) { - ret = NtWaitForSingleObject( hEvent, FALSE, NULL ); + NtWaitForSingleObject( hEvent, FALSE, NULL ); NtClose( hEvent ); + ret = STATUS_SUCCESS; } } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index ef0d181f1bd..fabd3b47d1e 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -1398,12 +1398,13 @@ enum server_fd_type -struct flush_file_request +struct flush_request { struct request_header __header; - obj_handle_t handle; + int blocking; + async_data_t async; }; -struct flush_file_reply +struct flush_reply { struct reply_header __header; obj_handle_t event; @@ -5220,7 +5221,7 @@ enum request REQ_alloc_file_handle, REQ_get_handle_unix_name, REQ_get_handle_fd, - REQ_flush_file, + REQ_flush, REQ_lock_file, REQ_unlock_file, REQ_create_socket, @@ -5489,7 +5490,7 @@ union generic_request struct alloc_file_handle_request alloc_file_handle_request; struct get_handle_unix_name_request get_handle_unix_name_request; struct get_handle_fd_request get_handle_fd_request; - struct flush_file_request flush_file_request; + struct flush_request flush_request; struct lock_file_request lock_file_request; struct unlock_file_request unlock_file_request; struct create_socket_request create_socket_request; @@ -5756,7 +5757,7 @@ union generic_reply struct alloc_file_handle_reply alloc_file_handle_reply; struct get_handle_unix_name_reply get_handle_unix_name_reply; struct get_handle_fd_reply get_handle_fd_reply; - struct flush_file_reply flush_file_reply; + struct flush_reply flush_reply; struct lock_file_reply lock_file_reply; struct unlock_file_reply unlock_file_reply; struct create_socket_reply create_socket_reply; @@ -5977,6 +5978,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; }; -#define SERVER_PROTOCOL_VERSION 471 +#define SERVER_PROTOCOL_VERSION 472 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/fd.c b/server/fd.c index 9b9ce97f490..c5340ff9171 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2174,9 +2174,10 @@ obj_handle_t no_fd_write( struct fd *fd, const async_data_t *async, int blocking } /* default flush() routine */ -void no_fd_flush( struct fd *fd, struct event **event ) +obj_handle_t no_fd_flush( struct fd *fd, const async_data_t *async, int blocking ) { set_error( STATUS_OBJECT_TYPE_MISMATCH ); + return 0; } /* default ioctl() routine */ @@ -2228,18 +2229,13 @@ void fd_copy_completion( struct fd *src, struct fd *dst ) } /* flush a file buffers */ -DECL_HANDLER(flush_file) +DECL_HANDLER(flush) { - struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 ); - struct event * event = NULL; + struct fd *fd = get_handle_fd_obj( current->process, req->async.handle, 0 ); if (fd) { - fd->fd_ops->flush( fd, &event ); - if ( event ) - { - reply->event = alloc_handle( current->process, event, SYNCHRONIZE, 0 ); - } + reply->event = fd->fd_ops->flush( fd, &req->async, req->blocking ); release_object( fd ); } } diff --git a/server/file.c b/server/file.c index 902125efde6..792bbe09b4e 100644 --- a/server/file.c +++ b/server/file.c @@ -70,7 +70,7 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd static void file_destroy( struct object *obj ); static int file_get_poll_events( struct fd *fd ); -static void file_flush( struct fd *fd, struct event **event ); +static obj_handle_t file_flush( struct fd *fd, const async_data_t *async, int blocking ); static enum server_fd_type file_get_fd_type( struct fd *fd ); static const struct object_ops file_ops = @@ -283,10 +283,11 @@ static int file_get_poll_events( struct fd *fd ) return events; } -static void file_flush( struct fd *fd, struct event **event ) +static obj_handle_t file_flush( struct fd *fd, const async_data_t *async, int blocking ) { int unix_fd = get_unix_fd( fd ); if (unix_fd != -1 && fsync( unix_fd ) == -1) file_set_error(); + return 0; } static enum server_fd_type file_get_fd_type( struct fd *fd ) diff --git a/server/file.h b/server/file.h index d30bb8451d7..7e8b12e4578 100644 --- a/server/file.h +++ b/server/file.h @@ -44,7 +44,7 @@ struct fd_ops /* perform a write on the file */ obj_handle_t (*write)(struct fd *, const async_data_t *, int, file_pos_t, data_size_t * ); /* flush the object buffers */ - void (*flush)(struct fd *, struct event **); + obj_handle_t (*flush)(struct fd *, const async_data_t *, int); /* perform an ioctl on the file */ obj_handle_t (*ioctl)(struct fd *fd, ioctl_code_t code, const async_data_t *async, int blocking ); /* queue an async operation */ @@ -92,7 +92,7 @@ extern void fd_reselect_async( struct fd *fd, struct async_queue *queue ); extern obj_handle_t no_fd_read( struct fd *fd, const async_data_t *async, int blocking, file_pos_t pos ); extern obj_handle_t no_fd_write( struct fd *fd, const async_data_t *async, int blocking, file_pos_t pos, data_size_t *written ); -extern void no_fd_flush( struct fd *fd, struct event **event ); +extern obj_handle_t no_fd_flush( struct fd *fd, const async_data_t *async, int blocking ); extern obj_handle_t no_fd_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async, int blocking ); extern obj_handle_t default_fd_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async, int blocking ); extern void no_fd_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); diff --git a/server/named_pipe.c b/server/named_pipe.c index d47524c2ebe..154eeb9c3f4 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -141,7 +141,7 @@ static const struct object_ops named_pipe_ops = static void pipe_server_dump( struct object *obj, int verbose ); static struct fd *pipe_server_get_fd( struct object *obj ); static void pipe_server_destroy( struct object *obj); -static void pipe_server_flush( struct fd *fd, struct event **event ); +static obj_handle_t pipe_server_flush( struct fd *fd, const async_data_t *async, int blocking ); static enum server_fd_type pipe_server_get_fd_type( struct fd *fd ); static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async, int blocking ); @@ -185,7 +185,7 @@ static void pipe_client_dump( struct object *obj, int verbose ); static int pipe_client_signaled( struct object *obj, struct wait_queue_entry *entry ); static struct fd *pipe_client_get_fd( struct object *obj ); static void pipe_client_destroy( struct object *obj ); -static void pipe_client_flush( struct fd *fd, struct event **event ); +static obj_handle_t pipe_client_flush( struct fd *fd, const async_data_t *async, int blocking ); static enum server_fd_type pipe_client_get_fd_type( struct fd *fd ); static const struct object_ops pipe_client_ops = @@ -555,30 +555,34 @@ static void check_flushed( void *arg ) } } -static void pipe_server_flush( struct fd *fd, struct event **event ) +static obj_handle_t pipe_server_flush( struct fd *fd, const async_data_t *async, int blocking ) { struct pipe_server *server = get_fd_user( fd ); + obj_handle_t handle = 0; - if (!server || server->state != ps_connected_server) return; + if (!server || server->state != ps_connected_server) return 0; /* FIXME: if multiple threads flush the same pipe, maybe should create a list of processes to notify */ - if (server->flush_poll) return; + if (server->flush_poll) return 0; if (pipe_data_remaining( server )) { /* this kind of sux - there's no unix way to be alerted when a pipe becomes empty */ server->event = create_event( NULL, NULL, 0, 0, 0, NULL ); - if (!server->event) return; + if (!server->event) return 0; server->flush_poll = add_timeout_user( -TICKS_PER_SEC / 10, check_flushed, server ); - *event = server->event; + handle = alloc_handle( current->process, server->event, SYNCHRONIZE, 0 ); + set_error( STATUS_PENDING ); } + return handle; } -static void pipe_client_flush( struct fd *fd, struct event **event ) +static obj_handle_t pipe_client_flush( struct fd *fd, const async_data_t *async, int blocking ) { /* FIXME: what do we have to do for this? */ + return 0; } static inline int is_overlapped( unsigned int options ) diff --git a/server/protocol.def b/server/protocol.def index 51ad56bbbf1..3c03977ea0c 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1149,8 +1149,9 @@ enum server_fd_type /* Flush a file buffers */ -@REQ(flush_file) - obj_handle_t handle; /* handle to the file */ +@REQ(flush) + int blocking; /* whether it's a blocking flush */ + async_data_t async; /* async I/O parameters */ @REPLY obj_handle_t event; /* event set when finished */ @END diff --git a/server/request.h b/server/request.h index 0a6096cb104..9ed815ecf5e 100644 --- a/server/request.h +++ b/server/request.h @@ -149,7 +149,7 @@ DECL_HANDLER(open_file_object); DECL_HANDLER(alloc_file_handle); DECL_HANDLER(get_handle_unix_name); DECL_HANDLER(get_handle_fd); -DECL_HANDLER(flush_file); +DECL_HANDLER(flush); DECL_HANDLER(lock_file); DECL_HANDLER(unlock_file); DECL_HANDLER(create_socket); @@ -417,7 +417,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_alloc_file_handle, (req_handler)req_get_handle_unix_name, (req_handler)req_get_handle_fd, - (req_handler)req_flush_file, + (req_handler)req_flush, (req_handler)req_lock_file, (req_handler)req_unlock_file, (req_handler)req_create_socket, @@ -949,10 +949,11 @@ C_ASSERT( FIELD_OFFSET(struct get_handle_fd_reply, cacheable) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_handle_fd_reply, access) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_handle_fd_reply, options) == 20 ); C_ASSERT( sizeof(struct get_handle_fd_reply) == 24 ); -C_ASSERT( FIELD_OFFSET(struct flush_file_request, handle) == 12 ); -C_ASSERT( sizeof(struct flush_file_request) == 16 ); -C_ASSERT( FIELD_OFFSET(struct flush_file_reply, event) == 8 ); -C_ASSERT( sizeof(struct flush_file_reply) == 16 ); +C_ASSERT( FIELD_OFFSET(struct flush_request, blocking) == 12 ); +C_ASSERT( FIELD_OFFSET(struct flush_request, async) == 16 ); +C_ASSERT( sizeof(struct flush_request) == 56 ); +C_ASSERT( FIELD_OFFSET(struct flush_reply, event) == 8 ); +C_ASSERT( sizeof(struct flush_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 27180ed7fc2..8d888d3c971 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1635,12 +1635,13 @@ static void dump_get_handle_fd_reply( const struct get_handle_fd_reply *req ) fprintf( stderr, ", options=%08x", req->options ); } -static void dump_flush_file_request( const struct flush_file_request *req ) +static void dump_flush_request( const struct flush_request *req ) { - fprintf( stderr, " handle=%04x", req->handle ); + fprintf( stderr, " blocking=%d", req->blocking ); + dump_async_data( ", async=", &req->async ); } -static void dump_flush_file_reply( const struct flush_file_reply *req ) +static void dump_flush_reply( const struct flush_reply *req ) { fprintf( stderr, " event=%04x", req->event ); } @@ -4193,7 +4194,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_alloc_file_handle_request, (dump_func)dump_get_handle_unix_name_request, (dump_func)dump_get_handle_fd_request, - (dump_func)dump_flush_file_request, + (dump_func)dump_flush_request, (dump_func)dump_lock_file_request, (dump_func)dump_unlock_file_request, (dump_func)dump_create_socket_request, @@ -4458,7 +4459,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_alloc_file_handle_reply, (dump_func)dump_get_handle_unix_name_reply, (dump_func)dump_get_handle_fd_reply, - (dump_func)dump_flush_file_reply, + (dump_func)dump_flush_reply, (dump_func)dump_lock_file_reply, NULL, (dump_func)dump_create_socket_reply, @@ -4723,7 +4724,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "alloc_file_handle", "get_handle_unix_name", "get_handle_fd", - "flush_file", + "flush", "lock_file", "unlock_file", "create_socket", -- 2.11.4.GIT