From 98207f6f77d91b199f606b74a251d1cd133b5f9a Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 5 Aug 2002 00:41:08 +0000 Subject: [PATCH] Fixed Quit(): * Error message, if not locked. * Lock(), quit, Unlock(), if not locked. * Don't call BLooper:Quit() any more. We post a _QUIT_ message when being called from another than the looper thread. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@575 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/app/Application.cpp | 39 ++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/kits/app/Application.cpp b/src/kits/app/Application.cpp index af5844cf0d..c2219bdd9f 100644 --- a/src/kits/app/Application.cpp +++ b/src/kits/app/Application.cpp @@ -285,24 +285,41 @@ thread_id BApplication::Run() //------------------------------------------------------------------------------ void BApplication::Quit() { + bool unlock = false; if (!IsLocked()) { const char* name = Name(); if (!name) name = "no-name"; - printf("ERROR - you must Lock a looper before calling Quit(), " - "team=%ld, looper=%s", Team(), name); + printf("ERROR - you must Lock the application object before calling " + "Quit(), team=%ld, looper=%s\n", Team(), name); + unlock = true; + if (!Lock()) + return; } - // Set the termination flag. That's sufficient in some cases. - fTerminating = true; // Delete the object, if not running only. - if (!fRunCalled) + if (!fRunCalled) { delete this; - // In case another thread called Quit(), things are a bit more complicated. - // BLooper::Quit() handles that gracefully. - else if (find_thread(NULL) != fTaskID) - BLooper::Quit(); - // prevent the BLooper destructor from killing the main thread - fTaskID = -1; + } else if (find_thread(NULL) != fTaskID) { + // We are not the looper thread. + // We push a _QUIT_ into the queue. + // TODO: When BLooper::AddMessage() is done, use that instead of + // PostMessage()??? This would overtake messages that are still at + // the port. + // NOTE: We must not unlock here -- otherwise we had to re-lock, which + // may not work. This is bad, since, if the port is full, it + // won't get emptier, as the looper thread needs to lock the object + // before dispatching messages. + while (PostMessage(_QUIT_, this) == B_WOULD_BLOCK) + snooze(10000); + } else { + // We are the looper thread. + // Just set fTerminating to true which makes us fall through the + // message dispatching loop and return from Run(). + fTerminating = true; + } + // If we had to lock the object, unlock now. + if (unlock) + Unlock(); } //------------------------------------------------------------------------------ bool BApplication::QuitRequested()