From 86714f32b54c3135e5626f66f65ae5daf946f744 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Tue, 12 Jun 2018 10:01:08 -0500
Subject: [PATCH 23/83] ntdll, wineandroid.drv, winemac.drv, winex11.drv: Store
 the thread's queue fd in ntdll.

I originally had esync grab it from the server in order to avoid touching the USER drivers, but this doesn't really work since we might perform a MsgWait before ever doing any operations which might initialize the USER driver's thread data. Doing it this way also has the advantage that we won't use extra file descriptors.

In any case I haven't bothered to guard this code with do_esync(); it'd require adding that function to each USER driver and it's pretty obvious it's not going to affect anything if esync is disabled.
---
 dlls/ntdll/esync.c             | 6 ++++++
 dlls/ntdll/ntdll.spec          | 2 ++
 dlls/ntdll/ntdll_misc.h        | 1 +
 dlls/ntdll/thread.c            | 2 ++
 dlls/wineandroid.drv/window.c  | 3 +++
 dlls/winemac.drv/macdrv_main.c | 3 +++
 dlls/winex11.drv/x11drv_main.c | 3 +++
 7 files changed, 20 insertions(+)

diff --git a/dlls/ntdll/esync.c b/dlls/ntdll/esync.c
index 0655ab779..210556fc2 100644
--- a/dlls/ntdll/esync.c
+++ b/dlls/ntdll/esync.c
@@ -74,6 +74,12 @@ int do_esync(void)
 #endif
 }
 
+/* Entry point for drivers to set queue fd. */
+void __wine_esync_set_queue_fd( int fd )
+{
+    ntdll_get_thread_data()->esync_queue_fd = fd;
+}
+
 enum esync_type
 {
     ESYNC_SEMAPHORE = 1,
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 74cebfc42..343ab66a5 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1498,6 +1498,8 @@
 # All functions must be prefixed with '__wine_' (for internal functions)
 # or 'wine_' (for user-visible functions) to avoid namespace conflicts.
 
+@ cdecl __wine_esync_set_queue_fd(long)
+
 # Server interface
 @ cdecl -norelay wine_server_call(ptr)
 @ cdecl wine_server_close_fds_by_type(long)
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index dad0996c4..e2ef7d9b8 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -280,6 +280,7 @@ struct debug_info
 struct ntdll_thread_data
 {
     struct debug_info *debug_info;    /* info for debugstr functions */
+    int                esync_queue_fd;/* fd to wait on for driver events */
     void              *start_stack;   /* stack for thread startup */
     int                request_fd;    /* fd for sending server requests */
     int                reply_fd;      /* fd for receiving server replies */
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index a1ff7c1dd..87134db09 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -326,6 +326,7 @@ void thread_init(void)
     thread_data->reply_fd   = -1;
     thread_data->wait_fd[0] = -1;
     thread_data->wait_fd[1] = -1;
+    thread_data->esync_queue_fd = -1;
 
     signal_init_thread( teb );
     virtual_init_threading();
@@ -694,6 +695,7 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle_ptr, ACCESS_MASK access, OBJECT
     thread_data->wait_fd[0]  = -1;
     thread_data->wait_fd[1]  = -1;
     thread_data->start_stack = (char *)teb->Tib.StackBase;
+    thread_data->esync_queue_fd = -1;
 
     pthread_attr_init( &pthread_attr );
     pthread_attr_setstack( &pthread_attr, teb->DeallocationStack,
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c
index eb05aaf28..2fc258dfd 100644
--- a/dlls/wineandroid.drv/window.c
+++ b/dlls/wineandroid.drv/window.c
@@ -364,6 +364,8 @@ jboolean motion_event( JNIEnv *env, jobject obj, jint win, jint action, jint x,
 }
 
 
+extern void __wine_esync_set_queue_fd( int fd );
+
 /***********************************************************************
  *           init_event_queue
  */
@@ -377,6 +379,7 @@ static void init_event_queue(void)
         ERR( "could not create data\n" );
         ExitProcess(1);
     }
+    __wine_esync_set_queue_fd( event_pipe[0] );
     if (wine_server_fd_to_handle( event_pipe[0], GENERIC_READ | SYNCHRONIZE, 0, &handle ))
     {
         ERR( "Can't allocate handle for event fd\n" );
diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c
index 544d448f9..5dfa54966 100644
--- a/dlls/winemac.drv/macdrv_main.c
+++ b/dlls/winemac.drv/macdrv_main.c
@@ -321,6 +321,7 @@ void CDECL macdrv_ThreadDetach(void)
     }
 }
 
+extern void __wine_esync_set_queue_fd( int fd );
 
 /***********************************************************************
  *              set_queue_display_fd
@@ -332,6 +333,8 @@ static void set_queue_display_fd(int fd)
     HANDLE handle;
     int ret;
 
+    __wine_esync_set_queue_fd(fd);
+
     if (wine_server_fd_to_handle(fd, GENERIC_READ | SYNCHRONIZE, 0, &handle))
     {
         MESSAGE("macdrv: Can't allocate handle for event queue fd\n");
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 40cd8ca29..18c98e3ec 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -624,6 +624,7 @@ void CDECL X11DRV_ThreadDetach(void)
     }
 }
 
+extern void __wine_esync_set_queue_fd( int fd );
 
 /* store the display fd into the message queue */
 static void set_queue_display_fd( Display *display )
@@ -631,6 +632,8 @@ static void set_queue_display_fd( Display *display )
     HANDLE handle;
     int ret;
 
+    __wine_esync_set_queue_fd( ConnectionNumber(display) );
+
     if (wine_server_fd_to_handle( ConnectionNumber(display), GENERIC_READ | SYNCHRONIZE, 0, &handle ))
     {
         MESSAGE( "x11drv: Can't allocate handle for display fd\n" );
-- 
2.20.1

