diff --git a/server/async.c b/server/async.c
index 838cc6b579b89910fe7012b42fa4fc20592c28eb..a4d0235f0557c2514464fd51953de537ff27c4ac 100644
--- a/server/async.c
+++ b/server/async.c
@@ -47,6 +47,7 @@ struct async
     int                     count;
     int                     eventmask;
     struct async           *next;
+    struct timeval          tv;
     struct timeout_user    *timeout;
     struct wait_queue_entry wait;
     void                   *buffer;
@@ -61,6 +62,7 @@ static int async_get_poll_events( struct object *obj );
 static int async_get_fd( struct object *obj );
 static int async_get_info( struct object *obj, struct get_file_info_request *req );
 static void async_poll_event( struct object *obj, int event );
+static void overlapped_timeout (void *private);
 
 static const struct object_ops async_ops =
 {
@@ -95,8 +97,10 @@ static void async_destroy( struct object *obj )
     assert( obj->ops == &async_ops );
 
     if(ov->timeout)
+    {
         remove_timeout_user(ov->timeout);
-    ov->timeout = NULL;
+        ov->timeout = NULL;
+    }
 }
 
 struct async *get_async_obj( struct process *process, handle_t handle, unsigned int access )
@@ -198,10 +202,17 @@ DECL_HANDLER(create_async)
     ov->file    = obj;
     ov->buffer  = req->buffer;
     ov->count   = req->count;
+    ov->tv.tv_sec = 0;
+    ov->tv.tv_usec = 0;
 
     /* FIXME: this should be a function pointer */
     serial_async_setup(obj,ov);
 
+    if( ov->tv.tv_sec || ov->tv.tv_usec )
+    {
+        ov->timeout = add_timeout_user(&ov->tv, overlapped_timeout, ov);
+    }
+
     ov->obj.ops->add_queue(&ov->obj,&ov->wait);
 
     req->ov_handle = alloc_handle( current->process, ov, GENERIC_READ|GENERIC_WRITE, 0 );
@@ -216,6 +227,11 @@ static void async_poll_event( struct object *obj, int event )
 
     /* queue an APC in the client thread to do our dirty work */
     ov->obj.ops->remove_queue(&ov->obj,&ov->wait);
+    if(ov->timeout)
+    {
+        remove_timeout_user(ov->timeout);
+        ov->timeout = NULL;
+    }
 
     /* FIXME: this should be a function pointer */
     event = serial_async_poll_event(obj,event);
@@ -230,6 +246,7 @@ static void overlapped_timeout (void *private)
     struct async *ov = (struct async *) private;
 
     ov->obj.ops->remove_queue(&ov->obj,&ov->wait);
+    ov->timeout = NULL;
 
     thread_queue_apc(ov->thread, NULL, ov->func, APC_ASYNC, 1, 3,
                      ov->client_overlapped,ov->buffer, 0);
@@ -237,11 +254,11 @@ static void overlapped_timeout (void *private)
 
 void async_add_timeout(struct async *ov, int timeout)
 {
-    struct timeval tv;
-
-    gettimeofday(&tv,0);
-    add_timeout(&tv,timeout);
-    ov->timeout = add_timeout_user(&tv, overlapped_timeout, ov);
+    if(timeout)
+    {
+        gettimeofday(&ov->tv,0);
+        add_timeout(&ov->tv,timeout);
+    }
 }
 
 DECL_HANDLER(async_result)
@@ -254,6 +271,10 @@ DECL_HANDLER(async_result)
         if(ov->result == STATUS_PENDING)
         {
             ov->obj.ops->add_queue(&ov->obj,&ov->wait);
+            if( (ov->tv.tv_sec || ov->tv.tv_usec) && !ov->timeout)
+            {
+                ov->timeout = add_timeout_user(&ov->tv, overlapped_timeout, ov);
+            }
         }
         release_object( ov );
     }