From 6aee58a4cb26a848cad1f4343af8597baa144df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sun, 17 Jan 2010 20:05:01 +0000 Subject: [PATCH] * Revert the reverse the addons iteration of r35121. * The media_addon_server before unloading addons need to be sure the nodes are deleted. For instance, applications could keep references on global nodes, thus preventing deletion. To release all references, the media_addon server uses a new method BMediaRosterEx::ReleaseNodeAll(). * Quit the MediaRoster looper when quitting media_addon server before unloading addons. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35133 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/media/MediaRosterEx.h | 1 + headers/private/media/ServerInterface.h | 1 + src/kits/media/MediaRoster.cpp | 34 ++++++++++++++++++++ src/servers/media/NodeManager.cpp | 32 ++++++++++++++++++ src/servers/media/NodeManager.h | 1 + src/servers/media/media_server.cpp | 11 +++++++ src/servers/media_addon/MediaAddonServer.cpp | 20 ++++++------ 7 files changed, 91 insertions(+), 9 deletions(-) diff --git a/headers/private/media/MediaRosterEx.h b/headers/private/media/MediaRosterEx.h index b07ad7d7de..381bfbe452 100644 --- a/headers/private/media/MediaRosterEx.h +++ b/headers/private/media/MediaRosterEx.h @@ -38,6 +38,7 @@ public: status_t IncrementAddonFlavorInstancesCount(media_addon_id addonid, int32 flavorid); status_t DecrementAddonFlavorInstancesCount(media_addon_id addonid, int32 flavorid); + status_t ReleaseNodeAll(const media_node& node); status_t SetNodeCreator(media_node_id node, team_id creator); diff --git a/headers/private/media/ServerInterface.h b/headers/private/media/ServerInterface.h index ba73e316e9..07913e1e7e 100644 --- a/headers/private/media/ServerInterface.h +++ b/headers/private/media/ServerInterface.h @@ -53,6 +53,7 @@ enum { SERVER_GET_LIVE_NODES, SERVER_GET_NODE_FOR, SERVER_RELEASE_NODE, + SERVER_RELEASE_NODE_ALL, SERVER_REGISTER_NODE, SERVER_UNREGISTER_NODE, SERVER_GET_DORMANT_NODE_FOR, diff --git a/src/kits/media/MediaRoster.cpp b/src/kits/media/MediaRoster.cpp index 6174926f5b..82c69c7bc2 100644 --- a/src/kits/media/MediaRoster.cpp +++ b/src/kits/media/MediaRoster.cpp @@ -190,6 +190,40 @@ BMediaRosterEx::DecrementAddonFlavorInstancesCount(media_addon_id addonID, } +status_t +BMediaRosterEx::ReleaseNodeAll(const media_node& node) +{ + CALLED(); + if (IS_INVALID_NODE(node)) + return B_MEDIA_BAD_NODE; + + if (node.kind & NODE_KIND_NO_REFCOUNTING) { + printf("BMediaRoster::ReleaseNodeAll, trying to release reference " + "counting disabled timesource, node %ld, port %ld, team %ld\n", + node.node, node.port, BPrivate::current_team()); + return B_OK; + } + + server_release_node_request request; + server_release_node_reply reply; + status_t rv; + + request.node = node; + request.team = BPrivate::current_team(); + + TRACE("BMediaRoster::ReleaseNodeAll, node %ld, port %ld, team %ld\n", + node.node, node.port, BPrivate::current_team()); + + rv = QueryServer(SERVER_RELEASE_NODE_ALL, &request, sizeof(request), &reply, + sizeof(reply)); + if (rv != B_OK) { + ERROR("BMediaRoster::ReleaseNodeAll FAILED, node %ld, port %ld, team " + "%ld!\n", node.node, node.port, BPrivate::current_team()); + } + return rv; +} + + status_t BMediaRosterEx::SetNodeCreator(media_node_id node, team_id creator) { diff --git a/src/servers/media/NodeManager.cpp b/src/servers/media/NodeManager.cpp index d9e17827b3..1e68f16ed0 100644 --- a/src/servers/media/NodeManager.cpp +++ b/src/servers/media/NodeManager.cpp @@ -280,6 +280,38 @@ NodeManager::ReleaseNodeReference(media_node_id id, team_id team) } +status_t +NodeManager::ReleaseNodeAll(media_node_id id) +{ + TRACE("NodeManager::ReleaseNodeAll enter: node %ld, team %ld\n", node.node, + team); + + BAutolock _(this); + + NodeMap::iterator found = fNodeMap.find(id); + if (found == fNodeMap.end()) { + ERROR("NodeManager::ReleaseNodeAll: node %ld not found\n", id); + return B_ERROR; + } + + registered_node& node = found->second; + node.team_ref_count.clear(); + node.ref_count = 0; + + node_final_release_command command; + status_t status = SendToPort(node.port, NODE_FINAL_RELEASE, &command, + sizeof(command)); + if (status != B_OK) { + ERROR("NodeManager::ReleaseNodeAll: can't send command to " + "node %ld\n", id); + // ignore error + } + + TRACE("NodeManager::ReleaseNodeAll leave: node %ld\n", id); + return B_OK; +} + + status_t NodeManager::SetNodeCreator(media_node_id id, team_id creator) { diff --git a/src/servers/media/NodeManager.h b/src/servers/media/NodeManager.h index 9e5a888d44..83569ec851 100644 --- a/src/servers/media/NodeManager.h +++ b/src/servers/media/NodeManager.h @@ -79,6 +79,7 @@ public: int32* _flavorID); status_t ReleaseNodeReference(media_node_id id, team_id team); + status_t ReleaseNodeAll(media_node_id id); status_t GetCloneForID(media_node_id id, team_id team, media_node* node); status_t GetClone(node_type type, team_id team, diff --git a/src/servers/media/media_server.cpp b/src/servers/media/media_server.cpp index cc885854d7..fd51cf7742 100644 --- a/src/servers/media/media_server.cpp +++ b/src/servers/media/media_server.cpp @@ -437,6 +437,17 @@ ServerApp::_HandleMessage(int32 code, const void* data, size_t size) request.SendReply(status, &reply, sizeof(reply)); break; } + + case SERVER_RELEASE_NODE_ALL: + { + const server_release_node_request& request + = *static_cast(data); + server_release_node_reply reply; + + status_t status = gNodeManager->ReleaseNodeAll(request.node.node); + request.SendReply(status, &reply, sizeof(reply)); + break; + } case SERVER_REGISTER_NODE: { diff --git a/src/servers/media_addon/MediaAddonServer.cpp b/src/servers/media_addon/MediaAddonServer.cpp index 01a9056eb2..c7f7c38b19 100644 --- a/src/servers/media_addon/MediaAddonServer.cpp +++ b/src/servers/media_addon/MediaAddonServer.cpp @@ -341,13 +341,15 @@ MediaAddonServer::QuitRequested() { CALLED(); - InfoMap::reverse_iterator iterator = fInfoMap.rbegin(); - for (; iterator != fInfoMap.rend(); iterator++) { - AddOnInfo& info = iterator->second; + InfoMap::iterator iterator = fInfoMap.begin(); + for (iterator = fInfoMap.begin(); iterator != fInfoMap.end(); iterator++) + _DestroyInstantiatedFlavors(iterator->second); - _DestroyInstantiatedFlavors(info); - _PutAddonIfPossible(info); - } + BMediaRoster::CurrentRoster()->Lock(); + BMediaRoster::CurrentRoster()->Quit(); + + for (iterator = fInfoMap.begin(); iterator != fInfoMap.end(); iterator++) + _PutAddonIfPossible(iterator->second); return true; } @@ -605,8 +607,8 @@ MediaAddonServer::_DestroyInstantiatedFlavors(AddOnInfo& info) { printf("MediaAddonServer::_DestroyInstantiatedFlavors addon %ld\n", info.id); - NodeVector::reverse_iterator iterator = info.active_flavors.rbegin(); - for (; iterator != info.active_flavors.rend(); iterator++) { + NodeVector::iterator iterator = info.active_flavors.begin(); + for (; iterator != info.active_flavors.end(); iterator++) { media_node& node = *iterator; printf("node %ld\n", node.node); @@ -680,7 +682,7 @@ MediaAddonServer::_DestroyInstantiatedFlavors(AddOnInfo& info) } } - fMediaRoster->ReleaseNode(node); + MediaRosterEx(fMediaRoster)->ReleaseNodeAll(node); } info.active_flavors.clear();