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 : Depends MediaKit :
libmedia.so libmedia.so
desklink # Servers
media_addon_server media_addon_server
media_server media_server
# Preference
Sounds
Media
# Deskbar replicant
desklink
# add-ons # add-ons
mixer.media_addon mixer.media_addon
tone_producer_demo.media_addon tone_producer_demo.media_addon
-10
View File
@@ -79,7 +79,6 @@ enum {
ADDONSERVER_RESCAN_MEDIAADDON_FLAVORS = 0x50, ADDONSERVER_RESCAN_MEDIAADDON_FLAVORS = 0x50,
SERVER_MESSAGE_START = 0x100, SERVER_MESSAGE_START = 0x100,
SERVER_REGISTER_ADDONSERVER,
SERVER_REGISTER_APP, SERVER_REGISTER_APP,
SERVER_UNREGISTER_APP, SERVER_UNREGISTER_APP,
SERVER_GET_NODE, SERVER_GET_NODE,
@@ -603,15 +602,6 @@ struct consumer_seek_tag_requested_reply : public reply_data
uint32 flags; 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 struct server_register_app_request : public request_data
{ {
team_id team; team_id team;
+34 -98
View File
@@ -30,12 +30,11 @@
#include <OS.h> #include <OS.h>
#include <Application.h> #include <Application.h>
#include <Roster.h> #include <Roster.h>
#include <Directory.h>
#include <Entry.h>
#include <Messenger.h> #include <Messenger.h>
#include <Autolock.h> #include <Autolock.h>
#include <stdio.h> #include <stdio.h>
#include "debug.h" #include "debug.h"
#include "MediaMisc.h"
#include "AppManager.h" #include "AppManager.h"
#include "NodeManager.h" #include "NodeManager.h"
#include "BufferManager.h" #include "BufferManager.h"
@@ -43,7 +42,6 @@
#include "media_server.h" #include "media_server.h"
AppManager::AppManager() AppManager::AppManager()
: fAddonServer(-1)
{ {
fAppMap = new Map<team_id, App>; fAppMap = new Map<team_id, App>;
fLocker = new BLocker("app manager locker"); fLocker = new BLocker("app manager locker");
@@ -52,6 +50,7 @@ AppManager::AppManager()
resume_thread(fBigBrother); resume_thread(fBigBrother);
} }
AppManager::~AppManager() AppManager::~AppManager()
{ {
status_t err; status_t err;
@@ -61,13 +60,17 @@ AppManager::~AppManager()
delete fAppMap; delete fAppMap;
} }
bool AppManager::HasTeam(team_id team)
bool
AppManager::HasTeam(team_id team)
{ {
BAutolock lock(fLocker); BAutolock lock(fLocker);
return fAppMap->Has(team); 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); BAutolock lock(fLocker);
TRACE("AppManager::RegisterTeam %ld\n", team); 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; 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_removed;
bool is_addon_server;
TRACE("AppManager::UnregisterTeam %ld\n", team); TRACE("AppManager::UnregisterTeam %ld\n", team);
fLocker->Lock(); fLocker->Lock();
is_removed = fAppMap->Remove(team); is_removed = fAppMap->Remove(team);
is_addon_server = fAddonServer == team;
if (is_addon_server)
fAddonServer = -1;
fLocker->Unlock(); fLocker->Unlock();
CleanupTeam(team); CleanupTeam(team);
if (is_addon_server)
CleanupAddonServer();
return is_removed ? B_OK : B_ERROR; return is_removed ? B_OK : B_ERROR;
} }
status_t status_t
AppManager::SendMessage(team_id team, BMessage *msg) AppManager::SendMessage(team_id team, BMessage *msg)
{ {
@@ -112,28 +112,9 @@ AppManager::SendMessage(team_id team, BMessage *msg)
return app->messenger.SendMessage(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
void AppManager::TeamDied(team_id team) AppManager::TeamDied(team_id team)
{ {
CleanupTeam(team); CleanupTeam(team);
fLocker->Lock(); fLocker->Lock();
@@ -141,32 +122,36 @@ void AppManager::TeamDied(team_id team)
fLocker->Unlock(); fLocker->Unlock();
} }
status_t AppManager::RegisterAddonServer(team_id team)
team_id
AppManager::AddonServerTeam()
{ {
BAutolock lock(fLocker); team_id id = be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE);
if (fAddonServer != -1) if (id < 0) {
return B_ERROR; ERROR("media_server: Trouble, media_addon_server is dead!\n");
fAddonServer = team; return -1;
return B_OK; }
return id;
} }
//========================================================================= //=========================================================================
// The BigBrother thread send ping messages to the BMediaRoster of // The BigBrother thread send ping messages to the BMediaRoster of
// all currently running teams. If the reply times out or is wrong, // all currently running teams. If the reply times out or is wrong,
// the team cleanup function TeamDied() will be called. If the dead // the team cleanup function TeamDied() will be called.
// team is the media_addon_server, additionally CleanupAddonServer()
// will be called and also RestartAddonServer()
//========================================================================= //=========================================================================
int32 AppManager::bigbrother(void *self) int32
AppManager::bigbrother(void *self)
{ {
static_cast<AppManager *>(self)->BigBrother(); static_cast<AppManager *>(self)->BigBrother();
return 0; return 0;
} }
void AppManager::BigBrother()
void
AppManager::BigBrother()
{ {
bool restart_addon_server;
status_t status; status_t status;
BMessage msg('PING'); BMessage msg('PING');
BMessage reply; BMessage reply;
@@ -180,18 +165,8 @@ void AppManager::BigBrother()
status = app->messenger.SendMessage(&msg, &reply, 5000000, 2000000); status = app->messenger.SendMessage(&msg, &reply, 5000000, 2000000);
if (status != B_OK || reply.what != 'PONG') { if (status != B_OK || reply.what != 'PONG') {
team = app->team; team = app->team;
if (fAddonServer == team) {
restart_addon_server = true;
fAddonServer = -1;
} else {
restart_addon_server = false;
}
fLocker->Unlock(); fLocker->Unlock();
TeamDied(team); TeamDied(team);
if (restart_addon_server) {
CleanupAddonServer();
RestartAddonServer();
}
continue; continue;
} }
} }
@@ -205,7 +180,8 @@ void AppManager::BigBrother()
// They clean up after a crash, or start/terminate the media_addon_server. // 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()); ASSERT(false == fLocker->IsLocked());
@@ -216,49 +192,9 @@ void AppManager::CleanupTeam(team_id team)
gNotificationManager->CleanupTeam(team); gNotificationManager->CleanupTeam(team);
} }
void AppManager::CleanupAddonServer()
{
ASSERT(false == fLocker->IsLocked());
TRACE("AppManager: cleaning up media_addon_server\n"); void
gNodeManager->CleanupDormantFlavorInfos(); AppManager::Dump()
}
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()
{ {
BAutolock lock(fLocker); BAutolock lock(fLocker);
printf("\n"); printf("\n");
+17 -18
View File
@@ -2,37 +2,34 @@
* Copyright 2002, Marcus Overhagen. All rights reserved. * Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef __APP_MANAGER_H
#define __APP_MANAGER_H
#include "TMap.h" #include "TMap.h"
class AppManager class AppManager
{ {
public: public:
AppManager(); AppManager();
~AppManager(); ~AppManager();
status_t RegisterAddonServer(team_id); status_t RegisterTeam(team_id, BMessenger);
status_t RegisterTeam(team_id, BMessenger); status_t UnregisterTeam(team_id);
status_t UnregisterTeam(team_id); bool HasTeam(team_id);
bool HasTeam(team_id);
void StartAddonServer(); team_id AddonServerTeam();
void TerminateAddonServer();
team_id AddonServer(); status_t SendMessage(team_id team, BMessage *msg);
status_t SendMessage(team_id team, BMessage *msg); void Dump();
void Dump();
private: private:
void CleanupTeam(team_id); void CleanupTeam(team_id);
void CleanupAddonServer(); void TeamDied(team_id team);
void TeamDied(team_id team);
void RestartAddonServer();
static int32 bigbrother(void *self); static int32 bigbrother(void *self);
void BigBrother(); void BigBrother();
private: private:
team_id fAddonServer;
thread_id fBigBrother; thread_id fBigBrother;
sem_id fQuit; sem_id fQuit;
@@ -43,3 +40,5 @@ private:
Map<team_id, App> * fAppMap; Map<team_id, App> * fAppMap;
BLocker *fLocker; 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, // exception. If the node is global, and the creator team tries to release it,
// we will release it in the the media_addon_server. // we will release it in the the media_addon_server.
team_id addon_server_team; 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)) { if (rn->creator == team && rn->teamrefcount.Get(addon_server_team, &count)) {
printf("!!! NodeManager::DecrementGlobalRefCount doing global release!\n"); printf("!!! NodeManager::DecrementGlobalRefCount doing global release!\n");
rn->creator = -1; //invalidate! rn->creator = -1; //invalidate!
+106 -55
View File
@@ -31,12 +31,15 @@
char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 Marcus Overhagen <[email protected]>"; char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 Marcus Overhagen <[email protected]>";
#include <Application.h> #include <Application.h>
#include <stdio.h> #include <Roster.h>
#include <Messenger.h> #include <Messenger.h>
#include <MediaDefs.h> #include <MediaDefs.h>
#include <MediaFormats.h> #include <MediaFormats.h>
#include <Autolock.h> #include <Autolock.h>
#include <Alert.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include "MMediaFilesManager.h" #include "MMediaFilesManager.h"
#include "NotificationManager.h" #include "NotificationManager.h"
#include "ServerInterface.h" #include "ServerInterface.h"
@@ -78,11 +81,13 @@ public:
ServerApp(); ServerApp();
~ServerApp(); ~ServerApp();
bool QuitRequested(); private:
void HandleMessage(int32 code, void *data, size_t size); bool QuitRequested();
void ArgvReceived(int32 argc, char **argv); void HandleMessage(int32 code, void *data, size_t size);
static int32 controlthread(void *arg); void ArgvReceived(int32 argc, char **argv);
// void StartSystemTimeSource();
void StartAddonServer();
void TerminateAddonServer();
/* functionality not yet implemented /* functionality not yet implemented
00014a00 T _ServerApp::_ServerApp(void) 00014a00 T _ServerApp::_ServerApp(void)
@@ -105,6 +110,8 @@ public:
0001adcc T _ServerApp::ReadyToRun(void) 0001adcc T _ServerApp::ReadyToRun(void)
*/ */
static int32 controlthread(void *arg);
private: private:
port_id control_port; port_id control_port;
thread_id control_thread; thread_id control_thread;
@@ -131,17 +138,18 @@ ServerApp::ServerApp()
control_port = create_port(64, MEDIA_SERVER_PORT_NAME); control_port = create_port(64, MEDIA_SERVER_PORT_NAME);
control_thread = spawn_thread(controlthread, "media_server control", 105, this); control_thread = spawn_thread(controlthread, "media_server control", 105, this);
resume_thread(control_thread); resume_thread(control_thread);
// StartSystemTimeSource();
gNodeManager->LoadState();
gFormatManager->LoadState();
} }
void ServerApp::ReadyToRun() 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(); gAddOnManager->LoadState();
} }
@@ -161,6 +169,20 @@ ServerApp::~ServerApp()
wait_for_thread(control_thread,&err); 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) void ServerApp::ArgvReceived(int32 argc, char **argv)
{ {
for (int arg = 1; arg < argc; arg++) { 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 app_info info;
ServerApp::StartSystemTimeSource() BEntry entry;
{ BDirectory dir;
TRACE("StartSystemTimeSource enter\n"); entry_ref ref;
status_t rv;
TRACE("StartSystemTimeSource creating object\n");
// 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); err = GetAppInfo(&info);
err |= entry.SetTo(&info.ref);
TRACE("StartSystemTimeSource setting as default\n"); err |= entry.GetParent(&entry);
err |= dir.SetTo(&entry);
err |= entry.SetTo(&dir, "media_addon_server");
err |= entry.GetRef(&ref);
rv = gNodeManager->SetDefaultNode(SYSTEM_TIME_SOURCE, &node, NULL, NULL); if (err == B_OK)
ASSERT(rv == B_OK); be_roster->Launch(&ref);
if (err == B_OK)
TRACE("StartSystemTimeSource leave\n"); 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 void
ServerApp::HandleMessage(int32 code, void *data, size_t size) ServerApp::HandleMessage(int32 code, void *data, size_t size)
{ {
@@ -245,15 +305,6 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
break; 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: case SERVER_REGISTER_APP:
{ {
const server_register_app_request *request = reinterpret_cast<const server_register_app_request *>(data); const server_register_app_request *request = reinterpret_cast<const server_register_app_request *>(data);
@@ -753,8 +804,8 @@ ServerApp::MessageReceived(BMessage *msg)
default: default:
inherited::MessageReceived(msg); inherited::MessageReceived(msg);
//printf("\nnew media server: unknown message received\n"); printf("\nmedia_server: unknown message received:\n");
//msg->PrintToStream(); msg->PrintToStream();
break; break;
} }
TRACE("ServerApp::MessageReceived %lx leave\n", msg->what); 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 // so we can talk to the media server and also receive
// commands for instantiation // 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); ASSERT(fStartup == true);
// The very first thing to do is to create the system time source, // 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 // register it with the server, and make it the default SYSTEM_TIME_SOURCE
BMediaNode *ts = new SystemTimeSource; BMediaNode *ts = new SystemTimeSource;
result = mediaroster->RegisterNode(ts); status_t result = mediaroster->RegisterNode(ts);
if (result != B_OK) if (result != B_OK)
debugger("Can't register system time source"); debugger("Can't register system time source");
if (ts->ID() != NODE_SYSTEM_TIMESOURCE_ID) if (ts->ID() != NODE_SYSTEM_TIMESOURCE_ID)