From ce7fd13b0d46be3f27689ce1500aca6ab6ff467f Mon Sep 17 00:00:00 2001 From: DarkWyrm Date: Thu, 21 Dec 2006 21:12:58 +0000 Subject: [PATCH] Initial checkin. Works fine for me so far, but YMMV. Bug reports appreciated. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19597 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/Jamfile | 1 + src/servers/services_daemon/Jamfile | 9 + .../services_daemon/ServicesDaemon.cpp | 245 ++++++++++++++++++ src/servers/services_daemon/ServicesDaemon.h | 25 ++ .../services_daemon/ServicesDaemon.rdef | 69 +++++ 5 files changed, 349 insertions(+) create mode 100644 src/servers/services_daemon/Jamfile create mode 100644 src/servers/services_daemon/ServicesDaemon.cpp create mode 100644 src/servers/services_daemon/ServicesDaemon.h create mode 100644 src/servers/services_daemon/ServicesDaemon.rdef diff --git a/src/servers/Jamfile b/src/servers/Jamfile index b8f4432999..4e3f77d41d 100644 --- a/src/servers/Jamfile +++ b/src/servers/Jamfile @@ -11,4 +11,5 @@ SubInclude HAIKU_TOP src servers net ; SubInclude HAIKU_TOP src servers power ; SubInclude HAIKU_TOP src servers print ; SubInclude HAIKU_TOP src servers registrar ; +SubInclude HAIKU_TOP src servers services_daemon ; SubInclude HAIKU_TOP src servers syslog_daemon ; diff --git a/src/servers/services_daemon/Jamfile b/src/servers/services_daemon/Jamfile new file mode 100644 index 0000000000..e0aa61721f --- /dev/null +++ b/src/servers/services_daemon/Jamfile @@ -0,0 +1,9 @@ +SubDir HAIKU_TOP src servers services_daemon ; + +SetSubDirSupportedPlatformsBeOSCompatible ; + +Application services_daemon : + ServicesDaemon.cpp + : be media + : ServicesDaemon.rdef + ; diff --git a/src/servers/services_daemon/ServicesDaemon.cpp b/src/servers/services_daemon/ServicesDaemon.cpp new file mode 100644 index 0000000000..f7ad8828ee --- /dev/null +++ b/src/servers/services_daemon/ServicesDaemon.cpp @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2005-2006, Haiku, Inc. + * Distributed under the terms of the MIT license. + * + * Author: + * DarkWyrm + */ +#include "ServicesDaemon.h" +#include +#include +#include +#include + +enum { + M_RELAUNCH_DESKBAR = 'rtsk', + M_RELAUNCH_TRACKER, + M_RELAUNCH_MAIL, + M_RELAUNCH_PRINT, + M_RELAUNCH_AUDIO, + M_RELAUNCH_MEDIA_ADDONS, + M_RELAUNCH_MEDIA, + M_RELAUNCH_MIDI +}; + +// Time delay in microseconds - 1 seconds +const bigtime_t kRelaunchDelay = 1000000; + +const char *gSignatures[] = { + "application/x-vnd.Be-TSKB", + "application/x-vnd.Be-TRAK", + "application/x-vnd.Be-POST", + "application/x-vnd.Be-PSRV", + "application/x-vnd.Be-AUSV", + "application/x-vnd.Be.addon-host", + "application/x-vnd.Be.media-server", + "application/x-vnd.be-midi-roster", + NULL +}; + +static sem_id sRelaunchSem; +static sem_id sQuitSem; + + + +App::App(void) + : BApplication("application/x-vnd.Haiku-ServicesDaemon"), + fStatus(B_NO_INIT) +{ + sRelaunchSem = create_sem(1,"relaunch_sem"); + sQuitSem = create_sem(1,"quit_sem"); + + // We will release this when we want the relauncher thread to quit + acquire_sem(sQuitSem); + + // We will release this semaphore when we want to activate the relauncher + // thread + acquire_sem(sRelaunchSem); + + fRelauncherID = spawn_thread(App::RelauncherThread, "relauncher_thread", + B_NORMAL_PRIORITY,this); + resume_thread(fRelauncherID); + + fStatus = be_roster->StartWatching(be_app_messenger, B_REQUEST_QUIT); + if (fStatus != B_OK) + PostMessage(B_QUIT_REQUESTED); +} + + +App::~App(void) +{ + // Release in this order so that there isn't a race condition when quitting. + // The thread waits + release_sem(sQuitSem); + release_sem(sRelaunchSem); + + int32 dummyval; + wait_for_thread(fRelauncherID, &dummyval); +} + + +bool +App::QuitRequested(void) +{ + if (fStatus == B_OK) + be_roster->StopWatching(be_app_messenger); + + return true; +} + +void +App::MessageReceived(BMessage *msg) +{ + switch (msg->what) { + case B_SOME_APP_QUIT: { + BString string; + if (msg->FindString("be:signature",&string) != B_OK) + return; + + int i = 0; + while (gSignatures[i]) { + // Checking to see if it's one of the supported signatures + // and if it is, add a relaunch message to the queue which is + // to be posted here at the + if (string.Compare(gSignatures[i]) == 0) { + BMessage *launchmsg = new BMessage(M_RELAUNCH_DESKBAR + i); + fRelaunchQueue.AddMessage(launchmsg); + + release_sem(sRelaunchSem); + acquire_sem(sRelaunchSem); + } + i++; + } + break; + } + case M_RELAUNCH_DESKBAR: { + BAlert *alert = new BAlert("Services Daemon", + "The Deskbar is no longer running. Restart it?", + "No","Yes"); + if (alert->Go() == 1) { + be_roster->Launch(gSignatures[msg->what - M_RELAUNCH_DESKBAR]); + break; + } + break; + } + case M_RELAUNCH_TRACKER: { + BAlert *alert = new BAlert("Services Daemon", + "Tracker is no longer running. Restart it?", + "No","Yes"); + if (alert->Go() == 1) { + be_roster->Launch(gSignatures[msg->what - M_RELAUNCH_DESKBAR]); + break; + } + break; + } + case M_RELAUNCH_MAIL: { + BAlert *alert = new BAlert("Services Daemon", + "Mail services are no longer running. Restart them?", + "No","Yes"); + if (alert->Go() == 1) { + be_roster->Launch(gSignatures[msg->what - M_RELAUNCH_DESKBAR]); + break; + } + break; + } + case M_RELAUNCH_PRINT: { + BAlert *alert = new BAlert("Services Daemon", + "Print services are no longer running. Restart them?", + "No","Yes"); + if (alert->Go() == 1) { + be_roster->Launch(gSignatures[msg->what - M_RELAUNCH_DESKBAR]); + break; + } + break; + } + case M_RELAUNCH_AUDIO: { + BAlert *alert = new BAlert("Services Daemon", + "The audio server is no longer running. Restart them?", + "No","Yes"); + if (alert->Go() == 1) { + be_roster->Launch(gSignatures[msg->what - M_RELAUNCH_DESKBAR]); + break; + } + break; + } + case M_RELAUNCH_MEDIA_ADDONS: + case M_RELAUNCH_MEDIA: { + BAlert *alert = new BAlert("Services Daemon", + "Media services are no longer running. Restart them?", + "No","Yes"); + if (alert->Go() == 1) { + shutdown_media_server(); + launch_media_server(); + break; + } + break; + } + case M_RELAUNCH_MIDI: { + BAlert *alert = new BAlert("Services Daemon", + "The MIDI server is no longer running. Restart them?", + "No","Yes"); + if (alert->Go() == 1) { + be_roster->Launch(gSignatures[msg->what - M_RELAUNCH_DESKBAR]); + break; + } + break; + } + default: + BApplication::MessageReceived(msg); + } +} + + +int32 +App::RelauncherThread(void *data) +{ + App *app = (App*) data; + + sem_info quitSemInfo; + get_sem_info(sQuitSem, &quitSemInfo); + + while (quitSemInfo.count > -1) { + // wait until we need to check for a relaunch + acquire_sem(sRelaunchSem); + + // We can afford to do this because while we have the semaphore, the + // app itself is locked. + BMessage *msg = app->fRelaunchQueue.NextMessage(); + + release_sem(sRelaunchSem); + + get_sem_info(sQuitSem, &quitSemInfo); + if (quitSemInfo.count > 0) { + if (msg) + delete msg; + break; + } + + if (msg) { + // Attempt to work around R5 shutdown procedures by checking for + // debug_server running state. If it's shut down, then chances are that + // the system is shutting down or has already done so. We use the + // debug server in particular because it's one of the few services + // that is available in safe mode which is closed on system shutdown. + + if (be_roster->IsRunning("application/x-vnd.Be-DBSV")) { + snooze(kRelaunchDelay); + app->PostMessage(msg->what); + delete msg; + } + } + + get_sem_info(sQuitSem, &quitSemInfo); + } + + return 0; +} + +int +main(void) +{ + App *app = new App(); + app->Run(); + delete app; + return 0; +} diff --git a/src/servers/services_daemon/ServicesDaemon.h b/src/servers/services_daemon/ServicesDaemon.h new file mode 100644 index 0000000000..9946c33da5 --- /dev/null +++ b/src/servers/services_daemon/ServicesDaemon.h @@ -0,0 +1,25 @@ +#ifndef SERVICES_DAEMON_H +#define SERVICES_DAEMON_H + +#include +#include +#include + +class App : public BApplication +{ +public: + App(void); + ~App(void); + bool QuitRequested(void); + void MessageReceived(BMessage *msg); + +private: + static int32 RelauncherThread(void *data); + + thread_id fRelauncherID; + status_t fStatus; + BMessageQueue fRelaunchQueue; +}; + + +#endif diff --git a/src/servers/services_daemon/ServicesDaemon.rdef b/src/servers/services_daemon/ServicesDaemon.rdef new file mode 100644 index 0000000000..ae85f58c14 --- /dev/null +++ b/src/servers/services_daemon/ServicesDaemon.rdef @@ -0,0 +1,69 @@ +resource app_signature "application/x-vnd.Haiku-ServicesDaemon"; + +resource app_version { + major = 0, + middle = 0, + minor = 1, + + variety = B_APPV_ALPHA, + internal = 0, + + short_info = "Services Daemon", + long_info = "Services Daemon © 2006 Haiku" +}; + +resource app_flags B_EXCLUSIVE_LAUNCH | B_BACKGROUND_APP; + +resource(101, "BEOS:L:STD_ICON") #'ICON' array { + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFF" + $"FFFFFFFFFF000000000000000000000000000000FFFF003FD9D9D90000FFFFFF" + $"FFFFFFFF003F3F3F3F3F3F3F3F3F3F3F3F3F3F3F00003FD9D9D9D9D9D90000FF" + $"FFFFFFFF003FD9D9D9D9D9D9D9D9D9D9D9D9D9D93F3FAAAAD9D9D9D9D9D98300" + $"FFFFFFFF003FD98383838383838383D9D9D9D9D9D9838383AAAAD9D9D983AA00" + $"FFFFFFFFFFFF00000000000000003FD9D9D9D9D9833F3FD93F3FAAAA83AAAA00" + $"FFFF85FFFFFFFFFFFFFF04FFFF3FD9D98383833F3FD9D9D9D9D93F3FAAAAAA00" + $"FFFFFF989898FFFFFFFF04FF3F98989898989883D9D9D9D93F3FD9D983AA0011" + $"FFFFFF98989898989898989898989898AA9898989898D9D93F3FD9D9D9AA0017" + $"FFFFFFFF989898AA9898989898989898AA98989898989898D9D9D9D9D9830011" + $"FFFFFFFF98989898AAAAAAAAAA98989898AA989898989898D9D9D9D983AA0111" + $"FFFFFFFFFFFF98989898989898AAAAAAAAAAAA98989898989898D983AA001111" + $"FFFFFFFFFFFF009898989898AA989898989898AAAAAA9898989898AA001111FF" + $"FFFFFFFFFF001ED9839898989898989898AAAA989898AAAA989898981111FFFF" + $"FFFFFFFF003FD9838300040498989898AA98989898989898AAAA989811FFFFFF" + $"FFFFFF003FD98383001ED9D904041A9898989898989898989898AA98FFFFFFFF" + $"FFFF003FD98383031ED9D983830004041A0F04AAAA98989898989898FFFFFFFF" + $"FF003FD98383003FD9D98383003FD9D90404AAAAAA83AA001111FF9898FFFFFF" + $"003FD98383003FD9D98383003FD9D9838300AAAA83AA001111FFFFFF9898FFFF" + $"00D98383003FD9D98383003FD9D98383003FD98383001111FFFFFFFFFFFFFFFF" + $"FF0000003FD9D98383003FD9D98383003FD98383001111FFFFFFFFFFFFFFFFFF" + $"FFFF003FD9D98383003FD9D98383003FD98383001111FFFFFFFFFFFFFFFFFFFF" + $"FFFF00D9838306003FD9D98383003FD98383001111FFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFF0000001000D9D98383003FD98383001111FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFF000000003FD98300001111FFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF000000111111FFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" +}; + +resource(101, "BEOS:M:STD_ICON") #'MICN' array { + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFF0000FFFFFF" + $"FFFFFFFFFFFFFFFFFF0000D9D90000FF" + $"FFFFFF000000000000D9D9AAAAD98300" + $"FFFF00D9D9D9D9D9D983833F3FAAAA00" + $"FF980000000000D9D9D9D9D9D9D9AA00" + $"FFFF98989800D998989898D93FD9AA01" + $"FFFFFF9898AA989898AA9898D9830011" + $"FFFFFF009898AAAAAAAAAA98980011FF" + $"FFFF00D983009898AA9898AA980011FF" + $"FF00D98300D98398989898830098FFFF" + $"00D98300D98300D904D9830011FF98FF" + $"008300D98300D900D9830011FFFFFFFF" + $"FF00D98300D900D9830011FFFFFFFFFF" + $"FFFF0000000000000011FFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" +};