Commit 7ec95c5b authored by Alexandre Julliard's avatar Alexandre Julliard

server: Explicitly specify when an ioctl call needs to be blocking.

parent f69e6220
...@@ -1198,6 +1198,7 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event, ...@@ -1198,6 +1198,7 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event,
SERVER_START_REQ( ioctl ) SERVER_START_REQ( ioctl )
{ {
req->code = code; req->code = code;
req->blocking = !apc && !event;
req->async.handle = wine_server_obj_handle( handle ); req->async.handle = wine_server_obj_handle( handle );
req->async.callback = ioctl_completion; req->async.callback = ioctl_completion;
req->async.iosb = io; req->async.iosb = io;
......
...@@ -2710,6 +2710,7 @@ struct ioctl_request ...@@ -2710,6 +2710,7 @@ struct ioctl_request
struct request_header __header; struct request_header __header;
ioctl_code_t code; ioctl_code_t code;
async_data_t async; async_data_t async;
int blocking;
/* VARARG(in_data,bytes); */ /* VARARG(in_data,bytes); */
}; };
struct ioctl_reply struct ioctl_reply
...@@ -5059,6 +5060,6 @@ union generic_reply ...@@ -5059,6 +5060,6 @@ union generic_reply
struct set_window_layered_info_reply set_window_layered_info_reply; struct set_window_layered_info_reply set_window_layered_info_reply;
}; };
#define SERVER_PROTOCOL_VERSION 370 #define SERVER_PROTOCOL_VERSION 371
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -125,7 +125,7 @@ static struct object *device_open_file( struct object *obj, unsigned int access, ...@@ -125,7 +125,7 @@ static struct object *device_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options ); unsigned int sharing, unsigned int options );
static enum server_fd_type device_get_fd_type( struct fd *fd ); static enum server_fd_type device_get_fd_type( struct fd *fd );
static obj_handle_t device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data, static obj_handle_t device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
const void *data, data_size_t size ); int blocking, const void *data, data_size_t size );
static const struct object_ops device_ops = static const struct object_ops device_ops =
{ {
...@@ -308,7 +308,7 @@ static struct ioctl_call *find_ioctl_call( struct device *device, struct thread ...@@ -308,7 +308,7 @@ static struct ioctl_call *find_ioctl_call( struct device *device, struct thread
} }
static obj_handle_t device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data, static obj_handle_t device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
const void *data, data_size_t size ) int blocking, const void *data, data_size_t size )
{ {
struct device *device = get_fd_user( fd ); struct device *device = get_fd_user( fd );
struct ioctl_call *ioctl; struct ioctl_call *ioctl;
......
...@@ -1912,7 +1912,7 @@ static void unmount_device( struct fd *device_fd ) ...@@ -1912,7 +1912,7 @@ static void unmount_device( struct fd *device_fd )
/* default ioctl() routine */ /* default ioctl() routine */
obj_handle_t default_fd_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async, obj_handle_t default_fd_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async,
const void *data, data_size_t size ) int blocking, const void *data, data_size_t size )
{ {
switch(code) switch(code)
{ {
...@@ -2015,7 +2015,7 @@ DECL_HANDLER(ioctl) ...@@ -2015,7 +2015,7 @@ DECL_HANDLER(ioctl)
if (fd) if (fd)
{ {
reply->wait = fd->fd_ops->ioctl( fd, req->code, &req->async, reply->wait = fd->fd_ops->ioctl( fd, req->code, &req->async, req->blocking,
get_req_data(), get_req_data_size() ); get_req_data(), get_req_data_size() );
reply->options = fd->options; reply->options = fd->options;
release_object( fd ); release_object( fd );
......
...@@ -39,7 +39,7 @@ struct fd_ops ...@@ -39,7 +39,7 @@ struct fd_ops
/* get file information */ /* get file information */
enum server_fd_type (*get_fd_type)(struct fd *fd); enum server_fd_type (*get_fd_type)(struct fd *fd);
/* perform an ioctl on the file */ /* perform an ioctl on the file */
obj_handle_t (*ioctl)(struct fd *fd, ioctl_code_t code, const async_data_t *async, obj_handle_t (*ioctl)(struct fd *fd, ioctl_code_t code, const async_data_t *async, int blocking,
const void *data, data_size_t size); const void *data, data_size_t size);
/* queue an async operation */ /* queue an async operation */
void (*queue_async)(struct fd *, const async_data_t *data, int type, int count); void (*queue_async)(struct fd *, const async_data_t *data, int type, int count);
...@@ -79,7 +79,7 @@ extern struct async *fd_queue_async( struct fd *fd, const async_data_t *data, in ...@@ -79,7 +79,7 @@ extern struct async *fd_queue_async( struct fd *fd, const async_data_t *data, in
extern void fd_async_wake_up( struct fd *fd, int type, unsigned int status ); extern void fd_async_wake_up( struct fd *fd, int type, unsigned int status );
extern void fd_reselect_async( struct fd *fd, struct async_queue *queue ); extern void fd_reselect_async( struct fd *fd, struct async_queue *queue );
extern obj_handle_t default_fd_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async, extern obj_handle_t default_fd_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async,
const void *data, data_size_t size ); int blocking, const void *data, data_size_t size );
extern void default_fd_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); extern void default_fd_queue_async( struct fd *fd, const async_data_t *data, int type, int count );
extern void default_fd_reselect_async( struct fd *fd, struct async_queue *queue ); extern void default_fd_reselect_async( struct fd *fd, struct async_queue *queue );
extern void default_fd_cancel_async( struct fd *fd ); extern void default_fd_cancel_async( struct fd *fd );
......
...@@ -140,7 +140,7 @@ static void pipe_server_destroy( struct object *obj); ...@@ -140,7 +140,7 @@ static void pipe_server_destroy( struct object *obj);
static void pipe_server_flush( struct fd *fd, struct event **event ); static void pipe_server_flush( struct fd *fd, struct event **event );
static enum server_fd_type pipe_server_get_fd_type( struct fd *fd ); 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, static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async,
const void *data, data_size_t size ); int blocking, const void *data, data_size_t size );
static const struct object_ops pipe_server_ops = static const struct object_ops pipe_server_ops =
{ {
...@@ -223,7 +223,7 @@ static struct object *named_pipe_device_open_file( struct object *obj, unsigned ...@@ -223,7 +223,7 @@ static struct object *named_pipe_device_open_file( struct object *obj, unsigned
static void named_pipe_device_destroy( struct object *obj ); static void named_pipe_device_destroy( struct object *obj );
static enum server_fd_type named_pipe_device_get_fd_type( struct fd *fd ); static enum server_fd_type named_pipe_device_get_fd_type( struct fd *fd );
static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data, static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
const void *data, data_size_t size ); int blocking, const void *data, data_size_t size );
static const struct object_ops named_pipe_device_ops = static const struct object_ops named_pipe_device_ops =
{ {
...@@ -592,7 +592,7 @@ static obj_handle_t alloc_wait_event( struct process *process ) ...@@ -592,7 +592,7 @@ static obj_handle_t alloc_wait_event( struct process *process )
} }
static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data, static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
const void *data, data_size_t size ) int blocking, const void *data, data_size_t size )
{ {
struct pipe_server *server = get_fd_user( fd ); struct pipe_server *server = get_fd_user( fd );
struct async *async; struct async *async;
...@@ -605,7 +605,7 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a ...@@ -605,7 +605,7 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a
{ {
case ps_idle_server: case ps_idle_server:
case ps_wait_connect: case ps_wait_connect:
if (!async_data->event && !async_data->apc) if (blocking)
{ {
async_data_t new_data = *async_data; async_data_t new_data = *async_data;
if (!(wait_handle = alloc_wait_event( current->process ))) break; if (!(wait_handle = alloc_wait_event( current->process ))) break;
...@@ -673,7 +673,7 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a ...@@ -673,7 +673,7 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a
return 0; return 0;
default: default:
return default_fd_ioctl( fd, code, async_data, data, size ); return default_fd_ioctl( fd, code, async_data, blocking, data, size );
} }
} }
...@@ -854,7 +854,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc ...@@ -854,7 +854,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc
} }
static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data, static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
const void *data, data_size_t size ) int blocking, const void *data, data_size_t size )
{ {
struct named_pipe_device *device = get_fd_user( fd ); struct named_pipe_device *device = get_fd_user( fd );
...@@ -887,7 +887,7 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, c ...@@ -887,7 +887,7 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, c
if (!pipe->waiters && !(pipe->waiters = create_async_queue( NULL ))) goto done; if (!pipe->waiters && !(pipe->waiters = create_async_queue( NULL ))) goto done;
if (!async_data->event && !async_data->apc) if (blocking)
{ {
async_data_t new_data = *async_data; async_data_t new_data = *async_data;
if (!(wait_handle = alloc_wait_event( current->process ))) goto done; if (!(wait_handle = alloc_wait_event( current->process ))) goto done;
...@@ -916,7 +916,7 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, c ...@@ -916,7 +916,7 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, c
} }
default: default:
return default_fd_ioctl( fd, code, async_data, data, size ); return default_fd_ioctl( fd, code, async_data, blocking, data, size );
} }
} }
......
...@@ -2003,6 +2003,7 @@ enum message_type ...@@ -2003,6 +2003,7 @@ enum message_type
@REQ(ioctl) @REQ(ioctl)
ioctl_code_t code; /* ioctl code */ ioctl_code_t code; /* ioctl code */
async_data_t async; /* async I/O parameters */ async_data_t async; /* async I/O parameters */
int blocking; /* whether it's a blocking ioctl */
VARARG(in_data,bytes); /* ioctl input data */ VARARG(in_data,bytes); /* ioctl input data */
@REPLY @REPLY
obj_handle_t wait; /* handle to wait on for blocking ioctl */ obj_handle_t wait; /* handle to wait on for blocking ioctl */
......
...@@ -2591,6 +2591,7 @@ static void dump_ioctl_request( const struct ioctl_request *req ) ...@@ -2591,6 +2591,7 @@ static void dump_ioctl_request( const struct ioctl_request *req )
fprintf( stderr, " async=" ); fprintf( stderr, " async=" );
dump_async_data( &req->async ); dump_async_data( &req->async );
fprintf( stderr, "," ); fprintf( stderr, "," );
fprintf( stderr, " blocking=%d,", req->blocking );
fprintf( stderr, " in_data=" ); fprintf( stderr, " in_data=" );
dump_varargs_bytes( cur_size ); dump_varargs_bytes( cur_size );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment