not in a nice way, but I hope to have fixed the deadlocking problems on program exit

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15279 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2005-12-02 00:10:41 +00:00
parent 0bbd104a7d
commit a825e4034c
5 changed files with 58 additions and 12 deletions

View File

@ -1,7 +1,7 @@
#include <stdio.h>
#include <Bitmap.h>
#include <Application.h>
#include <Message.h>
#include <MessageQueue.h>
#include <Messenger.h>
@ -43,12 +43,6 @@ Desktop::Desktop(DrawView* drawView)
// destructor
Desktop::~Desktop()
{
int32 count = CountWindows();
for (int32 i = count - 1; i >= 0; i--) {
WindowLayer* window = WindowAtFast(i);
window->Lock();
window->Quit();
}
}
// Draw
@ -241,6 +235,15 @@ Desktop::MessageReceived(BMessage* message)
break;
}
case MSG_QUIT:
if (LockClipping()) {
int32 count = CountWindows();
for (int32 i = 0; i < count; i++)
WindowAtFast(i)->PostMessage(B_QUIT_REQUESTED);
UnlockClipping();
}
break;
default:
BLooper::MessageReceived(message);
}
@ -603,6 +606,17 @@ Desktop::MarkDirty(BRegion* region)
}
}
// WindowDied
void
Desktop::WindowDied(WindowLayer* window)
{
// thread is expected expected to have the
// write lock!
fWindows.RemoveItem(window);
if (fWindows.CountItems() == 0)
be_app->PostMessage(B_QUIT_REQUESTED);
}
// #pragma mark -
// _RebuildClippingForAllWindows

View File

@ -28,6 +28,8 @@ enum {
MSG_DRAW = 'draw',
MSG_MARK_CLEAN = 'mcln',
MSG_QUIT = 'quit',
};
class Desktop : public BLooper {
@ -93,6 +95,8 @@ class Desktop : public BLooper {
BRegion& BackgroundRegion()
{ return fBackgroundRegion; }
void WindowDied(WindowLayer* window);
private:
void _RebuildClippingForAllWindows(BRegion* stillAvailableOnScreen);
void _TriggerWindowRedrawing(BRegion* newDirtyRegion);

View File

@ -78,9 +78,6 @@ WindowLayer::WindowLayer(BRect frame, const char* name,
// destructor
WindowLayer::~WindowLayer()
{
fClient->Lock();
fClient->Quit();
delete fTopLayer;
}
@ -156,6 +153,21 @@ WindowLayer::MessageReceived(BMessage* message)
}
}
// QuitRequested
bool
WindowLayer::QuitRequested()
{
if (fDesktop && fDesktop->LockClipping()) {
fDesktop->WindowDied(this);
fClient->Lock();
fClient->Quit();
fDesktop->UnlockClipping();
}
return true;
}
// SetClipping
void
WindowLayer::SetClipping(BRegion* stillAvailableOnScreen)

View File

@ -59,6 +59,7 @@ class WindowLayer : public BLooper {
virtual ~WindowLayer();
virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested();
inline BRect Frame() const
{ return fFrame; }

View File

@ -23,11 +23,14 @@ class Window : public BWindow {
Window(const char* title);
virtual ~Window();
virtual bool QuitRequested();
void AddWindow(BRect frame, const char* name);
void Test();
private:
DrawView* fView;
Desktop* fDesktop;
bool fQuit;
};
// constructor
@ -50,14 +53,14 @@ App::ReadyToRun()
// constructor
Window::Window(const char* title)
: BWindow(BRect(50, 50, 800, 650), title,
B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
B_QUIT_ON_WINDOW_CLOSE | B_ASYNCHRONOUS_CONTROLS)
B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_ASYNCHRONOUS_CONTROLS)
{
fView = new DrawView(Bounds());
fDesktop = new Desktop(fView);
fDesktop->Run();
AddChild(fView);
fView->MakeFocus(true);
fQuit = false;
}
// destructor
@ -67,6 +70,18 @@ Window::~Window()
fDesktop->Quit();
}
// QuitRequested
bool
Window::QuitRequested()
{
if (!fQuit) {
fDesktop->PostMessage(MSG_QUIT);
fQuit = true;
return false;
}
return true;
}
// AddWindow
void
Window::AddWindow(BRect frame, const char* name)