Added reference counting of media add-on instances.
You can't create more node instances than "possible_count". git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2990 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
b498f2e40c
commit
626824eaaf
@ -98,7 +98,7 @@ enum {
|
||||
SERVER_UNREGISTER_BUFFER,
|
||||
SERVER_RESCAN_DEFAULTS,
|
||||
SERVER_SET_NODE_CREATOR,
|
||||
SERVER_CHANGE_DORMANT_NODE_USECOUNT,
|
||||
SERVER_CHANGE_ADDON_FLAVOR_INSTANCES_COUNT,
|
||||
SERVER_MESSAGE_END,
|
||||
NODE_MESSAGE_START = 0x200,
|
||||
|
||||
@ -210,14 +210,14 @@ enum node_type
|
||||
// used by SERVER_PUBLISH_INPUTS and SERVER_PUBLISH_OUTPUTS
|
||||
enum
|
||||
{
|
||||
MAX_OUTPUTS = 48,
|
||||
MAX_INPUTS = 48,
|
||||
MAX_OUTPUTS = 8,
|
||||
MAX_INPUTS = 8,
|
||||
};
|
||||
|
||||
// used by SERVER_GET_LIVE_NODES
|
||||
enum
|
||||
{
|
||||
MAX_LIVE_INFO = 62,
|
||||
MAX_LIVE_INFO = 16,
|
||||
};
|
||||
|
||||
// used by SERVER_GET_INSTANCES_FOR
|
||||
@ -318,22 +318,6 @@ struct producer_disconnect_reply : public reply_data
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct producer_format_suggestion_requested_request : public request_data
|
||||
{
|
||||
media_type type;
|
||||
@ -437,36 +421,6 @@ struct producer_late_notice_received_command : public command_data
|
||||
bigtime_t performance_time;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct consumer_accept_format_request : public request_data
|
||||
{
|
||||
media_destination dest;
|
||||
@ -568,22 +522,6 @@ struct consumer_disconnected_reply : public reply_data
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct consumer_buffer_received_command : public command_data
|
||||
{
|
||||
media_buffer_id buffer;
|
||||
@ -634,12 +572,6 @@ struct consumer_seek_tag_requested_reply : public reply_data
|
||||
uint32 flags;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct server_register_addonserver_request : public request_data
|
||||
{
|
||||
team_id team;
|
||||
@ -678,14 +610,15 @@ struct server_set_node_creator_reply : public reply_data
|
||||
{
|
||||
};
|
||||
|
||||
struct server_change_dormant_node_usecount_request : public request_data
|
||||
struct server_change_addon_flavor_instances_count_request : public request_data
|
||||
{
|
||||
media_addon_id addon_id;
|
||||
int32 addon_flavor_id;
|
||||
int32 delta;
|
||||
media_addon_id addonid;
|
||||
int32 flavorid;
|
||||
int32 delta; // must be +1 or -1
|
||||
team_id team;
|
||||
};
|
||||
|
||||
struct server_change_dormant_node_usecount_reply : public reply_data
|
||||
struct server_change_addon_flavor_instances_count_reply : public reply_data
|
||||
{
|
||||
};
|
||||
|
||||
@ -804,9 +737,6 @@ struct server_rescan_defaults_command : public command_data
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
struct addonserver_rescan_mediaaddon_flavors_command : public command_data
|
||||
{
|
||||
media_addon_id addonid;
|
||||
|
@ -35,8 +35,8 @@ public:
|
||||
status_t SaveNodeConfiguration(BMediaNode *node);
|
||||
status_t LoadNodeConfiguration(media_addon_id addonid, int32 flavorid, BMessage *out_msg);
|
||||
|
||||
status_t IncrementDormantNodeUseCount(media_addon_id addonid, int32 flavorid);
|
||||
status_t DecrementDormantNodeUseCount(media_addon_id addonid, int32 flavorid);
|
||||
status_t IncrementAddonFlavorInstancesCount(media_addon_id addonid, int32 flavorid);
|
||||
status_t DecrementAddonFlavorInstancesCount(media_addon_id addonid, int32 flavorid);
|
||||
|
||||
status_t SetNodeCreator(media_node_id node, team_id creator);
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "DataExchange.h"
|
||||
#include "ServerInterface.h" // NEW_MEDIA_SERVER_SIGNATURE
|
||||
|
||||
#define TIMEOUT 5000000 // 5 seconds timeout!
|
||||
#define TIMEOUT 15000000 // 15 seconds timeout!
|
||||
|
||||
namespace BPrivate {
|
||||
namespace media {
|
||||
|
@ -1765,7 +1765,7 @@ BMediaRosterEx::InstantiateDormantNode(media_addon_id addonid, int32 flavorid, t
|
||||
status_t rv;
|
||||
rv = GetDormantFlavorInfo(addonid, flavorid, &node_info);
|
||||
if (rv != B_OK) {
|
||||
FATAL("BMediaRosterEx::InstantiateDormantNode error: failed to get dormant_flavor_info for addon-id %ld, flavour-id %ld\n", addonid, flavorid);
|
||||
FATAL("BMediaRosterEx::InstantiateDormantNode error: failed to get dormant_flavor_info for addon-id %ld, flavor-id %ld\n", addonid, flavorid);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@ -1784,7 +1784,7 @@ BMediaRosterEx::InstantiateDormantNode(media_addon_id addonid, int32 flavorid, t
|
||||
// flavor is limited.
|
||||
rv = IncrementAddonFlavorInstancesCount(addonid, flavorid);
|
||||
if (rv != B_OK) {
|
||||
FATAL("BMediaRosterEx::InstantiateDormantNode error: can't create more nodes for addon-id %ld, flavour-id %ld\n", addonid, flavorid);
|
||||
FATAL("BMediaRosterEx::InstantiateDormantNode error: can't create more nodes for addon-id %ld, flavor-id %ld\n", addonid, flavorid);
|
||||
// Put the addon back into the pool
|
||||
_DormantNodeManager->PutAddon(addonid);
|
||||
return B_ERROR;
|
||||
@ -1874,8 +1874,8 @@ BMediaRoster::InstantiateDormantNode(const dormant_node_info & in_info,
|
||||
status_t rv;
|
||||
rv = MediaRosterEx(this)->GetDormantFlavorInfo(in_info.addon, in_info.flavor_id, &node_info);
|
||||
if (rv != B_OK) {
|
||||
FATAL("BMediaRoster::InstantiateDormantNode error: failed to get dormant_flavor_info for addon-id %ld, flavour-id %ld\n", in_info.addon, in_info.flavor_id);
|
||||
return B_ERROR;
|
||||
FATAL("BMediaRoster::InstantiateDormantNode error: failed to get dormant_flavor_info for addon-id %ld, flavor-id %ld\n", in_info.addon, in_info.flavor_id);
|
||||
return B_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
ASSERT(node_info.internal_id == in_info.flavor_id);
|
||||
@ -1898,11 +1898,11 @@ BMediaRoster::InstantiateDormantNode(const dormant_node_info & in_info,
|
||||
// by the caller are not incompatible.
|
||||
if ((node_info.flavor_flags & B_FLAVOR_IS_GLOBAL) && (flags & B_FLAVOR_IS_LOCAL)) {
|
||||
FATAL("BMediaRoster::InstantiateDormantNode Error: requested B_FLAVOR_IS_LOCAL, but dormant node has B_FLAVOR_IS_GLOBAL\n");
|
||||
return B_BAD_VALUE;
|
||||
return B_NAME_NOT_FOUND;
|
||||
}
|
||||
if ((node_info.flavor_flags & B_FLAVOR_IS_LOCAL) && (flags & B_FLAVOR_IS_GLOBAL)) {
|
||||
FATAL("BMediaRoster::InstantiateDormantNode Error: requested B_FLAVOR_IS_GLOBAL, but dormant node has B_FLAVOR_IS_LOCAL\n");
|
||||
return B_BAD_VALUE;
|
||||
return B_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
// If either the node, or the caller requested to make the instance global
|
||||
@ -1915,23 +1915,25 @@ BMediaRoster::InstantiateDormantNode(const dormant_node_info & in_info,
|
||||
|
||||
addonserver_instantiate_dormant_node_request request;
|
||||
addonserver_instantiate_dormant_node_reply reply;
|
||||
status_t rv;
|
||||
request.addonid = in_info.addon;
|
||||
request.flavorid = in_info.flavor_id;
|
||||
request.creator_team = team; // creator team is allowed to also release global nodes
|
||||
rv = QueryAddonServer(ADDONSERVER_INSTANTIATE_DORMANT_NODE, &request, sizeof(request), &reply, sizeof(reply));
|
||||
if (rv == B_OK) {
|
||||
*out_node = reply.node;
|
||||
} else {
|
||||
*out_node = media_node::null;
|
||||
}
|
||||
return rv;
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
// creator team = -1, as this is a local node
|
||||
return MediaRosterEx(this)->InstantiateDormantNode(in_info.addon, in_info.flavor_id, -1, out_node);
|
||||
rv = MediaRosterEx(this)->InstantiateDormantNode(in_info.addon, in_info.flavor_id, -1, out_node);
|
||||
|
||||
}
|
||||
if (rv != B_OK) {
|
||||
*out_node = media_node::null;
|
||||
return B_NAME_NOT_FOUND;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <MediaAddOn.h>
|
||||
#include "debug.h"
|
||||
#include "NodeManager.h"
|
||||
#include "DefaultManager.h"
|
||||
#include "AppManager.h"
|
||||
|
||||
extern AppManager *gAppManager;
|
||||
@ -23,7 +24,7 @@ NodeManager::NodeManager() :
|
||||
fNextAddOnID(1),
|
||||
fNextNodeID(1),
|
||||
fLocker(new BLocker("node manager locker")),
|
||||
fDormantFlavorList(new List<dormant_flavor_info>),
|
||||
fDormantAddonFlavorList(new List<dormant_addon_flavor_info>),
|
||||
fAddonPathMap(new Map<media_addon_id, entry_ref>),
|
||||
fRegisteredNodeMap(new Map<media_node_id, registered_node>),
|
||||
fDefaultManager(new DefaultManager)
|
||||
@ -34,12 +35,15 @@ NodeManager::NodeManager() :
|
||||
NodeManager::~NodeManager()
|
||||
{
|
||||
delete fLocker;
|
||||
delete fDormantFlavorList;
|
||||
delete fDormantAddonFlavorList;
|
||||
delete fAddonPathMap;
|
||||
delete fRegisteredNodeMap;
|
||||
delete fDefaultManager;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Live node management
|
||||
**********************************************************************/
|
||||
|
||||
status_t
|
||||
NodeManager::RegisterNode(media_node_id *nodeid, media_addon_id addon_id, int32 addon_flavor_id, const char *name, uint64 kinds, port_id port, team_id team)
|
||||
@ -366,6 +370,30 @@ NodeManager::FindNodeId(media_node_id *nodeid, port_id port)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
status_t
|
||||
NodeManager::GetDormantNodeInfo(dormant_node_info *node_info, const media_node &node)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
// XXX not sure if this is correct
|
||||
registered_node *rn;
|
||||
for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) {
|
||||
if (rn->nodeid == node.node) {
|
||||
if (rn->addon_id == -1) { // This function must return an error if the node is application owned
|
||||
TRACE("NodeManager::GetDormantNodeInfo NODE IS APPLICATION OWNED! node %ld, addon_id %ld, addon_flavor_id %ld, name \"%s\"\n", node.node, rn->addon_id, rn->addon_flavor_id, rn->name);
|
||||
return B_ERROR;
|
||||
}
|
||||
ASSERT(node.port == rn->port);
|
||||
ASSERT(node.kind == rn->kinds);
|
||||
node_info->addon = rn->addon_id;
|
||||
node_info->flavor_id = rn->addon_flavor_id;
|
||||
strcpy(node_info->name, rn->name);
|
||||
TRACE("NodeManager::GetDormantNodeInfo node %ld, addon_id %ld, addon_flavor_id %ld, name \"%s\"\n", node.node, rn->addon_id, rn->addon_flavor_id, rn->name);
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
FATAL("!!! NodeManager::GetDormantNodeInfo failed, node %ld\n", node.node);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
status_t
|
||||
NodeManager::GetLiveNodeInfo(live_node_info *live_info, const media_node &node)
|
||||
@ -469,34 +497,6 @@ NodeManager::GetLiveNodes(Stack<live_node_info> *livenodes, int32 maxcount, cons
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
status_t
|
||||
NodeManager::GetDormantNodeInfo(dormant_node_info *node_info, const media_node &node)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
// XXX not sure if this is correct
|
||||
registered_node *rn;
|
||||
for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) {
|
||||
if (rn->nodeid == node.node) {
|
||||
if (rn->addon_id == -1) { // This function must return an error if the node is application owned
|
||||
TRACE("NodeManager::GetDormantNodeInfo NODE IS APPLICATION OWNED! node %ld, addon_id %ld, addon_flavor_id %ld, name \"%s\"\n", node.node, rn->addon_id, rn->addon_flavor_id, rn->name);
|
||||
return B_ERROR;
|
||||
}
|
||||
ASSERT(node.port == rn->port);
|
||||
ASSERT(node.kind == rn->kinds);
|
||||
node_info->addon = rn->addon_id;
|
||||
node_info->flavor_id = rn->addon_flavor_id;
|
||||
strcpy(node_info->name, rn->name);
|
||||
TRACE("NodeManager::GetDormantNodeInfo node %ld, addon_id %ld, addon_flavor_id %ld, name \"%s\"\n", node.node, rn->addon_id, rn->addon_flavor_id, rn->name);
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
FATAL("!!! NodeManager::GetDormantNodeInfo failed, node %ld\n", node.node);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* Add media_node_id of all live nodes to the message
|
||||
* int32 "media_node_id" (multiple items)
|
||||
*/
|
||||
@ -511,6 +511,10 @@ NodeManager::GetLiveNodes(BMessage *msg)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Registration of BMediaAddOns
|
||||
**********************************************************************/
|
||||
|
||||
void
|
||||
NodeManager::RegisterAddon(const entry_ref &ref, media_addon_id *newid)
|
||||
{
|
||||
@ -536,42 +540,6 @@ NodeManager::UnregisterAddon(media_addon_id id)
|
||||
fAddonPathMap->Remove(id);
|
||||
}
|
||||
|
||||
// this function is only called (indirectly) by the media_addon_server
|
||||
void
|
||||
NodeManager::AddDormantFlavorInfo(const dormant_flavor_info &dfi)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
|
||||
printf("NodeManager::AddDormantFlavorInfo, addon-id %ld, flavor-id %ld, name \"%s\", flavor-name \"%s\", flavor-info \"%s\"\n", dfi.node_info.addon, dfi.node_info.flavor_id, dfi.node_info.name, dfi.name, dfi.info);
|
||||
|
||||
fDormantFlavorList->Insert(dfi);
|
||||
}
|
||||
|
||||
// this function is only called (indirectly) by the media_addon_server
|
||||
void
|
||||
NodeManager::RemoveDormantFlavorInfo(media_addon_id id)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
dormant_flavor_info *flavor;
|
||||
for (fDormantFlavorList->Rewind(); fDormantFlavorList->GetNext(&flavor); ) {
|
||||
if (flavor->node_info.addon == id) {
|
||||
printf("NodeManager::RemoveDormantFlavorInfo, addon-id %ld, flavor-id %ld, name \"%s\", flavor-name \"%s\", flavor-info \"%s\"\n", flavor->node_info.addon, flavor->node_info.flavor_id, flavor->node_info.name, flavor->name, flavor->info);
|
||||
fDormantFlavorList->RemoveCurrent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this function is called when the media_addon_server has crashed
|
||||
void
|
||||
NodeManager::CleanupDormantFlavorInfos()
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
printf("NodeManager::CleanupDormantFlavorInfos\n");
|
||||
fDormantFlavorList->MakeEmpty();
|
||||
printf("NodeManager::CleanupDormantFlavorInfos done\n");
|
||||
// XXX FlavorsChanged(media_addon_id addonid, int32 newcount, int32 gonecount)
|
||||
}
|
||||
|
||||
status_t
|
||||
NodeManager::GetAddonRef(entry_ref *ref, media_addon_id id)
|
||||
{
|
||||
@ -586,6 +554,151 @@ NodeManager::GetAddonRef(entry_ref *ref, media_addon_id id)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Registration of node flavors, published by BMediaAddOns
|
||||
**********************************************************************/
|
||||
|
||||
// this function is only called (indirectly) by the media_addon_server
|
||||
void
|
||||
NodeManager::AddDormantFlavorInfo(const dormant_flavor_info &dfi)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
|
||||
printf("NodeManager::AddDormantFlavorInfo, addon-id %ld, flavor-id %ld, name \"%s\", flavor-name \"%s\", flavor-info \"%s\"\n", dfi.node_info.addon, dfi.node_info.flavor_id, dfi.node_info.name, dfi.name, dfi.info);
|
||||
|
||||
// Try to find the addon-id/flavor-id in the list.
|
||||
// If it already exists, update the Info, but don't
|
||||
// change the GlobalInstancesCount
|
||||
dormant_addon_flavor_info *dafi;
|
||||
for (fDormantAddonFlavorList->Rewind(); fDormantAddonFlavorList->GetNext(&dafi); ) {
|
||||
if (dafi->AddonID != dfi.node_info.addon || dafi->AddonFlavorID != dfi.node_info.flavor_id)
|
||||
continue;
|
||||
if (dafi->InfoValid) {
|
||||
FATAL("NodeManager::AddDormantFlavorInfo, addon-id %ld, flavor-id %ld does already exist\n", dafi->Info.node_info.addon, dafi->Info.node_info.flavor_id);
|
||||
}
|
||||
TRACE("NodeManager::AddDormantFlavorInfo, updating addon-id %ld, flavor-id %ld\n", dafi->Info.node_info.addon, dafi->Info.node_info.flavor_id);
|
||||
dafi->MaxInstancesCount = dfi.possible_count > 0 ? dfi.possible_count : 0x7fffffff;
|
||||
// do NOT modify dafi.GlobalInstancesCount
|
||||
dafi->InfoValid = true;
|
||||
dafi->Info = dfi;
|
||||
return;
|
||||
}
|
||||
|
||||
// Insert information into the list
|
||||
{
|
||||
dormant_addon_flavor_info dafi;
|
||||
dafi.AddonID = dfi.node_info.addon;
|
||||
dafi.AddonFlavorID = dfi.node_info.flavor_id;
|
||||
dafi.MaxInstancesCount = dfi.possible_count > 0 ? dfi.possible_count : 0x7fffffff;
|
||||
dafi.GlobalInstancesCount = 0;
|
||||
dafi.InfoValid = true;
|
||||
dafi.Info = dfi;
|
||||
fDormantAddonFlavorList->Insert(dafi);
|
||||
}
|
||||
}
|
||||
|
||||
// this function is only called (indirectly) by the media_addon_server
|
||||
void
|
||||
NodeManager::InvalidateDormantFlavorInfo(media_addon_id id)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
dormant_addon_flavor_info *dafi;
|
||||
for (fDormantAddonFlavorList->Rewind(); fDormantAddonFlavorList->GetNext(&dafi); ) {
|
||||
if (dafi->AddonID == id && dafi->InfoValid == true) {
|
||||
printf("NodeManager::InvalidateDormantFlavorInfo, addon-id %ld, flavor-id %ld, name \"%s\", flavor-name \"%s\", flavor-info \"%s\"\n", dafi->Info.node_info.addon, dafi->Info.node_info.flavor_id, dafi->Info.node_info.name, dafi->Info.name, dafi->Info.info);
|
||||
dormant_flavor_info dfi_null;
|
||||
dafi->Info = dfi_null;
|
||||
dafi->InfoValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this function is only called by clean up after gone add-ons
|
||||
void
|
||||
NodeManager::RemoveDormantFlavorInfo(media_addon_id id)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
dormant_addon_flavor_info *dafi;
|
||||
for (fDormantAddonFlavorList->Rewind(); fDormantAddonFlavorList->GetNext(&dafi); ) {
|
||||
if (dafi->AddonID == id) {
|
||||
printf("NodeManager::RemoveDormantFlavorInfo, addon-id %ld, flavor-id %ld, name \"%s\", flavor-name \"%s\", flavor-info \"%s\"\n", dafi->Info.node_info.addon, dafi->Info.node_info.flavor_id, dafi->Info.node_info.name, dafi->Info.name, dafi->Info.info);
|
||||
fDormantAddonFlavorList->RemoveCurrent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
status_t
|
||||
NodeManager::IncrementAddonFlavorInstancesCount(media_addon_id addonid, int32 flavorid, team_id team)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
|
||||
dormant_addon_flavor_info *dafi;
|
||||
for (fDormantAddonFlavorList->Rewind(); fDormantAddonFlavorList->GetNext(&dafi); ) {
|
||||
if (dafi->AddonID != addonid || dafi->AddonFlavorID != flavorid)
|
||||
continue;
|
||||
|
||||
if (dafi->GlobalInstancesCount >= dafi->MaxInstancesCount) {
|
||||
FATAL("NodeManager::IncrementAddonFlavorInstancesCount addonid %ld, flavorid %ld maximum (or more) instances already exist\n", addonid, flavorid);
|
||||
return B_ERROR; // maximum (or more) instances already exist
|
||||
}
|
||||
|
||||
bool b;
|
||||
int32 *count;
|
||||
b = dafi->TeamInstancesCount.Get(team, &count);
|
||||
if (b) {
|
||||
*count += 1;
|
||||
} else {
|
||||
b = dafi->TeamInstancesCount.Insert(team, 1);
|
||||
ASSERT(b);
|
||||
}
|
||||
dafi->GlobalInstancesCount += 1;
|
||||
return B_OK;
|
||||
}
|
||||
FATAL("NodeManager::IncrementAddonFlavorInstancesCount addonid %ld, flavorid %ld not found\n", addonid, flavorid);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
status_t
|
||||
NodeManager::DecrementAddonFlavorInstancesCount(media_addon_id addonid, int32 flavorid, team_id team)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
|
||||
dormant_addon_flavor_info *dafi;
|
||||
for (fDormantAddonFlavorList->Rewind(); fDormantAddonFlavorList->GetNext(&dafi); ) {
|
||||
if (dafi->AddonID != addonid || dafi->AddonFlavorID != flavorid)
|
||||
continue;
|
||||
|
||||
bool b;
|
||||
int32 *count;
|
||||
b = dafi->TeamInstancesCount.Get(team, &count);
|
||||
if (!b) {
|
||||
FATAL("NodeManager::DecrementAddonFlavorInstancesCount addonid %ld, flavorid %ld team %ld has no references\n", addonid, flavorid, team);
|
||||
return B_ERROR;
|
||||
}
|
||||
*count -= 1;
|
||||
if (*count == 0) {
|
||||
b = dafi->TeamInstancesCount.Remove(team);
|
||||
ASSERT(b);
|
||||
}
|
||||
if (dafi->GlobalInstancesCount > 0) // avoid underflow
|
||||
dafi->GlobalInstancesCount -= 1;
|
||||
return B_OK;
|
||||
}
|
||||
FATAL("NodeManager::DecrementAddonFlavorInstancesCount addonid %ld, flavorid %ld not found\n", addonid, flavorid);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// this function is called when the media_addon_server has crashed
|
||||
void
|
||||
NodeManager::CleanupDormantFlavorInfos()
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
printf("NodeManager::CleanupDormantFlavorInfos\n");
|
||||
fDormantAddonFlavorList->MakeEmpty();
|
||||
printf("NodeManager::CleanupDormantFlavorInfos done\n");
|
||||
// XXX FlavorsChanged(media_addon_id addonid, int32 newcount, int32 gonecount)
|
||||
}
|
||||
|
||||
status_t
|
||||
NodeManager::GetDormantNodes(dormant_node_info * out_info,
|
||||
int32 * io_count,
|
||||
@ -596,8 +709,8 @@ NodeManager::GetDormantNodes(dormant_node_info * out_info,
|
||||
uint64 deny_kinds /* = NULL */)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
dormant_addon_flavor_info *dafi;
|
||||
int32 maxcount;
|
||||
dormant_flavor_info *dfi;
|
||||
int namelen;
|
||||
|
||||
// determine the count of byte to compare when checking for a name with(out) wildcard
|
||||
@ -612,7 +725,13 @@ NodeManager::GetDormantNodes(dormant_node_info * out_info,
|
||||
|
||||
maxcount = *io_count;
|
||||
*io_count = 0;
|
||||
for (fDormantFlavorList->Rewind(); (*io_count < maxcount) && fDormantFlavorList->GetNext(&dfi); ) {
|
||||
for (fDormantAddonFlavorList->Rewind(); (*io_count < maxcount) && fDormantAddonFlavorList->GetNext(&dafi); ) {
|
||||
if (!dafi->InfoValid)
|
||||
continue;
|
||||
|
||||
dormant_flavor_info *dfi;
|
||||
dfi = &dafi->Info;
|
||||
|
||||
if ((dfi->kinds & require_kinds) != require_kinds)
|
||||
continue;
|
||||
if ((dfi->kinds & deny_kinds) != 0)
|
||||
@ -655,16 +774,20 @@ NodeManager::GetDormantFlavorInfoFor(media_addon_id addon,
|
||||
dormant_flavor_info *outFlavor)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
dormant_flavor_info *flavor;
|
||||
for (fDormantFlavorList->Rewind(); fDormantFlavorList->GetNext(&flavor); ) {
|
||||
if (flavor->node_info.addon == addon && flavor->node_info.flavor_id == flavor_id) {
|
||||
*outFlavor = *flavor;
|
||||
dormant_addon_flavor_info *dafi;
|
||||
for (fDormantAddonFlavorList->Rewind(); fDormantAddonFlavorList->GetNext(&dafi); ) {
|
||||
if (dafi->AddonID == addon && dafi->AddonFlavorID == flavor_id && dafi->InfoValid == true) {
|
||||
*outFlavor = dafi->Info;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Default node management
|
||||
**********************************************************************/
|
||||
|
||||
status_t
|
||||
NodeManager::SetDefaultNode(node_type type, const media_node *node, const dormant_node_info *info, const media_input *input)
|
||||
{
|
||||
@ -686,6 +809,10 @@ NodeManager::RescanDefaultNodes()
|
||||
return fDefaultManager->Rescan();
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Cleanup of dead teams
|
||||
**********************************************************************/
|
||||
|
||||
void
|
||||
NodeManager::CleanupTeam(team_id team)
|
||||
{
|
||||
@ -697,9 +824,12 @@ NodeManager::CleanupTeam(team_id team)
|
||||
|
||||
// XXX send notifications after removing nodes
|
||||
|
||||
// Cleanup node references
|
||||
|
||||
registered_node *rn;
|
||||
for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) {
|
||||
// if the gone team was the creator of some global dormant node instance, we now invalidate that
|
||||
// we may want to remove that global node, but I'm not sure
|
||||
if (rn->creator == team) {
|
||||
rn->creator = -1;
|
||||
// fall through
|
||||
@ -727,8 +857,28 @@ NodeManager::CleanupTeam(team_id team)
|
||||
fRegisteredNodeMap->RemoveCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup addon references
|
||||
dormant_addon_flavor_info *dafi;
|
||||
for (fDormantAddonFlavorList->Rewind(); fDormantAddonFlavorList->GetNext(&dafi); ) {
|
||||
bool b;
|
||||
int32 *count;
|
||||
b = dafi->TeamInstancesCount.Get(team, &count);
|
||||
if (b) {
|
||||
FATAL("NodeManager::CleanupTeam: removing %ld instances from addon %ld, flavor %ld\n", *count, dafi->AddonID, dafi->AddonFlavorID);
|
||||
dafi->GlobalInstancesCount -= *count;
|
||||
if (dafi->GlobalInstancesCount < 0) // avoid underflow
|
||||
dafi->GlobalInstancesCount = 0;
|
||||
b = dafi->TeamInstancesCount.Remove(team);
|
||||
ASSERT(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* State saving/loading
|
||||
**********************************************************************/
|
||||
|
||||
status_t
|
||||
NodeManager::LoadState()
|
||||
{
|
||||
@ -743,11 +893,18 @@ NodeManager::SaveState()
|
||||
return fDefaultManager->SaveState();
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Debugging
|
||||
**********************************************************************/
|
||||
|
||||
void
|
||||
NodeManager::Dump()
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
printf("\n");
|
||||
|
||||
/* for each addon-id, the addon path map contians an entry_ref
|
||||
*/
|
||||
printf("NodeManager: addon path map follows:\n");
|
||||
entry_ref *ref;
|
||||
media_addon_id *id;
|
||||
@ -758,11 +915,14 @@ NodeManager::Dump()
|
||||
}
|
||||
printf("NodeManager: list end\n");
|
||||
printf("\n");
|
||||
|
||||
/* for each node-id, the registered node map contians information about source of the node, users, etc.
|
||||
*/
|
||||
printf("NodeManager: registered nodes map follows:\n");
|
||||
registered_node *rn;
|
||||
for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) {
|
||||
printf(" node-id %ld, addon-id %ld, addon-flavor-id %ld, port %ld, team %ld, kinds %#08Lx, name \"%s\"\n",
|
||||
rn->nodeid, rn->addon_id, rn->addon_flavor_id, rn->port, rn->team, rn->kinds, rn->name);
|
||||
printf(" node-id %ld, addon-id %ld, addon-flavor-id %ld, port %ld, creator %ld, team %ld, kinds %#08Lx, name \"%s\"\n",
|
||||
rn->nodeid, rn->addon_id, rn->addon_flavor_id, rn->port, rn->creator, rn->team, rn->kinds, rn->name);
|
||||
printf(" teams (refcount): ");
|
||||
team_id *team;
|
||||
int32 *refcount;
|
||||
@ -784,15 +944,22 @@ NodeManager::Dump()
|
||||
}
|
||||
printf("NodeManager: list end\n");
|
||||
printf("\n");
|
||||
|
||||
/*
|
||||
*/
|
||||
printf("NodeManager: dormant flavor list follows:\n");
|
||||
dormant_flavor_info *dfi;
|
||||
for (fDormantFlavorList->Rewind(); fDormantFlavorList->GetNext(&dfi); ) {
|
||||
printf(" addon-id %ld, addon-flavor-id %ld, addon-name \"%s\"\n",
|
||||
dfi->node_info.addon, dfi->node_info.flavor_id, dfi->node_info.name);
|
||||
dormant_addon_flavor_info *dafi;
|
||||
for (fDormantAddonFlavorList->Rewind(); fDormantAddonFlavorList->GetNext(&dafi); ) {
|
||||
printf(" AddonID %ld, AddonFlavorID %ld, MaxInstancesCount %ld, GlobalInstancesCount %ld, InfoValid %s\n",
|
||||
dafi->AddonID, dafi->AddonFlavorID, dafi->MaxInstancesCount, dafi->GlobalInstancesCount, dafi->InfoValid ? "yes" : "no");
|
||||
if (!dafi->InfoValid)
|
||||
continue;
|
||||
printf(" addon-id %ld, addon-flavor-id %ld, addon-name \"%s\"\n",
|
||||
dafi->Info.node_info.addon, dafi->Info.node_info.flavor_id, dafi->Info.node_info.name);
|
||||
printf(" flavor-kinds %#08Lx, flavor_flags %#08lx, internal_id %ld, possible_count %ld, in_format_count %ld, out_format_count %ld\n",
|
||||
dfi->kinds, dfi->flavor_flags, dfi->internal_id, dfi->possible_count, dfi->in_format_count, dfi->out_format_count);
|
||||
printf(" flavor-name \"%s\"\n", dfi->name);
|
||||
printf(" flavor-info \"%s\"\n", dfi->info);
|
||||
dafi->Info.kinds, dafi->Info.flavor_flags, dafi->Info.internal_id, dafi->Info.possible_count, dafi->Info.in_format_count, dafi->Info.out_format_count);
|
||||
printf(" flavor-name \"%s\"\n", dafi->Info.name);
|
||||
printf(" flavor-info \"%s\"\n", dafi->Info.info);
|
||||
}
|
||||
printf("NodeManager: list end\n");
|
||||
fDefaultManager->Dump();
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "TMap.h"
|
||||
#include "TStack.h"
|
||||
#include "DataExchange.h"
|
||||
#include "DefaultManager.h"
|
||||
|
||||
struct registered_node
|
||||
{
|
||||
@ -24,6 +23,21 @@ struct registered_node
|
||||
List<media_output> outputlist;
|
||||
};
|
||||
|
||||
struct dormant_addon_flavor_info
|
||||
{
|
||||
media_addon_id AddonID;
|
||||
int32 AddonFlavorID;
|
||||
|
||||
int32 MaxInstancesCount;
|
||||
int32 GlobalInstancesCount;
|
||||
|
||||
Map<team_id, int32> TeamInstancesCount;
|
||||
|
||||
bool InfoValid;
|
||||
dormant_flavor_info Info;
|
||||
};
|
||||
|
||||
class DefaultManager;
|
||||
class BufferManager;
|
||||
|
||||
class NodeManager
|
||||
@ -31,19 +45,7 @@ class NodeManager
|
||||
public:
|
||||
NodeManager();
|
||||
~NodeManager();
|
||||
status_t RegisterNode(BMessenger, media_node &, char const *, long *, char const *, long, char const *, long, media_type, media_type);
|
||||
status_t UnregisterNode(long);
|
||||
status_t GetNodes(BMessage &, char const *);
|
||||
status_t GetLiveNode(BMessage &, char const *, long);
|
||||
status_t GetLiveNodes(BMessage &, char const *, media_format const *, media_format const *, char const *, unsigned long);
|
||||
status_t FindNode(long, media_node &);
|
||||
status_t FindSaveInfo(long, char const **, long *, long *, char const **);
|
||||
status_t FindDormantNodeFor(long, dormant_node_info *);
|
||||
status_t FindNodesFor(long, long, BMessage &, char const *);
|
||||
status_t FindNodesForPort(long, BMessage &, char const *);
|
||||
status_t UnregisterTeamNodes(long, BMessage &, char const *, long *, BufferManager *);
|
||||
status_t DumpGlobalReferences(BMessage &, char const *);
|
||||
status_t BroadcastMessage(long, void *, long, long long);
|
||||
|
||||
status_t LoadState();
|
||||
status_t SaveState();
|
||||
|
||||
@ -76,12 +78,18 @@ public:
|
||||
* int32 "media_node_id" (multiple items)
|
||||
*/
|
||||
status_t GetLiveNodes(BMessage *msg);
|
||||
|
||||
void AddDormantFlavorInfo(const dormant_flavor_info &dfi);
|
||||
void RemoveDormantFlavorInfo(media_addon_id id);
|
||||
void CleanupDormantFlavorInfos();
|
||||
|
||||
void RegisterAddon(const entry_ref &ref, media_addon_id *newid);
|
||||
void UnregisterAddon(media_addon_id id);
|
||||
|
||||
void AddDormantFlavorInfo(const dormant_flavor_info &dfi);
|
||||
void InvalidateDormantFlavorInfo(media_addon_id id);
|
||||
void RemoveDormantFlavorInfo(media_addon_id id);
|
||||
void CleanupDormantFlavorInfos();
|
||||
|
||||
status_t IncrementAddonFlavorInstancesCount(media_addon_id addonid, int32 flavorid, team_id team);
|
||||
status_t DecrementAddonFlavorInstancesCount(media_addon_id addonid, int32 flavorid, team_id team);
|
||||
|
||||
status_t GetAddonRef(entry_ref *ref, media_addon_id id);
|
||||
status_t GetDormantNodes(dormant_node_info * out_info,
|
||||
int32 * io_count,
|
||||
@ -102,7 +110,7 @@ private:
|
||||
media_node_id fNextNodeID;
|
||||
|
||||
BLocker *fLocker;
|
||||
List<dormant_flavor_info> *fDormantFlavorList;
|
||||
List<dormant_addon_flavor_info> *fDormantAddonFlavorList;
|
||||
Map<media_addon_id,entry_ref> *fAddonPathMap;
|
||||
Map<media_node_id,registered_node> *fRegisteredNodeMap;
|
||||
DefaultManager *fDefaultManager;
|
||||
|
@ -175,6 +175,19 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
status_t rv;
|
||||
INFO("ServerApp::HandleMessage %#lx\n", code);
|
||||
switch (code) {
|
||||
case SERVER_CHANGE_ADDON_FLAVOR_INSTANCES_COUNT:
|
||||
{
|
||||
const server_change_addon_flavor_instances_count_request *request = reinterpret_cast<const server_change_addon_flavor_instances_count_request *>(data);
|
||||
server_change_addon_flavor_instances_count_reply reply;
|
||||
ASSERT(request->delta == 1 || request->delta == -1);
|
||||
if (request->delta == 1)
|
||||
rv = gNodeManager->IncrementAddonFlavorInstancesCount(request->addonid, request->flavorid, request->team);
|
||||
else
|
||||
rv = gNodeManager->DecrementAddonFlavorInstancesCount(request->addonid, request->flavorid, request->team);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_RESCAN_DEFAULTS:
|
||||
{
|
||||
gNodeManager->RescanDefaultNodes();
|
||||
@ -415,7 +428,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
xfer_server_register_dormant_node *msg = (xfer_server_register_dormant_node *)data;
|
||||
dormant_flavor_info dfi;
|
||||
if (msg->purge_id > 0)
|
||||
gNodeManager->RemoveDormantFlavorInfo(msg->purge_id);
|
||||
gNodeManager->InvalidateDormantFlavorInfo(msg->purge_id);
|
||||
rv = dfi.Unflatten(msg->dfi_type, &(msg->dfi), msg->dfi_size);
|
||||
ASSERT(rv == B_OK);
|
||||
gNodeManager->AddDormantFlavorInfo(dfi);
|
||||
|
Loading…
Reference in New Issue
Block a user