Browse Source

Work around shutdown hang when compiling with SIMPLE_THREADS=1

This is a workaround for a specific case of #508
rdb 6 years ago
parent
commit
dc599901bc

+ 17 - 0
panda/src/device/winInputDeviceManager.cxx

@@ -464,6 +464,23 @@ destroy_message_loop() {
   }
 }
 
+/**
+ * Sends a signal to the thread input thread, asking it to shut itself down.
+ */
+void WinInputDeviceManager::
+stop_thread() {
+#ifdef HAVE_THREADS
+  WinInputDeviceManager *mgr = (WinInputDeviceManager *)_global_ptr;
+  if (mgr != nullptr) {
+    LightMutexHolder holder(mgr->_lock);
+    HWND hwnd = mgr->_message_hwnd;
+    if (hwnd) {
+      PostMessage(hwnd, WM_QUIT, 0, 0);
+    }
+  }
+#endif
+}
+
 /**
  * Implementation of the message loop.
  */

+ 2 - 0
panda/src/device/winInputDeviceManager.h

@@ -44,6 +44,8 @@ public:
   HWND setup_message_loop();
   void destroy_message_loop();
 
+  static void stop_thread();
+
 private:
   // There are always exactly four of these in existence.
   XInputDevice _xinput_device0;

+ 10 - 0
panda/src/display/graphicsEngine.cxx

@@ -49,6 +49,10 @@
 #include "callbackGraphicsWindow.h"
 #include "depthTestAttrib.h"
 
+#if defined(_WIN32) && defined(HAVE_THREADS) && defined(SIMPLE_THREADS)
+#include "winInputDeviceManager.h"
+#endif
+
 #if defined(WIN32)
   #define WINDOWS_LEAN_AND_MEAN
   #include <WinSock2.h>
@@ -637,6 +641,12 @@ remove_all_windows() {
   PStatClient::get_global_pstats()->disconnect();
 #endif
 
+#if defined(_WIN32) && defined(HAVE_THREADS) && defined(SIMPLE_THREADS)
+  // Send a message to the input message pump asking it to shut itself down.
+  // If we don't do that, the next call will deadlock.
+  WinInputDeviceManager::stop_thread();
+#endif
+
   // Well, and why not clean up all threads here?
   Thread::prepare_for_exit();
 }