From 6c3029fe763d6c94016a038d016eb810ad8e38ef Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Fri, 15 Jun 2018 11:01:44 -0500
Subject: [PATCH] server: Create eventfd descriptors for timers.

---
 dlls/ntdll/esync.c  |  1 +
 server/protocol.def |  1 +
 server/timer.c      | 18 +++++++++++++++++-
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/dlls/ntdll/esync.c b/dlls/ntdll/esync.c
index 17890f9e1f0..c1d8882d817 100644
--- a/dlls/ntdll/esync.c
+++ b/dlls/ntdll/esync.c
@@ -241,6 +241,7 @@ static NTSTATUS get_waitable_object( HANDLE handle, struct esync **obj )
         esync = &mutex->obj;
         break;
     }
+    case ESYNC_AUTO_SERVER:
     case ESYNC_MANUAL_SERVER:
     case ESYNC_QUEUE:
         esync = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*esync) );
diff --git a/server/protocol.def b/server/protocol.def
index 0ab32aaca64..eb80c81d6e6 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -4080,6 +4080,7 @@ enum esync_type
     ESYNC_AUTO_EVENT,
     ESYNC_MANUAL_EVENT,
     ESYNC_MUTEX,
+    ESYNC_AUTO_SERVER,
     ESYNC_MANUAL_SERVER,
     ESYNC_QUEUE,
 };
diff --git a/server/timer.c b/server/timer.c
index 2614e145c40..c3ebd3f52d3 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -36,6 +36,7 @@
 #include "file.h"
 #include "handle.h"
 #include "request.h"
+#include "esync.h"
 
 struct timer
 {
@@ -48,11 +49,13 @@ struct timer
     struct thread       *thread;    /* thread that set the APC function */
     client_ptr_t         callback;  /* callback APC function */
     client_ptr_t         arg;       /* callback argument */
+    int                  esync_fd;  /* esync file descriptor */
 };
 
 static void timer_dump( struct object *obj, int verbose );
 static struct object_type *timer_get_type( struct object *obj );
 static int timer_signaled( struct object *obj, struct wait_queue_entry *entry );
+static int timer_get_esync_fd( struct object *obj, enum esync_type *type );
 static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry );
 static unsigned int timer_map_access( struct object *obj, unsigned int access );
 static void timer_destroy( struct object *obj );
@@ -65,7 +68,7 @@ static const struct object_ops timer_ops =
     add_queue,                 /* add_queue */
     remove_queue,              /* remove_queue */
     timer_signaled,            /* signaled */
-    NULL,                      /* get_esync_fd */
+    timer_get_esync_fd,        /* get_esync_fd */
     timer_satisfied,           /* satisfied */
     no_signal,                 /* signal */
     no_get_fd,                 /* get_fd */
@@ -99,6 +102,9 @@ static struct timer *create_timer( struct object *root, const struct unicode_str
             timer->period   = 0;
             timer->timeout  = NULL;
             timer->thread   = NULL;
+
+            if (do_esync())
+                timer->esync_fd = esync_create_fd( 0, 0 );
         }
     }
     return timer;
@@ -172,6 +178,9 @@ static int set_timer( struct timer *timer, timeout_t expire, unsigned int period
     {
         period = 0;  /* period doesn't make any sense for a manual timer */
         timer->signaled = 0;
+
+        if (do_esync())
+            esync_clear( timer->esync_fd );
     }
     timer->when     = (expire <= 0) ? expire - monotonic_time : max( expire, current_time );
     timer->period   = period;
@@ -205,6 +214,13 @@ static int timer_signaled( struct object *obj, struct wait_queue_entry *entry )
     return timer->signaled;
 }
 
+static int timer_get_esync_fd( struct object *obj, enum esync_type *type )
+{
+    struct timer *timer = (struct timer *)obj;
+    *type = timer->manual ? ESYNC_MANUAL_SERVER : ESYNC_AUTO_SERVER;
+    return timer->esync_fd;
+}
+
 static void timer_satisfied( struct object *obj, struct wait_queue_entry *entry )
 {
     struct timer *timer = (struct timer *)obj;
-- 
2.26.0

