BMediaRoster: Reference count polishment

* BMediaNode is registering it's presence to the roster.
* Only addons needs their configuration to be saved.
This commit is contained in:
Dario Casalinuovo 2015-11-19 18:50:38 +01:00
parent d98b8c7c59
commit 6423f87f9e
2 changed files with 35 additions and 21 deletions

View File

@ -151,7 +151,12 @@ BMediaNode*
BMediaNode::Acquire() BMediaNode::Acquire()
{ {
CALLED(); CALLED();
atomic_add(&fRefCount,1); if (atomic_add(&fRefCount,1) == 0) {
status_t status = B_ERROR;
BMediaRoster* roster = BMediaRoster::Roster(&status);
if (roster != NULL && status == B_OK)
MediaRosterEx(roster)->RegisterLocalNode(this);
}
return this; return this;
} }
@ -161,13 +166,26 @@ BMediaNode::Release()
{ {
CALLED(); CALLED();
if (atomic_add(&fRefCount, -1) == 1) { if (atomic_add(&fRefCount, -1) == 1) {
TRACE("BMediaNode::Release() saving node %ld configuration\n", fNodeID); status_t status = B_ERROR;
MediaRosterEx(BMediaRoster::Roster())->SaveNodeConfiguration(this); BMediaRoster* roster = BMediaRoster::Roster(&status);
if (DeleteHook(this) != B_OK) { if (roster != NULL && status == B_OK) {
ERROR("BMediaNode::Release(): DeleteHook failed\n"); MediaRosterEx(roster)->UnregisterLocalNode(this);
return Acquire();
// Only addons needs the configuration to be saved.
int32 id;
if (AddOn(&id) != NULL) {
TRACE("BMediaNode::Release() saving node %ld"
" configuration\n", fNodeID);
MediaRosterEx(roster)->SaveNodeConfiguration(this);
}
if (DeleteHook(this) != B_OK) {
ERROR("BMediaNode::Release(): DeleteHook failed\n");
return Acquire();
}
return NULL;
} }
return NULL; TRACE("BMediaRoster::Release() the media roster is NULL!");
} }
return this; return this;
} }

View File

@ -3530,23 +3530,19 @@ BMediaRoster::MessageReceived(BMessage* message)
case NODE_FINAL_RELEASE: case NODE_FINAL_RELEASE:
{ {
// this function is called by a BMediaNode to delete // This function is called by a BMediaNode to delete
// itself, as this needs to be done from another thread // itself, as this needs to be done from another thread
// context, it is done here. // context, it is done here.
// TODO: If a node is released using BMediaRoster::ReleaseNode()
// TODO: instead of using BMediaNode::Release() / BMediaNode::Acquire()
// TODO: fRefCount of the BMediaNode will not be correct.
BMediaNode *node; BMediaNode* node = NULL;
message->FindPointer("node", reinterpret_cast<void **>(&node)); status_t err = message->FindPointer("node",
reinterpret_cast<void **>(&node));
TRACE("BMediaRoster::MessageReceived NODE_FINAL_RELEASE saving " if (err == B_OK && node != NULL)
"node %" B_PRId32 " configuration\n", node->ID()); node->Release();
MediaRosterEx(BMediaRoster::Roster())->SaveNodeConfiguration(node); else {
TRACE("BMediaRoster::MessageReceived: CRITICAL! received"
TRACE("BMediaRoster::MessageReceived NODE_FINAL_RELEASE releasing " "a release request but the node can't be found.");
"node %" B_PRId32 "\n", node->ID()); }
node->DeleteHook(node); // we don't call Release(), see above!
return; return;
} }