* 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
This commit is contained in:
Jérôme Duval 2010-01-17 20:05:01 +00:00
parent d9626569fb
commit 6aee58a4cb
7 changed files with 91 additions and 9 deletions

View File

@ -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);

View File

@ -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,

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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,

View File

@ -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<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:
{

View File

@ -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();