Make mailslots use as much of the default async fd implementation as
possible.

diff --git a/server/fd.c b/server/fd.c
index 2d31d52..3dcd862 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1409,12 +1409,12 @@
     wake_up( fd->user, 0 );
 }
 
-void default_fd_queue_async( struct fd *fd, void *apc, void *user, void *io_sb, int type, int count )
+void fd_queue_async_timeout( struct fd *fd, void *apc, void *user, void *io_sb, int type, int count, int *timeout )
 {
     struct list *queue;
     int events;
 
-    if (!(fd->fd_ops->get_file_info( fd ) & FD_FLAG_OVERLAPPED))
+    if (!(fd->fd_ops->get_file_info( fd ) & (FD_FLAG_OVERLAPPED|FD_FLAG_TIMEOUT)))
     {
         set_error( STATUS_INVALID_HANDLE );
         return;
@@ -1433,7 +1433,7 @@
         return;
     }
 
-    if (!create_async( current, NULL, queue, apc, user, io_sb ))
+    if (!create_async( current, timeout, queue, apc, user, io_sb ))
         return;
 
     /* Check if the new pending request can be served immediately */
@@ -1443,6 +1443,11 @@
     set_fd_events( fd, fd->fd_ops->get_poll_events( fd ) );
 }
 
+void default_fd_queue_async( struct fd *fd, void *apc, void *user, void *io_sb, int type, int count )
+{
+    fd_queue_async_timeout( fd, apc, user, io_sb, type, count, NULL );
+}
+
 void default_fd_cancel_async( struct fd *fd )
 {
     async_terminate_queue( &fd->read_q, STATUS_CANCELLED );
diff --git a/server/file.h b/server/file.h
index eed81d8..f89940b 100644
--- a/server/file.h
+++ b/server/file.h
@@ -65,6 +65,7 @@
 extern int default_fd_signaled( struct object *obj, struct thread *thread );
 extern int default_fd_get_poll_events( struct fd *fd );
 extern void default_poll_event( struct fd *fd, int event );
+extern void fd_queue_async_timeout( struct fd *fd, void *apc, void *user, void *io_sb, int type, int count, int *timeout );
 extern void default_fd_queue_async( struct fd *fd, void *apc, void *user, void *io_sb, int type, int count );
 extern void default_fd_cancel_async( struct fd *fd );
 extern int no_flush( struct fd *fd, struct event **event );
diff --git a/server/mailslot.c b/server/mailslot.c
index 69b9fea..18b3920 100644
--- a/server/mailslot.c
+++ b/server/mailslot.c
@@ -57,7 +57,6 @@
     unsigned int        max_msgsize;
     unsigned int        read_timeout;
     struct list         writers;
-    struct list         read_q;
 };
 
 /* mailslot functions */
@@ -79,20 +78,17 @@
     mailslot_destroy           /* destroy */
 };
 
-static int mailslot_get_poll_events( struct fd * );
-static void mailslot_poll_event( struct fd *, int );
 static int mailslot_get_info( struct fd * );
 static void mailslot_queue_async( struct fd *, void*, void*, void*, int, int );
-static void mailslot_cancel_async( struct fd * );
 
 static const struct fd_ops mailslot_fd_ops =
 {
-    mailslot_get_poll_events,  /* get_poll_events */
-    mailslot_poll_event,       /* poll_event */
-    no_flush,                  /* flush */
-    mailslot_get_info,         /* get_file_info */
-    mailslot_queue_async,      /* queue_async */
-    mailslot_cancel_async      /* cancel_async */
+    default_fd_get_poll_events, /* get_poll_events */
+    default_poll_event,         /* poll_event */
+    no_flush,                   /* flush */
+    mailslot_get_info,          /* get_file_info */
+    mailslot_queue_async,       /* queue_async */
+    default_fd_cancel_async     /* cancel_async */
 };
 
 struct mail_writer
@@ -141,8 +137,6 @@
     assert( mailslot->fd );
     assert( mailslot->write_fd );
 
-    async_terminate_queue( &mailslot->read_q, STATUS_CANCELLED );
-
     release_object( mailslot->fd );
     release_object( mailslot->write_fd );
 }
@@ -191,33 +185,11 @@
     return (struct fd *)grab_object( mailslot->fd );
 }
 
-static int mailslot_get_poll_events( struct fd *fd )
-{
-    struct mailslot *mailslot = get_fd_user( fd );
-    int events = 0;
-    assert( mailslot->obj.ops == &mailslot_ops );
-
-    if (!list_empty( &mailslot->read_q ))
-        events |= POLLIN;
-
-    return events;
-}
-
-static void mailslot_poll_event( struct fd *fd, int event )
-{
-    struct mailslot *mailslot = get_fd_user( fd );
-
-    if (!list_empty( &mailslot->read_q ) && (POLLIN & event))
-        async_terminate_head( &mailslot->read_q, STATUS_ALERTED );
-
-    set_fd_events( fd, mailslot_get_poll_events(fd) );
-}
-
 static void mailslot_queue_async( struct fd *fd, void *apc, void *user,
                                   void *iosb, int type, int count )
 {
     struct mailslot *mailslot = get_fd_user( fd );
-    int events, *ptimeout = NULL;
+    int *timeout = NULL;
 
     assert(mailslot->obj.ops == &mailslot_ops);
 
@@ -235,28 +207,9 @@
     }
 
     if (mailslot->read_timeout != MAILSLOT_WAIT_FOREVER)
-        ptimeout = &mailslot->read_timeout;
+        timeout = &mailslot->read_timeout;
 
-    if (!create_async( current, ptimeout, &mailslot->read_q, apc, user, iosb ))
-        return;
-
-    /* Check if the new pending request can be served immediately */
-    events = check_fd_events( fd, mailslot_get_poll_events( fd ) );
-    if (events)
-    {
-        mailslot_poll_event( fd, events );
-        return;
-    }
-
-    set_fd_events( fd, mailslot_get_poll_events( fd ));
-}
-
-static void mailslot_cancel_async( struct fd *fd )
-{
-    struct mailslot *mailslot = get_fd_user( fd );
-
-    assert(mailslot->obj.ops == &mailslot_ops);
-    async_terminate_queue( &mailslot->read_q, STATUS_CANCELLED );
+    fd_queue_async_timeout( fd, apc, user, iosb, type, count, timeout );
 }
 
 static struct mailslot *create_mailslot( const WCHAR *name, size_t len, int max_msgsize,
@@ -288,7 +241,6 @@
     mailslot->max_msgsize = max_msgsize;
     mailslot->read_timeout = read_timeout;
     list_init( &mailslot->writers );
-    list_init( &mailslot->read_q );
 
     if (!socketpair( PF_UNIX, SOCK_DGRAM, 0, fds ))
     {