server: Support FILE_SKIP_COMPLETION_PORT_ON_SUCCESS on server-side asyncs.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=38960 Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4be482bc82
commit
c0996553a1
|
@ -1287,7 +1287,6 @@ static void test_completion(void)
|
|||
ret = WriteFile(client, buf, sizeof(buf), &num_bytes, &ov);
|
||||
ok(ret, "WriteFile failed, error %u\n", GetLastError());
|
||||
ok(num_bytes == sizeof(buf), "expected sizeof(buf), got %u\n", num_bytes);
|
||||
todo_wine
|
||||
test_no_queued_completion(port);
|
||||
|
||||
ret = WriteFile(pipe, buf, sizeof(buf), &num_bytes, &ov);
|
||||
|
@ -1301,14 +1300,12 @@ static void test_completion(void)
|
|||
if(status == STATUS_PENDING) /* win8+ */
|
||||
test_queued_completion(port, &io, STATUS_BUFFER_OVERFLOW, 1);
|
||||
else
|
||||
todo_wine
|
||||
test_no_queued_completion(port);
|
||||
|
||||
status = NtReadFile(client, NULL, NULL, &io, &io, read_buf, sizeof(read_buf), NULL, NULL);
|
||||
ok(status == STATUS_SUCCESS, "status = %x\n", status);
|
||||
ok(io.Status == STATUS_SUCCESS, "Status = %x\n", io.Status);
|
||||
ok(io.Information == sizeof(buf)-1, "Information = %lu\n", io.Information);
|
||||
todo_wine
|
||||
test_no_queued_completion(port);
|
||||
|
||||
status = NtFsControlFile(client, NULL, NULL, &io, &io, FSCTL_PIPE_PEEK,
|
||||
|
@ -1317,7 +1314,6 @@ static void test_completion(void)
|
|||
if(status == STATUS_PENDING) /* win8+ */
|
||||
test_queued_completion(port, &io, STATUS_SUCCESS, FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data));
|
||||
else
|
||||
todo_wine
|
||||
test_no_queued_completion(port);
|
||||
|
||||
memset(&io, 0xcc, sizeof(io));
|
||||
|
@ -1339,7 +1335,6 @@ static void test_completion(void)
|
|||
if(status == STATUS_PENDING) /* win8+ */
|
||||
test_queued_completion(port, &io, STATUS_BUFFER_OVERFLOW, sizeof(peek_buf));
|
||||
else
|
||||
todo_wine
|
||||
test_no_queued_completion(port);
|
||||
|
||||
CloseHandle(ov.hEvent);
|
||||
|
|
|
@ -53,6 +53,7 @@ struct async
|
|||
int direct_result; /* a flag if we're passing result directly from request instead of APC */
|
||||
struct completion *completion; /* completion associated with fd */
|
||||
apc_param_t comp_key; /* completion key associated with fd */
|
||||
unsigned int comp_flags; /* completion flags */
|
||||
};
|
||||
|
||||
static void async_dump( struct object *obj, int verbose );
|
||||
|
@ -239,6 +240,7 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da
|
|||
async->wait_handle = 0;
|
||||
async->direct_result = 0;
|
||||
async->completion = fd_get_completion( fd, &async->comp_key );
|
||||
async->comp_flags = 0;
|
||||
|
||||
if (iosb) async->iosb = (struct iosb *)grab_object( iosb );
|
||||
else async->iosb = NULL;
|
||||
|
@ -258,7 +260,7 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da
|
|||
|
||||
/* create an async associated with iosb for async-based requests
|
||||
* returned async must be passed to async_handoff */
|
||||
struct async *create_request_async( struct fd *fd, const async_data_t *data )
|
||||
struct async *create_request_async( struct fd *fd, unsigned int comp_flags, const async_data_t *data )
|
||||
{
|
||||
struct async *async;
|
||||
struct iosb *iosb;
|
||||
|
@ -276,6 +278,7 @@ struct async *create_request_async( struct fd *fd, const async_data_t *data )
|
|||
return NULL;
|
||||
}
|
||||
async->direct_result = 1;
|
||||
async->comp_flags = comp_flags;
|
||||
}
|
||||
return async;
|
||||
}
|
||||
|
@ -377,8 +380,11 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota
|
|||
data.user.args[2] = 0;
|
||||
thread_queue_apc( NULL, async->thread, NULL, &data );
|
||||
}
|
||||
else if (async->data.apc_context)
|
||||
else if (async->data.apc_context && (!async->direct_result ||
|
||||
!(async->comp_flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)))
|
||||
{
|
||||
add_async_completion( async, async->data.apc_context, status, total );
|
||||
}
|
||||
|
||||
if (async->event) set_event( async->event );
|
||||
else if (async->fd) set_fd_signaled( async->fd, 1 );
|
||||
|
|
|
@ -2414,7 +2414,7 @@ DECL_HANDLER(flush)
|
|||
|
||||
if (!fd) return;
|
||||
|
||||
if ((async = create_request_async( fd, &req->async )))
|
||||
if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
|
||||
{
|
||||
reply->event = async_handoff( async, fd->fd_ops->flush( fd, async ), NULL );
|
||||
release_object( async );
|
||||
|
@ -2513,7 +2513,7 @@ DECL_HANDLER(read)
|
|||
|
||||
if (!fd) return;
|
||||
|
||||
if ((async = create_request_async( fd, &req->async )))
|
||||
if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
|
||||
{
|
||||
reply->wait = async_handoff( async, fd->fd_ops->read( fd, async, req->pos ), NULL );
|
||||
reply->options = fd->options;
|
||||
|
@ -2530,7 +2530,7 @@ DECL_HANDLER(write)
|
|||
|
||||
if (!fd) return;
|
||||
|
||||
if ((async = create_request_async( fd, &req->async )))
|
||||
if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
|
||||
{
|
||||
reply->wait = async_handoff( async, fd->fd_ops->write( fd, async, req->pos ), &reply->size );
|
||||
reply->options = fd->options;
|
||||
|
@ -2548,7 +2548,7 @@ DECL_HANDLER(ioctl)
|
|||
|
||||
if (!fd) return;
|
||||
|
||||
if ((async = create_request_async( fd, &req->async )))
|
||||
if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
|
||||
{
|
||||
reply->wait = async_handoff( async, fd->fd_ops->ioctl( fd, req->code, async ), NULL );
|
||||
reply->options = fd->options;
|
||||
|
|
|
@ -185,7 +185,7 @@ extern struct object *create_serial( struct fd *fd );
|
|||
/* async I/O functions */
|
||||
extern void free_async_queue( struct async_queue *queue );
|
||||
extern struct async *create_async( struct fd *fd, struct thread *thread, const async_data_t *data, struct iosb *iosb );
|
||||
extern struct async *create_request_async( struct fd *fd, const async_data_t *data );
|
||||
extern struct async *create_request_async( struct fd *fd, unsigned int comp_flags, const async_data_t *data );
|
||||
extern obj_handle_t async_handoff( struct async *async, int success, data_size_t *result );
|
||||
extern void queue_async( struct async_queue *queue, struct async *async );
|
||||
extern void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status );
|
||||
|
|
Loading…
Reference in New Issue