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:
beveloper 2002-11-20 01:28:23 +00:00
parent 4ff6d49f35
commit 6396865dcd
9 changed files with 332 additions and 450 deletions

View File

@ -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
{
};

View File

@ -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));
}
/*************************************************************

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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