From ad744b5d30474d7f46bf69dcdf829aa75b813879 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] 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 ea7517d3f1d2..94838d322132 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 44a65711c908..c24d4c807348 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1567,6 +1567,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 dd5db3f18f32..e9262de93da9 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -267,6 +267,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 0bc3971508fd..a3dd918fdf58 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -438,6 +438,7 @@ TEB *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;
 
     unix_funcs->dbg_init();
     unix_funcs->get_paths( &build_dir, &data_dir, &config_dir );
@@ -745,6 +746,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 c1e7b000a8f3..d96f001432d4 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 694a46b11e64..64b8d69b16de 100644
--- a/dlls/winemac.drv/macdrv_main.c
+++ b/dlls/winemac.drv/macdrv_main.c
@@ -323,6 +323,7 @@ void CDECL macdrv_ThreadDetach(void)
     }
 }
 
+extern void __wine_esync_set_queue_fd( int fd );
 
 /***********************************************************************
  *              set_queue_display_fd
@@ -334,6 +335,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 4eaedd1c5567..323b71534ace 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -643,6 +643,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 )
@@ -650,6 +651,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.26.2

