try to avoid a media_addon_server crash on quit (bug #5863).
* BMediaRosterEx::ReleaseNodeAll(): if media_server isn't available, try to contact the node locally. * BMediaRoster::UnregisterNode(): if media_server isn't available, try to get the addon_id from the local node. * BMediaNode::AddOn() as a pure virtual methode isn't available in the BMediaNode destructor. Workaround that by calling UnregisterNode() in DeleteHook() instead of the destructor. * MediaAddonServer::_DestroyInstantiatedFlavors(): give time to each flavor to clean up.
This commit is contained in:
@@ -148,12 +148,9 @@ BMediaNode::~BMediaNode()
|
|||||||
fTimeSource = NULL;
|
fTimeSource = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attention! We do not unregister TimeSourceObject nodes,
|
// Attention! We do not delete their control ports, since they are only a
|
||||||
// or delete their control ports, since they are only a
|
|
||||||
// shadow object, and the real one still exists
|
// shadow object, and the real one still exists
|
||||||
if (0 == (fKinds & NODE_KIND_SHADOW_TIMESOURCE)) {
|
if (0 == (fKinds & NODE_KIND_SHADOW_TIMESOURCE)) {
|
||||||
BMediaRoster::Roster()->UnregisterNode(this);
|
|
||||||
|
|
||||||
if (fControlPort > 0)
|
if (fControlPort > 0)
|
||||||
delete_port(fControlPort);
|
delete_port(fControlPort);
|
||||||
} else {
|
} else {
|
||||||
@@ -829,6 +826,10 @@ BMediaNode::ApplyChangeTag(int32 previously_reserved)
|
|||||||
BMediaNode::DeleteHook(BMediaNode *node)
|
BMediaNode::DeleteHook(BMediaNode *node)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
// Attention! We do not unregister TimeSourceObject nodes,
|
||||||
|
// since they are only a shadow object, and the real one still exists
|
||||||
|
if ((fKinds & NODE_KIND_SHADOW_TIMESOURCE) == 0)
|
||||||
|
BMediaRoster::Roster()->UnregisterNode(this);
|
||||||
delete this; // delete "this" or "node", both are the same
|
delete this; // delete "this" or "node", both are the same
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,11 +220,20 @@ BMediaRosterEx::ReleaseNodeAll(const media_node& node)
|
|||||||
|
|
||||||
rv = QueryServer(SERVER_RELEASE_NODE_ALL, &request, sizeof(request), &reply,
|
rv = QueryServer(SERVER_RELEASE_NODE_ALL, &request, sizeof(request), &reply,
|
||||||
sizeof(reply));
|
sizeof(reply));
|
||||||
|
if (rv != B_OK) {
|
||||||
|
ERROR("BMediaRoster::ReleaseNodeAll failed to query media_server, "
|
||||||
|
"retrying local, node %" B_PRId32 ", port %"
|
||||||
|
B_PRId32 ", team %" B_PRId32 "!\n", node.node, node.port,
|
||||||
|
BPrivate::current_team());
|
||||||
|
node_final_release_command command;
|
||||||
|
rv = SendToPort(node.port, NODE_FINAL_RELEASE, &command,
|
||||||
|
sizeof(command));
|
||||||
if (rv != B_OK) {
|
if (rv != B_OK) {
|
||||||
ERROR("BMediaRoster::ReleaseNodeAll FAILED, node %" B_PRId32 ", port %"
|
ERROR("BMediaRoster::ReleaseNodeAll FAILED, node %" B_PRId32 ", port %"
|
||||||
B_PRId32 ", team %" B_PRId32 "!\n", node.node, node.port,
|
B_PRId32 ", team %" B_PRId32 "!\n", node.node, node.port,
|
||||||
BPrivate::current_team());
|
BPrivate::current_team());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2079,13 +2088,16 @@ BMediaRoster::UnregisterNode(BMediaNode* node)
|
|||||||
BPrivate::media::notifications::NodesDeleted(&request.node_id, 1);
|
BPrivate::media::notifications::NodesDeleted(&request.node_id, 1);
|
||||||
|
|
||||||
server_unregister_node_reply reply;
|
server_unregister_node_reply reply;
|
||||||
|
reply.add_on_id = -1;
|
||||||
status_t status = QueryServer(SERVER_UNREGISTER_NODE, &request,
|
status_t status = QueryServer(SERVER_UNREGISTER_NODE, &request,
|
||||||
sizeof(request), &reply, sizeof(reply));
|
sizeof(request), &reply, sizeof(reply));
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
ERROR("BMediaRoster::UnregisterNode: failed to unregister node id %"
|
ERROR("BMediaRoster::UnregisterNode: failed to unregister node id %"
|
||||||
B_PRId32 ", name '%s': %s\n", node->ID(), node->Name(),
|
B_PRId32 ", name '%s': %s\n", node->ID(), node->Name(),
|
||||||
strerror(status));
|
strerror(status));
|
||||||
return status;
|
BMediaAddOn *addon = node->AddOn(&reply.flavor_id);
|
||||||
|
if (addon != NULL)
|
||||||
|
reply.add_on_id = addon->AddonID();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reply.add_on_id != -1) {
|
if (reply.add_on_id != -1) {
|
||||||
@@ -2110,7 +2122,7 @@ BMediaRoster::UnregisterNode(BMediaNode* node)
|
|||||||
// we are a friend class of BMediaNode and invalidate this member variable
|
// we are a friend class of BMediaNode and invalidate this member variable
|
||||||
node->fNodeID = NODE_UNREGISTERED_ID;
|
node->fNodeID = NODE_UNREGISTERED_ID;
|
||||||
|
|
||||||
return B_OK;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3309,4 +3321,3 @@ BMediaRoster::SetRunningDefault(media_node_id forDefault,
|
|||||||
|
|
||||||
|
|
||||||
BMediaRoster* BMediaRoster::sDefaultInstance = NULL;
|
BMediaRoster* BMediaRoster::sDefaultInstance = NULL;
|
||||||
|
|
||||||
|
|||||||
@@ -651,7 +651,13 @@ MediaAddonServer::_DestroyInstantiatedFlavors(AddOnInfo& info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaRosterEx(fMediaRoster)->ReleaseNodeAll(node);
|
if (MediaRosterEx(fMediaRoster)->ReleaseNodeAll(node) != B_OK) {
|
||||||
|
printf("MediaAddonServer::_DestroyInstantiatedFlavors "
|
||||||
|
"couldn't release node\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait a bit to let the node clean up
|
||||||
|
snooze(50000);
|
||||||
}
|
}
|
||||||
|
|
||||||
info.active_flavors.clear();
|
info.active_flavors.clear();
|
||||||
@@ -798,4 +804,3 @@ main()
|
|||||||
delete be_app;
|
delete be_app;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user