From 7d337b23b7a962caac04e6e5b8a03a35b9591394 Mon Sep 17 00:00:00 2001 From: Dario Casalinuovo Date: Tue, 1 Sep 2015 13:02:07 +0200 Subject: [PATCH] BMediaRoster: Reintroduce the undertaker class * This has been necessary due to the undefined call order of of static objects. Fixes #12315. * The bug has been caused by the linker which free unused resources, making the BMediaRoster to run in a zombie state. In this state anything such as a message could make the looper to crash. * The class is reintroduced with some differences though, we are going to protect it from another thread calling Roster() while the BMediaRoster is quitting and implement BMediaRosterEx::Quit. * Unregister registrar notifications before we quit our thread. Avoid to uninitialize anything from QuitRequested as it may cause problems. --- headers/private/media/MediaRosterEx.h | 2 ++ src/kits/media/MediaRoster.cpp | 40 +++++++++++++++++++++------ 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/headers/private/media/MediaRosterEx.h b/headers/private/media/MediaRosterEx.h index ab8ba22b25..74bec127e5 100644 --- a/headers/private/media/MediaRosterEx.h +++ b/headers/private/media/MediaRosterEx.h @@ -37,6 +37,8 @@ public: BMediaRosterEx(status_t* out_error); virtual ~BMediaRosterEx(); + virtual void Quit(); + status_t SaveNodeConfiguration(BMediaNode* node); status_t LoadNodeConfiguration(media_addon_id addonid, int32 flavorid, BMessage* out_msg); diff --git a/src/kits/media/MediaRoster.cpp b/src/kits/media/MediaRoster.cpp index 22552bf20d..363fa93b63 100644 --- a/src/kits/media/MediaRoster.cpp +++ b/src/kits/media/MediaRoster.cpp @@ -86,6 +86,22 @@ static bool sServerIsUp = false; static List sNotificationList; static BLocker sInitLocker("BMediaRoster::Roster locker"); + +class MediaRosterUndertaker { +public: + ~MediaRosterUndertaker() + { + BAutolock _(sInitLocker); + if (BMediaRoster::CurrentRoster() != NULL + && BMediaRoster::CurrentRoster()->Lock()) { + BMediaRoster::CurrentRoster()->Quit(); + } + } +}; + + +static MediaRosterUndertaker sMediaRosterUndertaker; + } // namespace media } // namespace BPrivate @@ -96,8 +112,8 @@ BMediaRosterEx::BMediaRosterEx(status_t* _error) : BMediaRoster() { - gDormantNodeManager = new DormantNodeManager; - gTimeSourceObjectManager = new TimeSourceObjectManager; + gDormantNodeManager = new DormantNodeManager(); + gTimeSourceObjectManager = new TimeSourceObjectManager(); *_error = BuildConnections(); @@ -111,6 +127,19 @@ BMediaRosterEx::BMediaRosterEx(status_t* _error) } +void +BMediaRosterEx::Quit() +{ + if (be_roster->StopWatching(BMessenger(this, this)) != B_OK) + TRACE("Can't unregister roster notifications"); + + if (sNotificationList.CountItems() != 0) + sNotificationList.MakeEmpty(); + + BMediaRoster::Quit(); +} + + status_t BMediaRosterEx::BuildConnections() { @@ -3474,13 +3503,6 @@ bool BMediaRoster::QuitRequested() { CALLED(); - - if (be_roster->StopWatching(BMessenger(this, this)) != B_OK) - TRACE("Can't unregister roster notifications"); - - if (sNotificationList.CountItems() != 0) - sNotificationList.MakeEmpty(); - return true; }