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
@@ -1,7 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <Bitmap.h> #include <Application.h>
#include <Message.h> #include <Message.h>
#include <MessageQueue.h> #include <MessageQueue.h>
#include <Messenger.h> #include <Messenger.h>
@@ -43,12 +43,6 @@ Desktop::Desktop(DrawView* drawView)
// destructor // destructor
Desktop::~Desktop() Desktop::~Desktop()
{ {
int32 count = CountWindows();
for (int32 i = count - 1; i >= 0; i--) {
WindowLayer* window = WindowAtFast(i);
window->Lock();
window->Quit();
}
} }
// Draw // Draw
@@ -241,6 +235,15 @@ Desktop::MessageReceived(BMessage* message)
break; 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: default:
BLooper::MessageReceived(message); 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 - // #pragma mark -
// _RebuildClippingForAllWindows // _RebuildClippingForAllWindows
@@ -28,6 +28,8 @@ enum {
MSG_DRAW = 'draw', MSG_DRAW = 'draw',
MSG_MARK_CLEAN = 'mcln', MSG_MARK_CLEAN = 'mcln',
MSG_QUIT = 'quit',
}; };
class Desktop : public BLooper { class Desktop : public BLooper {
@@ -93,6 +95,8 @@ class Desktop : public BLooper {
BRegion& BackgroundRegion() BRegion& BackgroundRegion()
{ return fBackgroundRegion; } { return fBackgroundRegion; }
void WindowDied(WindowLayer* window);
private: private:
void _RebuildClippingForAllWindows(BRegion* stillAvailableOnScreen); void _RebuildClippingForAllWindows(BRegion* stillAvailableOnScreen);
void _TriggerWindowRedrawing(BRegion* newDirtyRegion); void _TriggerWindowRedrawing(BRegion* newDirtyRegion);
@@ -78,9 +78,6 @@ WindowLayer::WindowLayer(BRect frame, const char* name,
// destructor // destructor
WindowLayer::~WindowLayer() WindowLayer::~WindowLayer()
{ {
fClient->Lock();
fClient->Quit();
delete fTopLayer; 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 // SetClipping
void void
WindowLayer::SetClipping(BRegion* stillAvailableOnScreen) WindowLayer::SetClipping(BRegion* stillAvailableOnScreen)
@@ -59,6 +59,7 @@ class WindowLayer : public BLooper {
virtual ~WindowLayer(); virtual ~WindowLayer();
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested();
inline BRect Frame() const inline BRect Frame() const
{ return fFrame; } { return fFrame; }
+17 -2
View File
@@ -23,11 +23,14 @@ class Window : public BWindow {
Window(const char* title); Window(const char* title);
virtual ~Window(); virtual ~Window();
virtual bool QuitRequested();
void AddWindow(BRect frame, const char* name); void AddWindow(BRect frame, const char* name);
void Test(); void Test();
private: private:
DrawView* fView; DrawView* fView;
Desktop* fDesktop; Desktop* fDesktop;
bool fQuit;
}; };
// constructor // constructor
@@ -50,14 +53,14 @@ App::ReadyToRun()
// constructor // constructor
Window::Window(const char* title) Window::Window(const char* title)
: BWindow(BRect(50, 50, 800, 650), title, : BWindow(BRect(50, 50, 800, 650), title,
B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_ASYNCHRONOUS_CONTROLS)
B_QUIT_ON_WINDOW_CLOSE | B_ASYNCHRONOUS_CONTROLS)
{ {
fView = new DrawView(Bounds()); fView = new DrawView(Bounds());
fDesktop = new Desktop(fView); fDesktop = new Desktop(fView);
fDesktop->Run(); fDesktop->Run();
AddChild(fView); AddChild(fView);
fView->MakeFocus(true); fView->MakeFocus(true);
fQuit = false;
} }
// destructor // destructor
@@ -67,6 +70,18 @@ Window::~Window()
fDesktop->Quit(); fDesktop->Quit();
} }
// QuitRequested
bool
Window::QuitRequested()
{
if (!fQuit) {
fDesktop->PostMessage(MSG_QUIT);
fQuit = true;
return false;
}
return true;
}
// AddWindow // AddWindow
void void
Window::AddWindow(BRect frame, const char* name) Window::AddWindow(BRect frame, const char* name)