From c6d83707d6c5b9af67f69d34034a60719584b805 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 1 Jan 2022 09:33:15 +0000 Subject: [PATCH] Fix deadlocks with invisible frames and threads in Haiku * 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 | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 2a74d0bd515..6a7a043fe06 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -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; -- 2.39.2