server: Add an async structure to the flush request to follow the common pattern.

This commit is contained in:
Alexandre Julliard 2015-05-05 12:23:08 +09:00
parent 837b39b202
commit 860091d2fd
9 changed files with 55 additions and 46 deletions

View File

@ -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;
}
}

View File

@ -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 */

View File

@ -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 );
}
}

View File

@ -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 )

View File

@ -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 );

View File

@ -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 )

View File

@ -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

View File

@ -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 );

View File

@ -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",