diff --git a/src/kits/media/MediaNode.cpp b/src/kits/media/MediaNode.cpp index c7b5f21f165..5f2ab4fa20a 100644 --- a/src/kits/media/MediaNode.cpp +++ b/src/kits/media/MediaNode.cpp @@ -151,7 +151,12 @@ BMediaNode* BMediaNode::Acquire() { 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; } @@ -161,13 +166,26 @@ BMediaNode::Release() { CALLED(); if (atomic_add(&fRefCount, -1) == 1) { - TRACE("BMediaNode::Release() saving node %ld configuration\n", fNodeID); - MediaRosterEx(BMediaRoster::Roster())->SaveNodeConfiguration(this); - if (DeleteHook(this) != B_OK) { - ERROR("BMediaNode::Release(): DeleteHook failed\n"); - return Acquire(); + status_t status = B_ERROR; + BMediaRoster* roster = BMediaRoster::Roster(&status); + if (roster != NULL && status == B_OK) { + MediaRosterEx(roster)->UnregisterLocalNode(this); + + // 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; } diff --git a/src/kits/media/MediaRoster.cpp b/src/kits/media/MediaRoster.cpp index 25777190326..35c1ac4b258 100644 --- a/src/kits/media/MediaRoster.cpp +++ b/src/kits/media/MediaRoster.cpp @@ -3530,23 +3530,19 @@ BMediaRoster::MessageReceived(BMessage* message) 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 // 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; - message->FindPointer("node", reinterpret_cast(&node)); - - TRACE("BMediaRoster::MessageReceived NODE_FINAL_RELEASE saving " - "node %" B_PRId32 " configuration\n", node->ID()); - MediaRosterEx(BMediaRoster::Roster())->SaveNodeConfiguration(node); - - TRACE("BMediaRoster::MessageReceived NODE_FINAL_RELEASE releasing " - "node %" B_PRId32 "\n", node->ID()); - node->DeleteHook(node); // we don't call Release(), see above! + BMediaNode* node = NULL; + status_t err = message->FindPointer("node", + reinterpret_cast(&node)); + if (err == B_OK && node != NULL) + node->Release(); + else { + TRACE("BMediaRoster::MessageReceived: CRITICAL! received" + "a release request but the node can't be found."); + } return; }