diff --git a/headers/os/app/Application.h b/headers/os/app/Application.h index ef7881d69eb..13a09823fb2 100644 --- a/headers/os/app/Application.h +++ b/headers/os/app/Application.h @@ -85,6 +85,11 @@ class BApplication : public BLooper { BHandler* handler); void SetPulseRate(bigtime_t rate); + // Register a BLooper to be quit before the BApplication + // object is destroyed. + status_t RegisterLooper(BLooper* looper); + status_t UnregisterLooper(BLooper* looper); + // More scripting virtual status_t GetSupportedSuites(BMessage* data); diff --git a/src/kits/app/Application.cpp b/src/kits/app/Application.cpp index cda2c6d8911..c1c3f33b62d 100644 --- a/src/kits/app/Application.cpp +++ b/src/kits/app/Application.cpp @@ -61,6 +61,7 @@ BMessenger be_app_messenger; pthread_once_t sAppResourcesInitOnce = PTHREAD_ONCE_INIT; BResources* BApplication::sAppResources = NULL; +BObjectList sOnQuitLooperList; enum { @@ -306,6 +307,13 @@ BApplication::~BApplication() // tell all loopers(usually windows) to quit. Also, wait for them. _QuitAllWindows(true); + // quit registered loopers + for (int32 i = 0; i < sOnQuitLooperList.CountItems(); i++) { + BLooper* looper = sOnQuitLooperList.ItemAt(i); + if (looper->Lock()) + looper->Quit(); + } + // unregister from the roster BRoster::Private().RemoveApp(Team()); @@ -960,6 +968,40 @@ BApplication::LooperAt(int32 index) const } +status_t +BApplication::RegisterLooper(BLooper* looper) +{ + BWindow* window = dynamic_cast(looper); + if (window != NULL) + return B_BAD_VALUE; + + if (sOnQuitLooperList.HasItem(looper)) + return B_ERROR; + + if (sOnQuitLooperList.AddItem(looper) != true) + return B_ERROR; + + return B_OK; +} + + +status_t +BApplication::UnregisterLooper(BLooper* looper) +{ + BWindow* window = dynamic_cast(looper); + if (window != NULL) + return B_BAD_VALUE; + + if (!sOnQuitLooperList.HasItem(looper)) + return B_ERROR; + + if (sOnQuitLooperList.RemoveItem(looper) != true) + return B_ERROR; + + return B_OK; +} + + bool BApplication::IsLaunching() const { diff --git a/src/kits/media/MediaRoster.cpp b/src/kits/media/MediaRoster.cpp index 6351302baf8..12a948a2e5d 100644 --- a/src/kits/media/MediaRoster.cpp +++ b/src/kits/media/MediaRoster.cpp @@ -42,8 +42,7 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus " #include -#include - +#include #include #include #include @@ -58,8 +57,9 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus " #include #include -#include +#include +#include #include #include #include @@ -82,6 +82,7 @@ struct RosterNotification { int32 what; }; + static bool sServerIsUp = false; static List sNotificationList; static BLocker sInitLocker("BMediaRoster::Roster locker"); @@ -94,6 +95,10 @@ class MediaRosterUndertaker { BAutolock _(sInitLocker); if (BMediaRoster::CurrentRoster() != NULL && BMediaRoster::CurrentRoster()->Lock()) { + + if (be_app != NULL) + be_app->UnregisterLooper(BMediaRoster::CurrentRoster()); + BMediaRoster::CurrentRoster()->Quit(); } } @@ -2221,6 +2226,9 @@ BMediaRoster::Roster(status_t* out_error) { BAutolock lock(sInitLocker); + if (be_app == NULL) + TRACE("Warning! You should have a valid BApplication."); + if (!lock.IsLocked()) return NULL; @@ -2240,8 +2248,11 @@ BMediaRoster::Roster(status_t* out_error) } if (out_error) *out_error = err; + } else if (be_app != NULL) { + be_app->RegisterLooper(sDefaultInstance); } } + return sDefaultInstance; }