server: Explicitly specify when an ioctl call needs to be blocking.
This commit is contained in:
parent
f69e62207b
commit
7ec95c5bee
|
@ -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
|
||||||
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
|
||||||
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,
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
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 )
|
||||||
|
|
||||||
/* 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)
|
||||||
|
|
||||||
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
|
||||||
/* 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
|
||||||
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);
|
||||||
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
|
||||||
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 )
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
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
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
@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 )
|
||||||
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 );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue