]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix deadlocks with invisible frames and threads in Haiku
authorPo Lu <luangruo@yahoo.com>
Sat, 1 Jan 2022 09:33:15 +0000 (09:33 +0000)
committerPo Lu <luangruo@yahoo.com>
Sat, 1 Jan 2022 09:33:15 +0000 (09:33 +0000)
* src/haiku_support.cc (class EmacsWindow): New field
`was_shown_p'.
(EmacsShow): Lock looper if the window wasn't ever visible.
(BWindow_new): Unlock window looper after creating it.

src/haiku_support.cc

index 2a74d0bd515ea4c50e264b9df42b78ad2d8f69fd..6a7a043fe06b5aab4b596a37f62e7de3326aac84 100644 (file)
@@ -245,6 +245,7 @@ public:
   int fullscreen_p = 0;
   int zoomed_p = 0;
   int shown_flag = 0;
+  volatile int was_shown_p = 0;
 
   EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK,
                            B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS)
@@ -726,6 +727,18 @@ public:
     if (!child_frame_lock.Lock ())
       gui_abort ("Failed to lock child frame state lock");
 
+    if (!was_shown_p)
+      {
+       /* This window is being shown for the first time, which means
+          Show will unlock the looper.  In this case, it should be
+          locked again, since the looper is unlocked when the window
+          is first created.  */
+
+       if (!LockLooper ())
+         gui_abort ("Failed to lock looper during first window show");
+       was_shown_p = true;
+      }
+
     if (this->parent)
       shown_flag = 1;
     Show ();
@@ -1560,6 +1573,14 @@ BWindow_new (void *_view)
       window->Quit ();
       return NULL;
     }
+
+  /* Windows are created locked by the current thread, but calling
+     Show for the first time causes them to be unlocked.  To avoid a
+     deadlock when a frame is created invisible in one thread, and
+     another thread later tries to lock it, the window is unlocked
+     here, and EmacsShow will lock it manually if it's being shown for
+     the first time.  */
+  window->UnlockLooper ();
   window->AddChild (vw);
   *v = vw;
   return window;