Commit 795e9de8 authored by Robert Shearman's avatar Robert Shearman Committed by Alexandre Julliard

Support WaitNamedPipe timeouts.

parent 5f35a32f
...@@ -91,6 +91,7 @@ struct connect_wait ...@@ -91,6 +91,7 @@ struct connect_wait
{ {
struct list entry; /* entry in named pipe wait list */ struct list entry; /* entry in named pipe wait list */
struct wait_info wait; struct wait_info wait;
struct timeout_user *timeout_user;
}; };
struct named_pipe struct named_pipe
...@@ -223,37 +224,63 @@ static void set_waiter( struct wait_info *wait, void *func, void *ov ) ...@@ -223,37 +224,63 @@ static void set_waiter( struct wait_info *wait, void *func, void *ov )
wait->overlapped = ov; wait->overlapped = ov;
} }
static void notify_connect_waiters( struct named_pipe *pipe, unsigned int status ) static void notify_connect_waiter( struct connect_wait *waiter, unsigned int status )
{
notify_waiter( &waiter->wait, status );
list_remove( &waiter->entry );
free( waiter );
}
static void notify_all_connect_waiters( struct named_pipe *pipe, unsigned int status )
{ {
struct list *ptr; struct list *ptr;
while ((ptr = list_head( &pipe->waiters )) != NULL) while ((ptr = list_head( &pipe->waiters )) != NULL)
{ {
struct connect_wait *waiter = LIST_ENTRY( ptr, struct connect_wait, entry ); struct connect_wait *waiter = LIST_ENTRY( ptr, struct connect_wait, entry );
notify_waiter( &waiter->wait, status ); if (waiter->timeout_user) remove_timeout_user( waiter->timeout_user );
list_remove( &waiter->entry ); notify_connect_waiter( waiter, status );
free( waiter );
} }
} }
/* pipe connect wait timeout */
static void connect_timeout( void *ptr )
{
struct connect_wait *waiter = (struct connect_wait *)ptr;
notify_connect_waiter( waiter, STATUS_TIMEOUT );
}
static void named_pipe_destroy( struct object *obj) static void named_pipe_destroy( struct object *obj)
{ {
struct named_pipe *pipe = (struct named_pipe *) obj; struct named_pipe *pipe = (struct named_pipe *) obj;
assert( list_empty( &pipe->servers ) ); assert( list_empty( &pipe->servers ) );
assert( !pipe->instances ); assert( !pipe->instances );
notify_connect_waiters( pipe, STATUS_HANDLES_CLOSED ); notify_all_connect_waiters( pipe, STATUS_HANDLES_CLOSED );
} }
static void queue_connect_waiter( struct named_pipe *pipe, void *func, void *overlapped ) static void queue_connect_waiter( struct named_pipe *pipe, void *func,
void *overlapped, unsigned int *timeout )
{ {
struct connect_wait *waiter; struct connect_wait *waiter;
waiter = mem_alloc( sizeof(*waiter) ); waiter = mem_alloc( sizeof(*waiter) );
if( waiter ) if( waiter )
{ {
struct timeval tv;
set_waiter( &waiter->wait, func, overlapped ); set_waiter( &waiter->wait, func, overlapped );
list_add_tail( &pipe->waiters, &waiter->entry ); list_add_tail( &pipe->waiters, &waiter->entry );
if (timeout)
{
gettimeofday( &tv, 0 );
add_timeout( &tv, *timeout );
waiter->timeout_user = add_timeout_user( &tv, connect_timeout,
waiter );
}
else
waiter->timeout_user = NULL;
} }
} }
...@@ -695,7 +722,7 @@ DECL_HANDLER(connect_named_pipe) ...@@ -695,7 +722,7 @@ DECL_HANDLER(connect_named_pipe)
assert( !server->fd ); assert( !server->fd );
server->state = ps_wait_open; server->state = ps_wait_open;
set_waiter( &server->wait, req->func, req->overlapped ); set_waiter( &server->wait, req->func, req->overlapped );
notify_connect_waiters( server->pipe, STATUS_SUCCESS ); notify_all_connect_waiters( server->pipe, STATUS_SUCCESS );
break; break;
case ps_connected_server: case ps_connected_server:
assert( server->fd ); assert( server->fd );
...@@ -735,7 +762,18 @@ DECL_HANDLER(wait_named_pipe) ...@@ -735,7 +762,18 @@ DECL_HANDLER(wait_named_pipe)
release_object( server ); release_object( server );
} }
else else
queue_connect_waiter( pipe, req->func, req->overlapped ); {
unsigned int timeout;
if (req->timeout == NMPWAIT_USE_DEFAULT_WAIT)
timeout = pipe->timeout;
else
timeout = req->timeout;
if (req->timeout == NMPWAIT_WAIT_FOREVER)
queue_connect_waiter( pipe, req->func, req->overlapped, NULL );
else
queue_connect_waiter( pipe, req->func, req->overlapped, &timeout );
}
release_object( pipe ); release_object( pipe );
} }
......
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