From 0cafe2dfb913996075f3a3d6c9bde77449cec65b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Tue, 26 Aug 2008 18:30:47 +0000 Subject: [PATCH] * Fixed a race condition in BWindow::Show(). If it was the first time Show() was called, the calling thread could be preempted, or simply be blocked on calling Lock() after running the window thread. The window thread in turn could be processing messages. In that case, fShowLevel would still have the wrong value. For example, MediaPlayer would call IsHidden() on one of it's views, which would then return true for this case. The result was that the video view was not hidden and a black rectangle was showing on top of the controls. This may also have caused other similar problems of course. * fRunCalled was accessed without holding the lock. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27209 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/interface/Window.cpp | 36 ++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/kits/interface/Window.cpp b/src/kits/interface/Window.cpp index d4d4138aba..fb537158e6 100644 --- a/src/kits/interface/Window.cpp +++ b/src/kits/interface/Window.cpp @@ -2317,8 +2317,24 @@ BWindow::ResizeTo(float width, float height) void BWindow::Show() { - if (!fRunCalled) { - // this is the fist time Show() is called, which implicitly runs the looper + bool runCalled = true; + if (Lock()) { + fShowLevel++; + + if (fShowLevel == 1) { + fLink->StartMessage(AS_SHOW_WINDOW); + fLink->Flush(); + } + + runCalled = fRunCalled; + + Unlock(); + } + + if (!runCalled) { + // This is the fist time Show() is called, which implicitly runs the + // looper. NOTE: The window is still locked if it has not been + // run yet, so accessing members is safe. if (fLink->SenderPort() < B_OK) { // We don't have valid app_server connection; there is no point // in starting our looper @@ -2327,18 +2343,6 @@ BWindow::Show() } else Run(); } - - if (Lock()) { - fShowLevel++; - - if (fShowLevel == 1) { - STRACE(("BWindow(%s): sending AS_SHOW_WINDOW message...\n", Name())); - fLink->StartMessage(AS_SHOW_WINDOW); - fLink->Flush(); - } - - Unlock(); - } } @@ -2348,7 +2352,9 @@ BWindow::Hide() if (!Lock()) return; - if (--fShowLevel == 0) { + fShowLevel--; + + if (fShowLevel == 0) { fLink->StartMessage(AS_HIDE_WINDOW); fLink->Flush(); }