* 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
This commit is contained in:
Stephan Aßmus
2008-08-26 18:30:47 +00:00
parent 9a5f768b19
commit 0cafe2dfb9
+21 -15
View File
@@ -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();
}