From 28a06094b2a1b2239861d222260e501413990cde Mon Sep 17 00:00:00 2001 From: beveloper Date: Sun, 15 Aug 2004 20:43:01 +0000 Subject: [PATCH] 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 --- Jamfile | 9 +- headers/private/media/DataExchange.h | 10 -- src/servers/media/AppManager.cpp | 132 ++++++---------------- src/servers/media/AppManager.h | 35 +++--- src/servers/media/NodeManager.cpp | 2 +- src/servers/media/media_server.cpp | 161 ++++++++++++++++++--------- src/servers/media_addon/main.cpp | 14 +-- 7 files changed, 167 insertions(+), 196 deletions(-) diff --git a/Jamfile b/Jamfile index 90f0bb8980..b568ed2868 100644 --- a/Jamfile +++ b/Jamfile @@ -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 diff --git a/headers/private/media/DataExchange.h b/headers/private/media/DataExchange.h index 550313da9a..cf6438f91d 100644 --- a/headers/private/media/DataExchange.h +++ b/headers/private/media/DataExchange.h @@ -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; diff --git a/src/servers/media/AppManager.cpp b/src/servers/media/AppManager.cpp index 019ade8dce..9d3e58df68 100644 --- a/src/servers/media/AppManager.cpp +++ b/src/servers/media/AppManager.cpp @@ -30,12 +30,11 @@ #include #include #include -#include -#include #include #include #include #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; 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(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"); diff --git a/src/servers/media/AppManager.h b/src/servers/media/AppManager.h index f3b3edc462..df3c29f9c9 100644 --- a/src/servers/media/AppManager.h +++ b/src/servers/media/AppManager.h @@ -2,37 +2,34 @@ * 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" class AppManager { public: - AppManager(); - ~AppManager(); + 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(); + status_t RegisterTeam(team_id, BMessenger); + status_t UnregisterTeam(team_id); + bool HasTeam(team_id); + + team_id AddonServerTeam(); + + status_t SendMessage(team_id team, BMessage *msg); - status_t SendMessage(team_id team, BMessage *msg); - - void Dump(); + void Dump(); private: - void CleanupTeam(team_id); - void CleanupAddonServer(); - void TeamDied(team_id team); - void RestartAddonServer(); + void CleanupTeam(team_id); + void TeamDied(team_id team); static int32 bigbrother(void *self); - void BigBrother(); + void BigBrother(); private: - team_id fAddonServer; thread_id fBigBrother; sem_id fQuit; @@ -43,3 +40,5 @@ private: Map * fAppMap; BLocker *fLocker; }; + +#endif // __APP_MANAGER_H diff --git a/src/servers/media/NodeManager.cpp b/src/servers/media/NodeManager.cpp index fe2b400627..efcb236616 100644 --- a/src/servers/media/NodeManager.cpp +++ b/src/servers/media/NodeManager.cpp @@ -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! diff --git a/src/servers/media/media_server.cpp b/src/servers/media/media_server.cpp index 348248ea40..196809a1f7 100644 --- a/src/servers/media/media_server.cpp +++ b/src/servers/media/media_server.cpp @@ -31,12 +31,15 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 Marcus Overhagen "; #include -#include +#include #include #include #include #include +#include +#include #include + #include "MMediaFilesManager.h" #include "NotificationManager.h" #include "ServerInterface.h" @@ -78,11 +81,13 @@ public: ServerApp(); ~ServerApp(); - bool QuitRequested(); - void HandleMessage(int32 code, void *data, size_t size); - void ArgvReceived(int32 argc, char **argv); - static int32 controlthread(void *arg); -// void StartSystemTimeSource(); +private: + bool QuitRequested(); + void HandleMessage(int32 code, void *data, size_t size); + void ArgvReceived(int32 argc, char **argv); + + 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; - - 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); + app_info info; + BEntry entry; + BDirectory dir; + entry_ref ref; - ASSERT(node.node == NODE_SYSTEM_TIMESOURCE_ID); - - TRACE("StartSystemTimeSource setting as default\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); - 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(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(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); diff --git a/src/servers/media_addon/main.cpp b/src/servers/media_addon/main.cpp index 9f72837508..9b19727013 100644 --- a/src/servers/media_addon/main.cpp +++ b/src/servers/media_addon/main.cpp @@ -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)