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:
beveloper
2004-08-15 20:43:01 +00:00
parent da69157621
commit 28a06094b2
7 changed files with 167 additions and 196 deletions
+8 -1
View File
@@ -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
-10
View File
@@ -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;
+34 -98
View File
@@ -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");
+6 -7
View File
@@ -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
+1 -1
View File
@@ -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!
+103 -52
View File
@@ -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);
+1 -13
View File
@@ -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)