Modified media_server and media_addon_server cration/terminatio.
Now uses application mime sig for start/stopping. Much better compatibility with libbe.so restarting functions. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8586 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -31,10 +31,17 @@ NotFile MediaKit ;
|
||||
Depends MediaKit :
|
||||
libmedia.so
|
||||
|
||||
desklink
|
||||
# Servers
|
||||
media_addon_server
|
||||
media_server
|
||||
|
||||
# Preference
|
||||
Sounds
|
||||
Media
|
||||
|
||||
# Deskbar replicant
|
||||
desklink
|
||||
|
||||
# add-ons
|
||||
mixer.media_addon
|
||||
tone_producer_demo.media_addon
|
||||
|
||||
@@ -79,7 +79,6 @@ enum {
|
||||
ADDONSERVER_RESCAN_MEDIAADDON_FLAVORS = 0x50,
|
||||
|
||||
SERVER_MESSAGE_START = 0x100,
|
||||
SERVER_REGISTER_ADDONSERVER,
|
||||
SERVER_REGISTER_APP,
|
||||
SERVER_UNREGISTER_APP,
|
||||
SERVER_GET_NODE,
|
||||
@@ -603,15 +602,6 @@ struct consumer_seek_tag_requested_reply : public reply_data
|
||||
uint32 flags;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
@@ -30,12 +30,11 @@
|
||||
#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 "MediaMisc.h"
|
||||
#include "AppManager.h"
|
||||
#include "NodeManager.h"
|
||||
#include "BufferManager.h"
|
||||
@@ -43,7 +42,6 @@
|
||||
#include "media_server.h"
|
||||
|
||||
AppManager::AppManager()
|
||||
: fAddonServer(-1)
|
||||
{
|
||||
fAppMap = new Map<team_id, App>;
|
||||
fLocker = new BLocker("app manager locker");
|
||||
@@ -52,6 +50,7 @@ AppManager::AppManager()
|
||||
resume_thread(fBigBrother);
|
||||
}
|
||||
|
||||
|
||||
AppManager::~AppManager()
|
||||
{
|
||||
status_t err;
|
||||
@@ -61,13 +60,17 @@ AppManager::~AppManager()
|
||||
delete fAppMap;
|
||||
}
|
||||
|
||||
bool AppManager::HasTeam(team_id team)
|
||||
|
||||
bool
|
||||
AppManager::HasTeam(team_id team)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
return fAppMap->Has(team);
|
||||
}
|
||||
|
||||
status_t AppManager::RegisterTeam(team_id team, BMessenger messenger)
|
||||
|
||||
status_t
|
||||
AppManager::RegisterTeam(team_id team, BMessenger messenger)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
TRACE("AppManager::RegisterTeam %ld\n", team);
|
||||
@@ -81,27 +84,24 @@ status_t AppManager::RegisterTeam(team_id team, BMessenger messenger)
|
||||
return fAppMap->Insert(team, app) ? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
status_t AppManager::UnregisterTeam(team_id team)
|
||||
|
||||
status_t
|
||||
AppManager::UnregisterTeam(team_id team)
|
||||
{
|
||||
bool is_removed;
|
||||
bool is_addon_server;
|
||||
|
||||
TRACE("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;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AppManager::SendMessage(team_id team, BMessage *msg)
|
||||
{
|
||||
@@ -112,28 +112,9 @@ AppManager::SendMessage(team_id team, BMessage *msg)
|
||||
return app->messenger.SendMessage(msg);
|
||||
}
|
||||
|
||||
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) {
|
||||
PRINT(1, "AppManager: Restarting media_addon_server...\n");
|
||||
// XXX fixme. We should wait until it is *really* gone
|
||||
snooze(5000000);
|
||||
StartAddonServer();
|
||||
} else {
|
||||
PRINT(1, "AppManager: media_addon_server crashed too often, not restarted\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AppManager::TeamDied(team_id team)
|
||||
void
|
||||
AppManager::TeamDied(team_id team)
|
||||
{
|
||||
CleanupTeam(team);
|
||||
fLocker->Lock();
|
||||
@@ -141,32 +122,36 @@ void AppManager::TeamDied(team_id team)
|
||||
fLocker->Unlock();
|
||||
}
|
||||
|
||||
status_t AppManager::RegisterAddonServer(team_id team)
|
||||
|
||||
team_id
|
||||
AppManager::AddonServerTeam()
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
if (fAddonServer != -1)
|
||||
return B_ERROR;
|
||||
fAddonServer = team;
|
||||
return B_OK;
|
||||
team_id id = be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE);
|
||||
if (id < 0) {
|
||||
ERROR("media_server: Trouble, media_addon_server is dead!\n");
|
||||
return -1;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// 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()
|
||||
// the team cleanup function TeamDied() will be called.
|
||||
//=========================================================================
|
||||
|
||||
int32 AppManager::bigbrother(void *self)
|
||||
int32
|
||||
AppManager::bigbrother(void *self)
|
||||
{
|
||||
static_cast<AppManager *>(self)->BigBrother();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AppManager::BigBrother()
|
||||
|
||||
void
|
||||
AppManager::BigBrother()
|
||||
{
|
||||
bool restart_addon_server;
|
||||
status_t status;
|
||||
BMessage msg('PING');
|
||||
BMessage reply;
|
||||
@@ -180,18 +165,8 @@ void AppManager::BigBrother()
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -205,7 +180,8 @@ void AppManager::BigBrother()
|
||||
// They clean up after a crash, or start/terminate the media_addon_server.
|
||||
//=========================================================================
|
||||
|
||||
void AppManager::CleanupTeam(team_id team)
|
||||
void
|
||||
AppManager::CleanupTeam(team_id team)
|
||||
{
|
||||
ASSERT(false == fLocker->IsLocked());
|
||||
|
||||
@@ -216,49 +192,9 @@ void AppManager::CleanupTeam(team_id team)
|
||||
gNotificationManager->CleanupTeam(team);
|
||||
}
|
||||
|
||||
void AppManager::CleanupAddonServer()
|
||||
{
|
||||
ASSERT(false == fLocker->IsLocked());
|
||||
|
||||
TRACE("AppManager: cleaning up media_addon_server\n");
|
||||
gNodeManager->CleanupDormantFlavorInfos();
|
||||
}
|
||||
|
||||
void AppManager::StartAddonServer()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
void AppManager::TerminateAddonServer()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
team_id
|
||||
AppManager::AddonServer()
|
||||
{
|
||||
// XXX not sure about locking
|
||||
return fAddonServer;
|
||||
}
|
||||
|
||||
void AppManager::Dump()
|
||||
void
|
||||
AppManager::Dump()
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
printf("\n");
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* Copyright 2002, Marcus Overhagen. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef __APP_MANAGER_H
|
||||
#define __APP_MANAGER_H
|
||||
|
||||
#include "TMap.h"
|
||||
|
||||
@@ -11,13 +13,11 @@ public:
|
||||
AppManager();
|
||||
~AppManager();
|
||||
|
||||
status_t RegisterAddonServer(team_id);
|
||||
status_t RegisterTeam(team_id, BMessenger);
|
||||
status_t UnregisterTeam(team_id);
|
||||
bool HasTeam(team_id);
|
||||
void StartAddonServer();
|
||||
void TerminateAddonServer();
|
||||
team_id AddonServer();
|
||||
|
||||
team_id AddonServerTeam();
|
||||
|
||||
status_t SendMessage(team_id team, BMessage *msg);
|
||||
|
||||
@@ -25,14 +25,11 @@ public:
|
||||
|
||||
private:
|
||||
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;
|
||||
|
||||
@@ -43,3 +40,5 @@ private:
|
||||
Map<team_id, App> * fAppMap;
|
||||
BLocker *fLocker;
|
||||
};
|
||||
|
||||
#endif // __APP_MANAGER_H
|
||||
|
||||
@@ -174,7 +174,7 @@ NodeManager::DecrementGlobalRefCount(media_node_id nodeid, team_id team)
|
||||
// exception. If the node is global, and the creator team tries to release it,
|
||||
// we will release it in the the media_addon_server.
|
||||
team_id addon_server_team;
|
||||
addon_server_team = gAppManager->AddonServer();
|
||||
addon_server_team = gAppManager->AddonServerTeam();
|
||||
if (rn->creator == team && rn->teamrefcount.Get(addon_server_team, &count)) {
|
||||
printf("!!! NodeManager::DecrementGlobalRefCount doing global release!\n");
|
||||
rn->creator = -1; //invalidate!
|
||||
|
||||
@@ -31,12 +31,15 @@
|
||||
char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 Marcus Overhagen <[email protected]>";
|
||||
|
||||
#include <Application.h>
|
||||
#include <stdio.h>
|
||||
#include <Roster.h>
|
||||
#include <Messenger.h>
|
||||
#include <MediaDefs.h>
|
||||
#include <MediaFormats.h>
|
||||
#include <Autolock.h>
|
||||
#include <Alert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "MMediaFilesManager.h"
|
||||
#include "NotificationManager.h"
|
||||
#include "ServerInterface.h"
|
||||
@@ -78,11 +81,13 @@ public:
|
||||
ServerApp();
|
||||
~ServerApp();
|
||||
|
||||
private:
|
||||
bool QuitRequested();
|
||||
void HandleMessage(int32 code, void *data, size_t size);
|
||||
void ArgvReceived(int32 argc, char **argv);
|
||||
static int32 controlthread(void *arg);
|
||||
// void StartSystemTimeSource();
|
||||
|
||||
void StartAddonServer();
|
||||
void TerminateAddonServer();
|
||||
|
||||
/* functionality not yet implemented
|
||||
00014a00 T _ServerApp::_ServerApp(void)
|
||||
@@ -105,6 +110,8 @@ public:
|
||||
0001adcc T _ServerApp::ReadyToRun(void)
|
||||
*/
|
||||
|
||||
static int32 controlthread(void *arg);
|
||||
|
||||
private:
|
||||
port_id control_port;
|
||||
thread_id control_thread;
|
||||
@@ -131,17 +138,18 @@ ServerApp::ServerApp()
|
||||
control_port = create_port(64, MEDIA_SERVER_PORT_NAME);
|
||||
control_thread = spawn_thread(controlthread, "media_server control", 105, this);
|
||||
resume_thread(control_thread);
|
||||
|
||||
// StartSystemTimeSource();
|
||||
gNodeManager->LoadState();
|
||||
gFormatManager->LoadState();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ServerApp::ReadyToRun()
|
||||
{
|
||||
gAppManager->StartAddonServer();
|
||||
gNodeManager->LoadState();
|
||||
gFormatManager->LoadState();
|
||||
|
||||
// make sure any previous media_addon_server is gone
|
||||
TerminateAddonServer();
|
||||
// and start a new one
|
||||
StartAddonServer();
|
||||
|
||||
gAddOnManager->LoadState();
|
||||
}
|
||||
|
||||
@@ -161,6 +169,20 @@ ServerApp::~ServerApp()
|
||||
wait_for_thread(control_thread,&err);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ServerApp::QuitRequested()
|
||||
{
|
||||
TRACE("ServerApp::QuitRequested()\n");
|
||||
gMMediaFilesManager->SaveState();
|
||||
gNodeManager->SaveState();
|
||||
gFormatManager->SaveState();
|
||||
gAddOnManager->SaveState();
|
||||
TerminateAddonServer();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::ArgvReceived(int32 argc, char **argv)
|
||||
{
|
||||
for (int arg = 1; arg < argc; arg++) {
|
||||
@@ -183,43 +205,81 @@ void ServerApp::ArgvReceived(int32 argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ServerApp::QuitRequested()
|
||||
{
|
||||
TRACE("ServerApp::QuitRequested()\n");
|
||||
gMMediaFilesManager->SaveState();
|
||||
gNodeManager->SaveState();
|
||||
gFormatManager->SaveState();
|
||||
gAddOnManager->SaveState();
|
||||
gAppManager->TerminateAddonServer();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ServerApp::StartAddonServer()
|
||||
{
|
||||
status_t err;
|
||||
|
||||
// launching media_addon_server from this application's directoy
|
||||
// should no longer be needed, we now can launch by mime signature
|
||||
/*
|
||||
void
|
||||
ServerApp::StartSystemTimeSource()
|
||||
{
|
||||
TRACE("StartSystemTimeSource enter\n");
|
||||
status_t rv;
|
||||
app_info info;
|
||||
BEntry entry;
|
||||
BDirectory dir;
|
||||
entry_ref ref;
|
||||
|
||||
TRACE("StartSystemTimeSource creating object\n");
|
||||
err = GetAppInfo(&info);
|
||||
err |= entry.SetTo(&info.ref);
|
||||
err |= entry.GetParent(&entry);
|
||||
err |= dir.SetTo(&entry);
|
||||
err |= entry.SetTo(&dir, "media_addon_server");
|
||||
err |= entry.GetRef(&ref);
|
||||
|
||||
// register a dummy node
|
||||
media_node node;
|
||||
rv = gNodeManager->RegisterNode(&node.node, -1, 0, "System Clock", B_TIME_SOURCE, SYSTEM_TIMESOURCE_CONTROL_PORT, BPrivate::media::team);
|
||||
ASSERT(rv == B_OK);
|
||||
|
||||
ASSERT(node.node == NODE_SYSTEM_TIMESOURCE_ID);
|
||||
|
||||
TRACE("StartSystemTimeSource setting as default\n");
|
||||
|
||||
rv = gNodeManager->SetDefaultNode(SYSTEM_TIME_SOURCE, &node, NULL, NULL);
|
||||
ASSERT(rv == B_OK);
|
||||
|
||||
TRACE("StartSystemTimeSource leave\n");
|
||||
}
|
||||
if (err == B_OK)
|
||||
be_roster->Launch(&ref);
|
||||
if (err == B_OK)
|
||||
return;
|
||||
*/
|
||||
|
||||
err = be_roster->Launch(B_MEDIA_ADDON_SERVER_SIGNATURE);
|
||||
if (err == B_OK)
|
||||
return;
|
||||
|
||||
(new BAlert("media_server", "Launing media_addon_server failed.\n\nmedia_server will terminate", "OK"))->Go();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void ServerApp::TerminateAddonServer()
|
||||
{
|
||||
// nothing to do if it's already terminated
|
||||
if (!be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE))
|
||||
return;
|
||||
|
||||
// send a quit request to the media_addon_server
|
||||
BMessenger msger(B_MEDIA_ADDON_SERVER_SIGNATURE);
|
||||
if (!msger.IsValid()) {
|
||||
ERROR("Trouble terminating media_addon_server. Messenger invalid\n");
|
||||
} else {
|
||||
BMessage msg(B_QUIT_REQUESTED);
|
||||
status_t err = msger.SendMessage(&msg, (BHandler *)NULL, 2000000 /* 2 sec timeout */);
|
||||
if (err) {
|
||||
ERROR("Trouble terminating media_addon_server (2). Error %d (%s)\n", err, strerror(err));
|
||||
}
|
||||
}
|
||||
|
||||
// wait 5 seconds for it to terminate
|
||||
for (int i = 0; i < 50; i++) {
|
||||
if (!be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE))
|
||||
return;
|
||||
snooze(100000); // 100 ms
|
||||
}
|
||||
|
||||
// try to kill it (or many of them), up to 10 seconds
|
||||
for (int i = 0; i < 50; i++) {
|
||||
team_id id = be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE);
|
||||
if (id < 0)
|
||||
break;
|
||||
kill_team(id);
|
||||
snooze(200000); // 200 ms
|
||||
}
|
||||
|
||||
if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) {
|
||||
ERROR("Trouble terminating media_addon_server, it's still running\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
{
|
||||
@@ -245,15 +305,6 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -753,8 +804,8 @@ ServerApp::MessageReceived(BMessage *msg)
|
||||
|
||||
default:
|
||||
inherited::MessageReceived(msg);
|
||||
//printf("\nnew media server: unknown message received\n");
|
||||
//msg->PrintToStream();
|
||||
printf("\nmedia_server: unknown message received:\n");
|
||||
msg->PrintToStream();
|
||||
break;
|
||||
}
|
||||
TRACE("ServerApp::MessageReceived %lx leave\n", msg->what);
|
||||
|
||||
@@ -184,24 +184,12 @@ MediaAddonServer::ReadyToRun()
|
||||
// so we can talk to the media server and also receive
|
||||
// commands for instantiation
|
||||
|
||||
// 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) {
|
||||
ERROR("Communication with server failed. Terminating.\n");
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(fStartup == true);
|
||||
|
||||
// The very first thing to do is to create the system time source,
|
||||
// register it with the server, and make it the default SYSTEM_TIME_SOURCE
|
||||
BMediaNode *ts = new SystemTimeSource;
|
||||
result = mediaroster->RegisterNode(ts);
|
||||
status_t result = mediaroster->RegisterNode(ts);
|
||||
if (result != B_OK)
|
||||
debugger("Can't register system time source");
|
||||
if (ts->ID() != NODE_SYSTEM_TIMESOURCE_ID)
|
||||
|
||||
Reference in New Issue
Block a user