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.
This commit is contained in:
parent
a33d19b0a4
commit
7d337b23b7
@ -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);
|
||||
|
@ -86,6 +86,22 @@ static bool sServerIsUp = false;
|
||||
static List<RosterNotification> 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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user