Commit 4e5c7038 authored by Alexandre Julliard's avatar Alexandre Julliard

server: Make timeout status for async I/O specifiable. Fix mailslots timeout handling.

parent 3040e09a
...@@ -299,7 +299,7 @@ static int mailslot_test(void) ...@@ -299,7 +299,7 @@ static int mailslot_test(void)
ok( !ReadFile( hSlot, buffer, sizeof buffer, &count, NULL), "slot read\n"); ok( !ReadFile( hSlot, buffer, sizeof buffer, &count, NULL), "slot read\n");
ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError() ); ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError() );
dwTimeout = GetTickCount() - dwTimeout; dwTimeout = GetTickCount() - dwTimeout;
todo_wine ok( dwTimeout >= 1000, "timeout too short %u\n", dwTimeout ); ok( dwTimeout >= 1000, "timeout too short %u\n", dwTimeout );
ok( CloseHandle( hSlot ), "closing the mailslot\n"); ok( CloseHandle( hSlot ), "closing the mailslot\n");
return 0; return 0;
......
...@@ -38,6 +38,7 @@ struct async ...@@ -38,6 +38,7 @@ struct async
struct thread *thread; /* owning thread */ struct thread *thread; /* owning thread */
struct list queue_entry; /* entry in file descriptor queue */ struct list queue_entry; /* entry in file descriptor queue */
struct timeout_user *timeout; struct timeout_user *timeout;
unsigned int timeout_status; /* status to report upon timeout */
struct event *event; struct event *event;
async_data_t data; /* data for async I/O call */ async_data_t data; /* data for async I/O call */
}; };
...@@ -149,7 +150,7 @@ static void async_timeout( void *private ) ...@@ -149,7 +150,7 @@ static void async_timeout( void *private )
struct async *async = private; struct async *async = private;
async->timeout = NULL; async->timeout = NULL;
async_terminate( async, STATUS_TIMEOUT ); async_terminate( async, async->timeout_status );
} }
/* create a new async queue for a given fd */ /* create a new async queue for a given fd */
...@@ -193,11 +194,12 @@ struct async *create_async( struct thread *thread, struct async_queue *queue, co ...@@ -193,11 +194,12 @@ struct async *create_async( struct thread *thread, struct async_queue *queue, co
} }
/* set the timeout of an async operation */ /* set the timeout of an async operation */
void async_set_timeout( struct async *async, const struct timeval *timeout ) void async_set_timeout( struct async *async, const struct timeval *timeout, unsigned int status )
{ {
if (async->timeout) remove_timeout_user( async->timeout ); if (async->timeout) remove_timeout_user( async->timeout );
if (timeout) async->timeout = add_timeout_user( timeout, async_timeout, async ); if (timeout) async->timeout = add_timeout_user( timeout, async_timeout, async );
else async->timeout = NULL; else async->timeout = NULL;
async->timeout_status = status;
} }
/* store the result of the client-side async callback */ /* store the result of the client-side async callback */
......
...@@ -126,7 +126,8 @@ extern struct object *create_serial( struct fd *fd, unsigned int options ); ...@@ -126,7 +126,8 @@ extern struct object *create_serial( struct fd *fd, unsigned int options );
extern struct async_queue *create_async_queue( struct fd *fd ); extern struct async_queue *create_async_queue( struct fd *fd );
extern struct async *create_async( struct thread *thread, struct async_queue *queue, extern struct async *create_async( struct thread *thread, struct async_queue *queue,
const async_data_t *data ); const async_data_t *data );
extern void async_set_timeout( struct async *async, const struct timeval *timeout ); extern void async_set_timeout( struct async *async, const struct timeval *timeout,
unsigned int status );
extern void async_set_result( struct object *obj, unsigned int status ); extern void async_set_result( struct object *obj, unsigned int status );
extern int async_waiting( struct async_queue *queue ); extern int async_waiting( struct async_queue *queue );
extern void async_wake_up( struct async_queue *queue, unsigned int status ); extern void async_wake_up( struct async_queue *queue, unsigned int status );
......
...@@ -208,17 +208,6 @@ static void mailslot_dump( struct object *obj, int verbose ) ...@@ -208,17 +208,6 @@ static void mailslot_dump( struct object *obj, int verbose )
mailslot->max_msgsize, mailslot->read_timeout ); mailslot->max_msgsize, mailslot->read_timeout );
} }
static int mailslot_message_count(struct mailslot *mailslot)
{
struct pollfd pfd;
/* poll the socket to see if there's any messages */
pfd.fd = get_unix_fd( mailslot->fd );
pfd.events = POLLIN;
pfd.revents = 0;
return (poll( &pfd, 1, 0 ) == 1) ? 1 : 0;
}
static enum server_fd_type mailslot_get_info( struct fd *fd, int *flags ) static enum server_fd_type mailslot_get_info( struct fd *fd, int *flags )
{ {
struct mailslot *mailslot = get_fd_user( fd ); struct mailslot *mailslot = get_fd_user( fd );
...@@ -286,20 +275,13 @@ static void mailslot_queue_async( struct fd *fd, const async_data_t *data, int t ...@@ -286,20 +275,13 @@ static void mailslot_queue_async( struct fd *fd, const async_data_t *data, int t
assert(mailslot->obj.ops == &mailslot_ops); assert(mailslot->obj.ops == &mailslot_ops);
if (list_empty( &mailslot->writers ) ||
!mailslot_message_count( mailslot ))
{
set_error(STATUS_IO_TIMEOUT);
return;
}
if ((async = fd_queue_async( fd, data, type, count ))) if ((async = fd_queue_async( fd, data, type, count )))
{ {
if (mailslot->read_timeout != -1) if (mailslot->read_timeout != -1)
{ {
struct timeval when = current_time; struct timeval when = current_time;
add_timeout( &when, max(1,mailslot->read_timeout) ); add_timeout( &when, max(1,mailslot->read_timeout) );
async_set_timeout( async, &when ); async_set_timeout( async, &when, STATUS_IO_TIMEOUT );
} }
release_object( async ); release_object( async );
set_error( STATUS_PENDING ); set_error( STATUS_PENDING );
......
...@@ -867,7 +867,7 @@ DECL_HANDLER(wait_named_pipe) ...@@ -867,7 +867,7 @@ DECL_HANDLER(wait_named_pipe)
struct timeval when = current_time; struct timeval when = current_time;
if (req->timeout == NMPWAIT_USE_DEFAULT_WAIT) add_timeout( &when, pipe->timeout ); if (req->timeout == NMPWAIT_USE_DEFAULT_WAIT) add_timeout( &when, pipe->timeout );
else add_timeout( &when, req->timeout ); else add_timeout( &when, req->timeout );
async_set_timeout( async, &when ); async_set_timeout( async, &when, STATUS_TIMEOUT );
} }
release_object( async ); release_object( async );
set_error( STATUS_PENDING ); set_error( STATUS_PENDING );
......
...@@ -219,7 +219,7 @@ static void serial_queue_async( struct fd *fd, const async_data_t *data, int typ ...@@ -219,7 +219,7 @@ static void serial_queue_async( struct fd *fd, const async_data_t *data, int typ
{ {
struct timeval when = current_time; struct timeval when = current_time;
add_timeout( &when, timeout ); add_timeout( &when, timeout );
async_set_timeout( async, &when ); async_set_timeout( async, &when, STATUS_TIMEOUT );
} }
release_object( async ); release_object( async );
set_error( STATUS_PENDING ); set_error( STATUS_PENDING );
......
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