Author: korli Date: 2010-01-17 21:05:01 +0100 (Sun, 17 Jan 2010) New Revision: 35133 Changeset: http://dev.haiku-os.org/changeset/35133/haiku Modified: haiku/trunk/headers/private/media/MediaRosterEx.h haiku/trunk/headers/private/media/ServerInterface.h haiku/trunk/src/kits/media/MediaRoster.cpp haiku/trunk/src/servers/media/NodeManager.cpp haiku/trunk/src/servers/media/NodeManager.h haiku/trunk/src/servers/media/media_server.cpp haiku/trunk/src/servers/media_addon/MediaAddonServer.cpp Log: * 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. Modified: haiku/trunk/headers/private/media/MediaRosterEx.h =================================================================== --- haiku/trunk/headers/private/media/MediaRosterEx.h 2010-01-17 19:58:46 UTC (rev 35132) +++ haiku/trunk/headers/private/media/MediaRosterEx.h 2010-01-17 20:05:01 UTC (rev 35133) @@ -38,6 +38,7 @@ 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); Modified: haiku/trunk/headers/private/media/ServerInterface.h =================================================================== --- haiku/trunk/headers/private/media/ServerInterface.h 2010-01-17 19:58:46 UTC (rev 35132) +++ haiku/trunk/headers/private/media/ServerInterface.h 2010-01-17 20:05:01 UTC (rev 35133) @@ -53,6 +53,7 @@ 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, Modified: haiku/trunk/src/kits/media/MediaRoster.cpp =================================================================== --- haiku/trunk/src/kits/media/MediaRoster.cpp 2010-01-17 19:58:46 UTC (rev 35132) +++ haiku/trunk/src/kits/media/MediaRoster.cpp 2010-01-17 20:05:01 UTC (rev 35133) @@ -191,6 +191,40 @@ 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) { server_set_node_creator_request request; Modified: haiku/trunk/src/servers/media/NodeManager.cpp =================================================================== --- haiku/trunk/src/servers/media/NodeManager.cpp 2010-01-17 19:58:46 UTC (rev 35132) +++ haiku/trunk/src/servers/media/NodeManager.cpp 2010-01-17 20:05:01 UTC (rev 35133) @@ -281,6 +281,38 @@ 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) { TRACE("NodeManager::SetNodeCreator node %ld, creator %ld\n", id, creator); Modified: haiku/trunk/src/servers/media/NodeManager.h =================================================================== --- haiku/trunk/src/servers/media/NodeManager.h 2010-01-17 19:58:46 UTC (rev 35132) +++ haiku/trunk/src/servers/media/NodeManager.h 2010-01-17 20:05:01 UTC (rev 35133) @@ -79,6 +79,7 @@ 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, Modified: haiku/trunk/src/servers/media/media_server.cpp =================================================================== --- haiku/trunk/src/servers/media/media_server.cpp 2010-01-17 19:58:46 UTC (rev 35132) +++ haiku/trunk/src/servers/media/media_server.cpp 2010-01-17 20:05:01 UTC (rev 35133) @@ -437,7 +437,18 @@ request.SendReply(status, &reply, sizeof(reply)); break; } + + case SERVER_RELEASE_NODE_ALL: + { + const server_release_node_request& request + = *static_cast<const server_release_node_request*>(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: { const server_register_node_request& request Modified: haiku/trunk/src/servers/media_addon/MediaAddonServer.cpp =================================================================== --- haiku/trunk/src/servers/media_addon/MediaAddonServer.cpp 2010-01-17 19:58:46 UTC (rev 35132) +++ haiku/trunk/src/servers/media_addon/MediaAddonServer.cpp 2010-01-17 20:05:01 UTC (rev 35133) @@ -341,13 +341,15 @@ { 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 @@ { 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 @@ } } - fMediaRoster->ReleaseNode(node); + MediaRosterEx(fMediaRoster)->ReleaseNodeAll(node); } info.active_flavors.clear();