added automatic media_addon_server launching and termination.
added detection of and cleanup after application crashes. if the media_addon_server crashes, it will be restarted. removed preleminary volume control functions. removed unneeded media_server functions. changed application registration to use port based messaging. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2027 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
4ff6d49f35
commit
6396865dcd
@ -9,6 +9,7 @@
|
||||
#include <MediaDefs.h>
|
||||
#include <MediaNode.h>
|
||||
#include <MediaAddOn.h>
|
||||
#include <Messenger.h>
|
||||
#include <Entry.h>
|
||||
|
||||
namespace BPrivate {
|
||||
@ -73,7 +74,12 @@ enum {
|
||||
|
||||
// Raw port based communication
|
||||
enum {
|
||||
ADDONSERVER_RESCAN_MEDIAADDON_FLAVORS = 0x50,
|
||||
|
||||
SERVER_MESSAGE_START = 0x100,
|
||||
SERVER_REGISTER_ADDONSERVER,
|
||||
SERVER_REGISTER_APP,
|
||||
SERVER_UNREGISTER_APP,
|
||||
SERVER_GET_NODE,
|
||||
SERVER_SET_NODE,
|
||||
SERVER_PUBLISH_INPUTS,
|
||||
@ -623,13 +629,33 @@ struct consumer_seek_tag_requested_reply : public reply_data
|
||||
|
||||
|
||||
|
||||
struct server_register_addonserver_request : public request_data
|
||||
{
|
||||
team_id team;
|
||||
};
|
||||
|
||||
struct server_register_addonserver_reply : public reply_data
|
||||
{
|
||||
};
|
||||
|
||||
struct server_register_app_request : public request_data
|
||||
{
|
||||
team_id team;
|
||||
BMessenger messenger;
|
||||
};
|
||||
|
||||
struct server_register_app_reply : public reply_data
|
||||
{
|
||||
};
|
||||
|
||||
struct server_unregister_app_request : public request_data
|
||||
{
|
||||
team_id team;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct server_unregister_app_reply : public reply_data
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -8,8 +8,6 @@
|
||||
#include <malloc.h>
|
||||
#define DEBUG 3
|
||||
#include "debug.h"
|
||||
#include "PortPool.h"
|
||||
#include "ServerInterface.h"
|
||||
#include "DataExchange.h"
|
||||
|
||||
/*
|
||||
@ -538,15 +536,10 @@ BMediaAddOn::NotifyFlavorChange()
|
||||
CALLED();
|
||||
if (fAddon == 0)
|
||||
return B_ERROR;
|
||||
|
||||
port_id port;
|
||||
port = find_port("media_addon_server port");
|
||||
if (port <= B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
addonserver_rescan_mediaaddon_flavors_command msg;
|
||||
msg.addonid = fAddon;
|
||||
return write_port(port, ADDONSERVER_RESCAN_MEDIAADDON_FLAVORS, &msg, sizeof(msg));
|
||||
addonserver_rescan_mediaaddon_flavors_command command;
|
||||
command.addonid = fAddon;
|
||||
return SendToAddonServer(ADDONSERVER_RESCAN_MEDIAADDON_FLAVORS, &command, sizeof(command));
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
|
@ -34,10 +34,14 @@ using namespace BPrivate::media;
|
||||
class _DefaultDeleter
|
||||
{
|
||||
public:
|
||||
~_DefaultDeleter() { delete BMediaRoster::_sDefault; }
|
||||
};
|
||||
|
||||
_DefaultDeleter _deleter;
|
||||
~_DefaultDeleter()
|
||||
{
|
||||
if (BMediaRoster::_sDefault) {
|
||||
BMediaRoster::_sDefault->Lock();
|
||||
BMediaRoster::_sDefault->Quit();
|
||||
}
|
||||
}
|
||||
} _deleter;
|
||||
|
||||
namespace BPrivate { namespace media { namespace mediaroster {
|
||||
|
||||
@ -662,10 +666,10 @@ BMediaRoster::StartNode(const media_node & node,
|
||||
if (node.node <= 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
|
||||
node_start_command msg;
|
||||
msg.performance_time = at_performance_time;
|
||||
node_start_command command;
|
||||
command.performance_time = at_performance_time;
|
||||
|
||||
return write_port(node.port, NODE_START, &msg, sizeof(msg));
|
||||
return SendToPort(node.port, NODE_START, &command, sizeof(command));
|
||||
}
|
||||
|
||||
|
||||
@ -678,11 +682,11 @@ BMediaRoster::StopNode(const media_node & node,
|
||||
if (node.node <= 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
|
||||
node_stop_command msg;
|
||||
msg.performance_time = at_performance_time;
|
||||
msg.immediate = immediate;
|
||||
node_stop_command command;
|
||||
command.performance_time = at_performance_time;
|
||||
command.immediate = immediate;
|
||||
|
||||
return write_port(node.port, NODE_STOP, &msg, sizeof(msg));
|
||||
return SendToPort(node.port, NODE_STOP, &command, sizeof(command));
|
||||
}
|
||||
|
||||
|
||||
@ -695,11 +699,11 @@ BMediaRoster::SeekNode(const media_node & node,
|
||||
if (node.node <= 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
|
||||
node_seek_command msg;
|
||||
msg.media_time = to_media_time;
|
||||
msg.performance_time = at_performance_time;
|
||||
node_seek_command command;
|
||||
command.media_time = to_media_time;
|
||||
command.performance_time = at_performance_time;
|
||||
|
||||
return write_port(node.port, NODE_SEEK, &msg, sizeof(msg));
|
||||
return SendToPort(node.port, NODE_SEEK, &command, sizeof(command));
|
||||
}
|
||||
|
||||
|
||||
@ -1933,13 +1937,21 @@ BMediaRoster::MediaFlags(media_flags cap,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* BLooper overrides */
|
||||
/* virtual */ void
|
||||
BMediaRoster::MessageReceived(BMessage * message)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
// media_server plays ping-pong with the BMediaRosters
|
||||
// to detect dead teams. Normal communication uses ports.
|
||||
static BMessage pong('PONG');
|
||||
if (message->what == 'PING') {
|
||||
message->SendReply(&pong, static_cast<BHandler *>(NULL), 2000000);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("BMediaRoster::MessageReceived: unknown message!\n");
|
||||
message->PrintToStream();
|
||||
}
|
||||
|
||||
/* virtual */ bool
|
||||
@ -1972,10 +1984,12 @@ BMediaRoster::GetSupportedSuites(BMessage *data)
|
||||
BMediaRoster::~BMediaRoster()
|
||||
{
|
||||
CALLED();
|
||||
BMessage msg(MEDIA_SERVER_UNREGISTER_APP);
|
||||
BMessage reply;
|
||||
msg.AddInt32("team",team);
|
||||
QueryServer(&msg, &reply);
|
||||
|
||||
// unregister this application with the media server
|
||||
server_unregister_app_request request;
|
||||
server_unregister_app_reply reply;
|
||||
request.team = team;
|
||||
QueryServer(SERVER_UNREGISTER_APP, &request, sizeof(request), &reply, sizeof(reply));
|
||||
}
|
||||
|
||||
|
||||
@ -2007,15 +2021,22 @@ status_t BMediaRoster::_Reserved_MediaRoster_7(void *) { return B_ERROR; }
|
||||
|
||||
|
||||
BMediaRoster::BMediaRoster() :
|
||||
BLooper("BMediaRoster looper",B_NORMAL_PRIORITY,B_LOOPER_PORT_DEFAULT_CAPACITY)
|
||||
BLooper("_BMediaRoster_", B_URGENT_DISPLAY_PRIORITY, B_LOOPER_PORT_DEFAULT_CAPACITY)
|
||||
{
|
||||
CALLED();
|
||||
BMessage msg(MEDIA_SERVER_REGISTER_APP);
|
||||
BMessage reply;
|
||||
msg.AddInt32("team",team);
|
||||
QueryServer(&msg,&reply);
|
||||
|
||||
// start the looper
|
||||
Run();
|
||||
|
||||
// register this application with the media server
|
||||
server_register_app_request request;
|
||||
server_register_app_reply reply;
|
||||
request.team = team;
|
||||
request.messenger = BMessenger(NULL, this);
|
||||
QueryServer(SERVER_REGISTER_APP, &request, sizeof(request), &reply, sizeof(reply));
|
||||
}
|
||||
|
||||
|
||||
/* static */ status_t
|
||||
BMediaRoster::ParseCommand(BMessage & reply)
|
||||
{
|
||||
@ -2023,7 +2044,6 @@ BMediaRoster::ParseCommand(BMessage & reply)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
status_t
|
||||
BMediaRoster::GetDefaultInfo(media_node_id for_default,
|
||||
|
@ -14,44 +14,10 @@ namespace MediaKitPrivate {
|
||||
|
||||
status_t GetMasterVolume(float *left, float *right)
|
||||
{
|
||||
CALLED();
|
||||
BMessenger m(NEW_MEDIA_SERVER_SIGNATURE);
|
||||
BMessage msg(MEDIA_SERVER_GET_VOLUME);
|
||||
BMessage reply;
|
||||
status_t s;
|
||||
|
||||
if (!m.IsValid())
|
||||
return B_ERROR;
|
||||
|
||||
s = m.SendMessage(&msg,&reply);
|
||||
if (s != B_OK)
|
||||
return s;
|
||||
|
||||
reply.FindFloat("left",left);
|
||||
reply.FindFloat("right",right);
|
||||
|
||||
return (status_t)reply.what;
|
||||
}
|
||||
|
||||
status_t SetMasterVolume(float left, float right)
|
||||
{
|
||||
CALLED();
|
||||
BMessenger m(NEW_MEDIA_SERVER_SIGNATURE);
|
||||
BMessage msg(MEDIA_SERVER_SET_VOLUME);
|
||||
BMessage reply;
|
||||
status_t s;
|
||||
|
||||
if (!m.IsValid())
|
||||
return B_ERROR;
|
||||
|
||||
msg.AddFloat("left",left);
|
||||
msg.AddFloat("right",right);
|
||||
|
||||
s = m.SendMessage(&msg,&reply);
|
||||
if (s != B_OK)
|
||||
return s;
|
||||
|
||||
return (status_t)reply.what;
|
||||
}
|
||||
|
||||
} //namespace MediaKitPrivate
|
||||
|
@ -2,87 +2,211 @@
|
||||
* Copyright 2002, Marcus Overhagen. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#define DEBUG 1
|
||||
|
||||
#include <OS.h>
|
||||
#include <Application.h>
|
||||
#include <Roster.h>
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <Messenger.h>
|
||||
#include <Autolock.h>
|
||||
#include <stdio.h>
|
||||
#include <Debug.h>
|
||||
#include "AppManager.h"
|
||||
|
||||
AppManager::AppManager()
|
||||
: fAddonServer(-1)
|
||||
{
|
||||
fAppMap = new Map<team_id, App>;
|
||||
fLocker = new BLocker;
|
||||
fQuit = create_sem(0, "big brother waits");
|
||||
fBigBrother = spawn_thread(bigbrother, "big brother is watching you", B_NORMAL_PRIORITY, this);
|
||||
resume_thread(fBigBrother);
|
||||
}
|
||||
|
||||
AppManager::~AppManager()
|
||||
{
|
||||
status_t err;
|
||||
delete_sem(fQuit);
|
||||
wait_for_thread(fBigBrother, &err);
|
||||
delete fLocker;
|
||||
delete fAppMap;
|
||||
}
|
||||
|
||||
bool AppManager::HasTeam(team_id team)
|
||||
{
|
||||
BAutolock lock(mLocker);
|
||||
ListItem *item;
|
||||
for (int32 i = 0; (item = (ListItem *)mList.ItemAt(i)) != NULL; i++)
|
||||
if (item->team == team)
|
||||
return true;
|
||||
return false;
|
||||
BAutolock lock(fLocker);
|
||||
App app;
|
||||
return fAppMap->Get(team, &app);
|
||||
}
|
||||
|
||||
status_t AppManager::RegisterTeam(team_id team, BMessenger messenger)
|
||||
{
|
||||
printf("AppManager::RegisterTeam %d\n",(int) team);
|
||||
|
||||
BAutolock lock(mLocker);
|
||||
ListItem *item;
|
||||
|
||||
BAutolock lock(fLocker);
|
||||
printf("AppManager::RegisterTeam %ld\n", team);
|
||||
if (HasTeam(team))
|
||||
return B_ERROR;
|
||||
|
||||
item = new ListItem;
|
||||
item->team = team;
|
||||
item->messenger = messenger;
|
||||
|
||||
return mList.AddItem(item) ? B_OK : B_ERROR;
|
||||
App app;
|
||||
app.team = team;
|
||||
app.messenger = messenger;
|
||||
return fAppMap->Insert(team, app) ? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
status_t AppManager::UnregisterTeam(team_id team)
|
||||
{
|
||||
printf("AppManager::UnregisterTeam %d\n",(int) team);
|
||||
bool is_removed;
|
||||
bool is_addon_server;
|
||||
|
||||
printf("AppManager::UnregisterTeam %ld\n", team);
|
||||
|
||||
fLocker->Lock();
|
||||
is_removed = fAppMap->Remove(team);
|
||||
is_addon_server = fAddonServer == team;
|
||||
if (is_addon_server)
|
||||
fAddonServer = -1;
|
||||
fLocker->Unlock();
|
||||
|
||||
CleanupTeam(team);
|
||||
if (is_addon_server)
|
||||
CleanupAddonServer();
|
||||
|
||||
return is_removed ? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
BAutolock lock(mLocker);
|
||||
ListItem *item;
|
||||
for (int32 i = 0; (item = (ListItem *)mList.ItemAt(i)) != NULL; i++)
|
||||
if (item->team == team) {
|
||||
if (mList.RemoveItem(item)) {
|
||||
delete item;
|
||||
return B_OK;
|
||||
} else {
|
||||
break;
|
||||
void AppManager::RestartAddonServer()
|
||||
{
|
||||
static bigtime_t restart_period = 0;
|
||||
static int restart_tries = 0;
|
||||
restart_tries++;
|
||||
|
||||
if (((system_time() - restart_period) > 60000000LL) && (restart_tries < 5)) {
|
||||
restart_period = system_time();
|
||||
restart_tries = 0;
|
||||
}
|
||||
if (restart_tries < 5) {
|
||||
printf("AppManager: Restarting media_addon_server...\n");
|
||||
// XXX fixme. We should wait until it is *really* gone
|
||||
snooze(5000000);
|
||||
StartAddonServer();
|
||||
} else {
|
||||
printf("AppManager: media_addon_server crashed too often, not restarted\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AppManager::TeamDied(team_id team)
|
||||
{
|
||||
CleanupTeam(team);
|
||||
fLocker->Lock();
|
||||
fAppMap->Remove(team);
|
||||
fLocker->Unlock();
|
||||
}
|
||||
|
||||
status_t AppManager::RegisterAddonServer(team_id team)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
if (fAddonServer != -1)
|
||||
return B_ERROR;
|
||||
fAddonServer = team;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// The BigBrother thread send ping messages to the BMediaRoster of
|
||||
// all currently running teams. If the reply times out or is wrong,
|
||||
// the team cleanup function TeamDied() will be called. If the dead
|
||||
// team is the media_addon_server, additionally CleanupAddonServer()
|
||||
// will be called and also RestartAddonServer()
|
||||
//=========================================================================
|
||||
|
||||
int32 AppManager::bigbrother(void *self)
|
||||
{
|
||||
static_cast<AppManager *>(self)->BigBrother();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AppManager::BigBrother()
|
||||
{
|
||||
bool restart_addon_server;
|
||||
status_t status;
|
||||
BMessage msg('PING');
|
||||
BMessage reply;
|
||||
team_id team;
|
||||
App *app;
|
||||
do {
|
||||
if (!fLocker->Lock())
|
||||
break;
|
||||
for (int32 i = 0; fAppMap->GetPointerAt(i, &app); i++) {
|
||||
reply.what = 0;
|
||||
status = app->messenger.SendMessage(&msg, &reply, 5000000, 2000000);
|
||||
if (status != B_OK || reply.what != 'PONG') {
|
||||
team = app->team;
|
||||
if (fAddonServer == team) {
|
||||
restart_addon_server = true;
|
||||
fAddonServer = -1;
|
||||
} else {
|
||||
restart_addon_server = false;
|
||||
}
|
||||
fLocker->Unlock();
|
||||
TeamDied(team);
|
||||
if (restart_addon_server) {
|
||||
CleanupAddonServer();
|
||||
RestartAddonServer();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return B_ERROR;
|
||||
fLocker->Unlock();
|
||||
status = acquire_sem_etc(fQuit, 1, B_RELATIVE_TIMEOUT, 2000000);
|
||||
} while (status == B_TIMED_OUT || status == B_INTERRUPTED);
|
||||
}
|
||||
|
||||
void AppManager::BroadcastMessage(BMessage *msg, bigtime_t timeout)
|
||||
//=========================================================================
|
||||
// The following functions must be called unlocked.
|
||||
// They clean up after a crash, or start/terminate the media_addon_server.
|
||||
//=========================================================================
|
||||
|
||||
void AppManager::CleanupTeam(team_id team)
|
||||
{
|
||||
BAutolock lock(mLocker);
|
||||
ListItem *item;
|
||||
for (int32 i = 0; (item = (ListItem *)mList.ItemAt(i)) != NULL; i++)
|
||||
if (B_OK != item->messenger.SendMessage(msg,(BHandler *)NULL,timeout))
|
||||
HandleBroadcastError(msg, item->messenger, item->team, timeout);
|
||||
ASSERT(false == fLocker->IsLocked());
|
||||
|
||||
printf("AppManager: cleaning up team %ld\n", team);
|
||||
|
||||
}
|
||||
|
||||
void AppManager::HandleBroadcastError(BMessage *msg, BMessenger &, team_id team, bigtime_t timeout)
|
||||
void AppManager::CleanupAddonServer()
|
||||
{
|
||||
BAutolock lock(mLocker);
|
||||
printf("error broadcasting team %d with message after %.3f seconds\n",int(team),timeout / 1000000.0);
|
||||
msg->PrintToStream();
|
||||
ASSERT(false == fLocker->IsLocked());
|
||||
|
||||
printf("AppManager: cleaning up media_addon_server\n");
|
||||
|
||||
}
|
||||
|
||||
status_t AppManager::LoadState()
|
||||
void AppManager::StartAddonServer()
|
||||
{
|
||||
return B_ERROR;
|
||||
ASSERT(false == fLocker->IsLocked());
|
||||
|
||||
app_info info;
|
||||
be_app->GetAppInfo(&info);
|
||||
BEntry entry(&info.ref);
|
||||
entry.GetParent(&entry);
|
||||
BDirectory dir(&entry);
|
||||
entry.SetTo(&dir, "media_addon_server");
|
||||
entry_ref ref;
|
||||
entry.GetRef(&ref);
|
||||
be_roster->Launch(&ref);
|
||||
}
|
||||
|
||||
status_t AppManager::SaveState()
|
||||
void AppManager::TerminateAddonServer()
|
||||
{
|
||||
return B_ERROR;
|
||||
ASSERT(false == fLocker->IsLocked());
|
||||
|
||||
if (fAddonServer != -1) {
|
||||
BMessenger msger(NULL, fAddonServer);
|
||||
msger.SendMessage(B_QUIT_REQUESTED);
|
||||
// XXX fixme. We should wait until it is gone
|
||||
snooze(1000000);
|
||||
}
|
||||
}
|
||||
|
@ -3,26 +3,38 @@
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <List.h>
|
||||
#include <Locker.h>
|
||||
#include "TMap.h"
|
||||
|
||||
class AppManager
|
||||
{
|
||||
public:
|
||||
AppManager();
|
||||
~AppManager();
|
||||
bool HasTeam(team_id);
|
||||
|
||||
status_t RegisterAddonServer(team_id);
|
||||
status_t RegisterTeam(team_id, BMessenger);
|
||||
status_t UnregisterTeam(team_id);
|
||||
void BroadcastMessage(BMessage *msg, bigtime_t timeout);
|
||||
void HandleBroadcastError(BMessage *, BMessenger &, team_id team, bigtime_t timeout);
|
||||
status_t LoadState();
|
||||
status_t SaveState();
|
||||
bool HasTeam(team_id);
|
||||
void StartAddonServer();
|
||||
void TerminateAddonServer();
|
||||
|
||||
private:
|
||||
struct ListItem {
|
||||
void CleanupTeam(team_id);
|
||||
void CleanupAddonServer();
|
||||
void TeamDied(team_id team);
|
||||
void RestartAddonServer();
|
||||
static int32 bigbrother(void *self);
|
||||
void BigBrother();
|
||||
|
||||
private:
|
||||
team_id fAddonServer;
|
||||
thread_id fBigBrother;
|
||||
sem_id fQuit;
|
||||
|
||||
struct App {
|
||||
team_id team;
|
||||
BMessenger messenger;
|
||||
};
|
||||
BList mList;
|
||||
BLocker mLocker;
|
||||
Map<team_id, App> * fAppMap;
|
||||
BLocker *fLocker;
|
||||
};
|
||||
|
@ -9,47 +9,10 @@
|
||||
#define NEW_MEDIA_SERVER_SIGNATURE "application/x-vnd.OpenBeOS-media-server"
|
||||
|
||||
enum {
|
||||
// Application management
|
||||
MEDIA_SERVER_REGISTER_APP,
|
||||
MEDIA_SERVER_UNREGISTER_APP,
|
||||
|
||||
// Buffer management
|
||||
MEDIA_SERVER_GET_SHARED_BUFFER_AREA,
|
||||
MEDIA_SERVER_REGISTER_BUFFER,
|
||||
MEDIA_SERVER_UNREGISTER_BUFFER,
|
||||
|
||||
// Something else
|
||||
MEDIA_SERVER_SET_VOLUME,
|
||||
MEDIA_SERVER_GET_VOLUME,
|
||||
MEDIA_SERVER_GET_NODE_ID,
|
||||
MEDIA_SERVER_FIND_RUNNING_INSTANCES,
|
||||
MEDIA_SERVER_BUFFER_GROUP_REG,
|
||||
MEDIA_SERVER_GET_LATENT_INFO,
|
||||
MEDIA_SERVER_GET_DORMANT_FILE_FORMATS,
|
||||
MEDIA_SERVER_GET_GETDORMANTFLAVOR,
|
||||
MEDIA_SERVER_BROADCAST_MESSAGE,
|
||||
MEDIA_SERVER_RELEASE_NODE_REFERENCE,
|
||||
MEDIA_SERVER_SET_REALTIME_FLAGS,
|
||||
MEDIA_SERVER_GET_REALTIME_FLAGS,
|
||||
MEDIA_SERVER_INSTANTIATE_PERSISTENT_NODE,
|
||||
MEDIA_SERVER_SNIFF_FILE,
|
||||
MEDIA_SERVER_QUERY_LATENTS,
|
||||
MEDIA_SERVER_REGISTER_NODE,
|
||||
MEDIA_SERVER_UNREGISTER_NODE,
|
||||
MEDIA_SERVER_SET_DEFAULT,
|
||||
MEDIA_SERVER_ACQUIRE_NODE_REFERENCE,
|
||||
MEDIA_SERVER_SET_OUTPUT_BUFFERS,
|
||||
MEDIA_SERVER_RECLAIM_OUTPUT_BUFFERS,
|
||||
MEDIA_SERVER_ORPHAN_RECLAIMABLE_BUFFERS,
|
||||
MEDIA_SERVER_SET_TIME_SOURCE,
|
||||
MEDIA_SERVER_QUERY_NODES,
|
||||
MEDIA_SERVER_GET_DORMANT_NODE,
|
||||
MEDIA_SERVER_FORMAT_CHANGED,
|
||||
MEDIA_SERVER_GET_DEFAULT_INFO,
|
||||
MEDIA_SERVER_GET_RUNNING_DEFAULT,
|
||||
MEDIA_SERVER_SET_RUNNING_DEFAULT,
|
||||
MEDIA_SERVER_TYPE_ITEM_OP,
|
||||
MEDIA_SERVER_FORMAT_OP
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -57,7 +20,6 @@ enum {
|
||||
SERVER_REGISTER_MEDIAADDON,
|
||||
SERVER_UNREGISTER_MEDIAADDON,
|
||||
SERVER_GET_MEDIAADDON_REF,
|
||||
ADDONSERVER_RESCAN_MEDIAADDON_FLAVORS,
|
||||
SERVER_REGISTER_DORMANT_NODE,
|
||||
SERVER_GET_DORMANT_NODES,
|
||||
SERVER_GET_DORMANT_FLAVOR_INFO,
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
ServerApp();
|
||||
~ServerApp();
|
||||
|
||||
bool QuitRequested();
|
||||
void HandleMessage(int32 code, void *data, size_t size);
|
||||
static int32 controlthread(void *arg);
|
||||
|
||||
@ -52,41 +53,6 @@ public:
|
||||
void RegisterBuffer(BMessage *msg);
|
||||
void UnregisterBuffer(BMessage *msg);
|
||||
|
||||
void GetNodeID(BMessage *);
|
||||
void FindRunningInstances(BMessage *);
|
||||
void BufferGroupReg(BMessage *);
|
||||
void GetLatentInfo(BMessage *);
|
||||
void GetDormantFileFormats(BMessage *);
|
||||
void GetDormantFlavor(BMessage *);
|
||||
void BroadcastMessage(BMessage *);
|
||||
void ReleaseNodeReference(BMessage *);
|
||||
void SetRealtimeFlags(BMessage *);
|
||||
void GetRealtimeFlags(BMessage *);
|
||||
void InstantiatePersistentNode(BMessage *);
|
||||
void SniffFile(BMessage *);
|
||||
void QueryLatents(BMessage *);
|
||||
void RegisterApp(BMessage *);
|
||||
void UnregisterApp(BMessage *);
|
||||
void RegisterNode(BMessage *);
|
||||
void UnregisterNode(BMessage *);
|
||||
void SetDefault(BMessage *);
|
||||
void AcquireNodeReference(BMessage *);
|
||||
void SetOutputBuffers(BMessage *);
|
||||
void ReclaimOutputBuffers(BMessage *);
|
||||
void OrphanReclaimableBuffers(BMessage *);
|
||||
void SetTimeSource(BMessage *);
|
||||
void QueryNodes(BMessage *);
|
||||
void GetDormantNode(BMessage *);
|
||||
void FormatChanged(BMessage *);
|
||||
void GetDefaultInfo(BMessage *);
|
||||
void GetRunningDefault(BMessage *);
|
||||
void SetRunningDefault(BMessage *);
|
||||
void TypeItemOp(BMessage *);
|
||||
void FormatOp(BMessage *);
|
||||
|
||||
void SetVolume(BMessage *);
|
||||
void GetVolume(BMessage *);
|
||||
|
||||
/* functionality not yet implemented
|
||||
00014a00 T _ServerApp::_ServerApp(void)
|
||||
00014e1c T _ServerApp::~_ServerApp(void)
|
||||
@ -114,18 +80,13 @@ private:
|
||||
|
||||
BLocker *fLocker;
|
||||
|
||||
float fVolumeLeft;
|
||||
float fVolumeRight;
|
||||
|
||||
void MessageReceived(BMessage *msg);
|
||||
typedef BApplication inherited;
|
||||
};
|
||||
|
||||
ServerApp::ServerApp()
|
||||
: BApplication(NEW_MEDIA_SERVER_SIGNATURE),
|
||||
fLocker(new BLocker("server locker")),
|
||||
fVolumeLeft(0.0),
|
||||
fVolumeRight(0.0)
|
||||
fLocker(new BLocker("server locker"))
|
||||
{
|
||||
//load volume settings from config file
|
||||
//mVolumeLeft = ???;
|
||||
@ -137,12 +98,15 @@ ServerApp::ServerApp()
|
||||
gNodeManager = new NodeManager;
|
||||
|
||||
control_port = create_port(64,"media_server port");
|
||||
control_thread = spawn_thread(controlthread,"media_server control",12,this);
|
||||
control_thread = spawn_thread(controlthread, "media_server control", 105, this);
|
||||
resume_thread(control_thread);
|
||||
|
||||
gAppManager->StartAddonServer();
|
||||
}
|
||||
|
||||
ServerApp::~ServerApp()
|
||||
{
|
||||
printf("####ServerApp::~ServerApp()\n");
|
||||
delete gNotificationManager;
|
||||
delete gBufferManager;
|
||||
delete gAppManager;
|
||||
@ -153,6 +117,13 @@ ServerApp::~ServerApp()
|
||||
wait_for_thread(control_thread,&err);
|
||||
}
|
||||
|
||||
bool
|
||||
ServerApp::QuitRequested()
|
||||
{
|
||||
printf("####ServerApp::QuitRequested()\n");
|
||||
gAppManager->TerminateAddonServer();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
@ -160,6 +131,33 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
status_t rv;
|
||||
printf("ServerApp::HandleMessage %#lx\n", code);
|
||||
switch (code) {
|
||||
case SERVER_REGISTER_ADDONSERVER:
|
||||
{
|
||||
const server_register_addonserver_request *request = reinterpret_cast<const server_register_addonserver_request *>(data);
|
||||
server_register_addonserver_reply reply;
|
||||
rv = gAppManager->RegisterAddonServer(request->team);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_REGISTER_APP:
|
||||
{
|
||||
const server_register_app_request *request = reinterpret_cast<const server_register_app_request *>(data);
|
||||
server_register_app_reply reply;
|
||||
rv = gAppManager->RegisterTeam(request->team, request->messenger);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_UNREGISTER_APP:
|
||||
{
|
||||
const server_unregister_app_request *request = reinterpret_cast<const server_unregister_app_request *>(data);
|
||||
server_unregister_app_reply reply;
|
||||
rv = gAppManager->UnregisterTeam(request->team);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_GET_MEDIAADDON_REF:
|
||||
{
|
||||
server_get_mediaaddon_ref_request *msg = (server_get_mediaaddon_ref_request *)data;
|
||||
@ -505,206 +503,6 @@ ServerApp::UnregisterBuffer(BMessage *msg)
|
||||
msg->SendReply(&reply,(BHandler*)NULL,REPLY_TIMEOUT);
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::GetNodeID(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::FindRunningInstances(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::BufferGroupReg(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::GetLatentInfo(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::GetDormantFileFormats(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::GetDormantFlavor(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::BroadcastMessage(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::ReleaseNodeReference(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::SetRealtimeFlags(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::GetRealtimeFlags(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::InstantiatePersistentNode(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::SniffFile(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::QueryLatents(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::RegisterApp(BMessage *msg)
|
||||
{
|
||||
team_id team;
|
||||
msg->FindInt32("team", &team);
|
||||
gAppManager->RegisterTeam(team, msg->ReturnAddress());
|
||||
|
||||
BMessage reply(B_OK);
|
||||
msg->SendReply(&reply,(BHandler*)NULL,REPLY_TIMEOUT);
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::UnregisterApp(BMessage *msg)
|
||||
{
|
||||
team_id team;
|
||||
msg->FindInt32("team", &team);
|
||||
gAppManager->UnregisterTeam(team);
|
||||
|
||||
BMessage reply(B_OK);
|
||||
msg->SendReply(&reply,(BHandler*)NULL,REPLY_TIMEOUT);
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::RegisterNode(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::UnregisterNode(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::SetDefault(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::AcquireNodeReference(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::SetOutputBuffers(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::ReclaimOutputBuffers(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::OrphanReclaimableBuffers(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::SetTimeSource(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::QueryNodes(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::GetDormantNode(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::FormatChanged(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::GetDefaultInfo(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::GetRunningDefault(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::SetRunningDefault(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::TypeItemOp(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::FormatOp(BMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
void ServerApp::SetVolume(BMessage *msg)
|
||||
{
|
||||
float left;
|
||||
float right;
|
||||
msg->FindFloat("left", &left);
|
||||
msg->FindFloat("right", &right);
|
||||
|
||||
fLocker->Lock();
|
||||
fVolumeLeft = left;
|
||||
fVolumeRight = right;
|
||||
fLocker->Unlock();
|
||||
|
||||
//save volume settings to config file
|
||||
// ??? = left;
|
||||
// ??? = right;
|
||||
|
||||
BMessage reply(B_OK);
|
||||
msg->SendReply(&reply,(BHandler*)NULL,REPLY_TIMEOUT);
|
||||
}
|
||||
|
||||
void ServerApp::GetVolume(BMessage *msg)
|
||||
{
|
||||
BMessage reply(B_OK);
|
||||
|
||||
fLocker->Lock();
|
||||
reply.AddFloat("left", fVolumeLeft);
|
||||
reply.AddFloat("right", fVolumeRight);
|
||||
fLocker->Unlock();
|
||||
|
||||
msg->SendReply(&reply,(BHandler*)NULL,REPLY_TIMEOUT);
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::MessageReceived(BMessage *msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
@ -714,41 +512,6 @@ void ServerApp::MessageReceived(BMessage *msg)
|
||||
case MEDIA_SERVER_REQUEST_NOTIFICATIONS: gNotificationManager->EnqueueMessage(msg); break;
|
||||
case MEDIA_SERVER_CANCEL_NOTIFICATIONS: gNotificationManager->EnqueueMessage(msg); break;
|
||||
case MEDIA_SERVER_SEND_NOTIFICATIONS: gNotificationManager->EnqueueMessage(msg); break;
|
||||
|
||||
|
||||
case MEDIA_SERVER_GET_NODE_ID: GetNodeID(msg); break;
|
||||
case MEDIA_SERVER_FIND_RUNNING_INSTANCES: FindRunningInstances(msg); break;
|
||||
case MEDIA_SERVER_BUFFER_GROUP_REG: BufferGroupReg(msg); break;
|
||||
case MEDIA_SERVER_GET_LATENT_INFO: GetLatentInfo(msg); break;
|
||||
case MEDIA_SERVER_GET_DORMANT_FILE_FORMATS: GetDormantFileFormats(msg); break;
|
||||
case MEDIA_SERVER_GET_GETDORMANTFLAVOR: GetDormantFlavor(msg); break;
|
||||
case MEDIA_SERVER_BROADCAST_MESSAGE: BroadcastMessage(msg); break;
|
||||
case MEDIA_SERVER_RELEASE_NODE_REFERENCE: ReleaseNodeReference(msg); break;
|
||||
case MEDIA_SERVER_SET_REALTIME_FLAGS: SetRealtimeFlags(msg); break;
|
||||
case MEDIA_SERVER_GET_REALTIME_FLAGS: GetRealtimeFlags(msg); break;
|
||||
case MEDIA_SERVER_INSTANTIATE_PERSISTENT_NODE: InstantiatePersistentNode(msg); break;
|
||||
case MEDIA_SERVER_SNIFF_FILE: SniffFile(msg); break;
|
||||
case MEDIA_SERVER_QUERY_LATENTS: QueryLatents(msg); break;
|
||||
case MEDIA_SERVER_REGISTER_APP: RegisterApp(msg); break;
|
||||
case MEDIA_SERVER_UNREGISTER_APP: UnregisterApp(msg); break;
|
||||
case MEDIA_SERVER_REGISTER_NODE: RegisterNode(msg); break;
|
||||
case MEDIA_SERVER_UNREGISTER_NODE: UnregisterNode(msg); break;
|
||||
case MEDIA_SERVER_SET_DEFAULT: SetDefault(msg); break;
|
||||
case MEDIA_SERVER_ACQUIRE_NODE_REFERENCE: AcquireNodeReference(msg); break;
|
||||
case MEDIA_SERVER_SET_OUTPUT_BUFFERS: SetOutputBuffers(msg); break;
|
||||
case MEDIA_SERVER_RECLAIM_OUTPUT_BUFFERS: ReclaimOutputBuffers(msg); break;
|
||||
case MEDIA_SERVER_ORPHAN_RECLAIMABLE_BUFFERS: OrphanReclaimableBuffers(msg); break;
|
||||
case MEDIA_SERVER_SET_TIME_SOURCE: SetTimeSource(msg); break;
|
||||
case MEDIA_SERVER_QUERY_NODES: QueryNodes(msg); break;
|
||||
case MEDIA_SERVER_GET_DORMANT_NODE: GetDormantNode(msg); break;
|
||||
case MEDIA_SERVER_FORMAT_CHANGED: FormatChanged(msg); break;
|
||||
case MEDIA_SERVER_GET_DEFAULT_INFO: GetDefaultInfo(msg); break;
|
||||
case MEDIA_SERVER_GET_RUNNING_DEFAULT: GetRunningDefault(msg); break;
|
||||
case MEDIA_SERVER_SET_RUNNING_DEFAULT: SetRunningDefault(msg); break;
|
||||
case MEDIA_SERVER_TYPE_ITEM_OP: TypeItemOp(msg); break;
|
||||
case MEDIA_SERVER_FORMAT_OP: FormatOp(msg); break;
|
||||
case MEDIA_SERVER_SET_VOLUME: SetVolume(msg); break;
|
||||
case MEDIA_SERVER_GET_VOLUME: GetVolume(msg); break;
|
||||
default:
|
||||
printf("\nnew media server: unknown message received\n");
|
||||
msg->PrintToStream();
|
||||
|
@ -23,6 +23,10 @@
|
||||
|
||||
void DumpFlavorInfo(const flavor_info *info);
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
extern team_id team;
|
||||
} } // BPrivate::media
|
||||
|
||||
class MediaAddonServer : BApplication
|
||||
{
|
||||
public:
|
||||
@ -34,7 +38,7 @@ public:
|
||||
void WatchDir(BEntry *dir);
|
||||
void AddOnAdded(const char *path, ino_t file_node);
|
||||
void AddOnRemoved(ino_t file_node);
|
||||
void HandleMessage(int32 code, void *data, size_t size);
|
||||
void HandleMessage(int32 code, const void *data, size_t size);
|
||||
static int32 controlthread(void *arg);
|
||||
|
||||
void ScanAddOnFlavors(BMediaAddOn *addon);
|
||||
@ -76,30 +80,30 @@ MediaAddonServer::~MediaAddonServer()
|
||||
}
|
||||
|
||||
void
|
||||
MediaAddonServer::HandleMessage(int32 code, void *data, size_t size)
|
||||
MediaAddonServer::HandleMessage(int32 code, const void *data, size_t size)
|
||||
{
|
||||
switch (code) {
|
||||
case ADDONSERVER_INSTANTIATE_DORMANT_NODE:
|
||||
{
|
||||
const addonserver_instantiate_dormant_node_request *msg = (const addonserver_instantiate_dormant_node_request *)data;
|
||||
const addonserver_instantiate_dormant_node_request *request = static_cast<const addonserver_instantiate_dormant_node_request *>(data);
|
||||
addonserver_instantiate_dormant_node_reply reply;
|
||||
status_t rv;
|
||||
rv = mediaroster->InstantiateDormantNode(msg->info, &reply.node);
|
||||
msg->SendReply(rv, &reply, sizeof(reply));
|
||||
rv = mediaroster->InstantiateDormantNode(request->info, &reply.node);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case ADDONSERVER_RESCAN_MEDIAADDON_FLAVORS:
|
||||
{
|
||||
const addonserver_rescan_mediaaddon_flavors_command *msg = (const addonserver_rescan_mediaaddon_flavors_command *)data;
|
||||
const addonserver_rescan_mediaaddon_flavors_command *command = static_cast<const addonserver_rescan_mediaaddon_flavors_command *>(data);
|
||||
BMediaAddOn *addon;
|
||||
addon = _DormantNodeManager->GetAddon(msg->addonid);
|
||||
addon = _DormantNodeManager->GetAddon(command->addonid);
|
||||
if (!addon) {
|
||||
printf("rescan flavors: Can't find a addon object for id %d\n",(int)msg->addonid);
|
||||
printf("rescan flavors: Can't find a addon object for id %d\n",(int)command->addonid);
|
||||
break;
|
||||
}
|
||||
ScanAddOnFlavors(addon);
|
||||
_DormantNodeManager->PutAddon(msg->addonid);
|
||||
_DormantNodeManager->PutAddon(command->addonid);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -126,8 +130,20 @@ MediaAddonServer::controlthread(void *arg)
|
||||
void
|
||||
MediaAddonServer::ReadyToRun()
|
||||
{
|
||||
node_ref nref;
|
||||
// register with media_server
|
||||
server_register_addonserver_request request;
|
||||
server_register_addonserver_reply reply;
|
||||
status_t result;
|
||||
request.team = BPrivate::media::team;
|
||||
result = QueryServer(SERVER_REGISTER_ADDONSERVER, &request, sizeof(request), &reply, sizeof(reply));
|
||||
if (result != B_OK) {
|
||||
printf("Communication with server failed. Terminating.\n");
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
return;
|
||||
}
|
||||
|
||||
// load dormant media nodes
|
||||
node_ref nref;
|
||||
BEntry e("/boot/beos/system/add-ons/media");
|
||||
e.GetNodeRef(&nref);
|
||||
DirNodeSystem = nref.node;
|
||||
|
Loading…
x
Reference in New Issue
Block a user