From 2fd4a0411b7a0a98d8099ef3ec8e52ee75a1d3a1 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 17 Jul 2005 16:37:11 +0000 Subject: [PATCH] Added a boolean "synchronous" parameter to BRoster::Shutdown(). Used in the Deskbar to initiate the shutdown process asynchronously. Couldn't test it, because opening the Be menu doesn't work: ***PANIC: BW: Can't find view with ID: 19 !*** git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13722 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- docs/develop/servers/registrar/Protocols | 7 ++++- headers/os/app/Roster.h | 2 +- headers/private/app/RosterPrivate.h | 4 +-- src/apps/deskbar/BarApp.cpp | 34 ++++++----------------- src/bin/shutdown.cpp | 2 +- src/kits/app/Roster.cpp | 9 ++++-- src/servers/registrar/ShutdownProcess.cpp | 22 ++++++++++++++- src/servers/registrar/ShutdownProcess.h | 3 ++ 8 files changed, 50 insertions(+), 33 deletions(-) diff --git a/docs/develop/servers/registrar/Protocols b/docs/develop/servers/registrar/Protocols index d57039875c..2e2403d8bf 100644 --- a/docs/develop/servers/registrar/Protocols +++ b/docs/develop/servers/registrar/Protocols @@ -66,7 +66,9 @@ shut down target: registrar app looper (preferred handler) message: B_REG_SHUT_DOWN - "reboot": B_BOOL_TYPE + "reboot": B_BOOL_TYPE + "confirm": B_BOOL_TYPE + "synchronously": B_BOOL_TYPE reply: standard success on error: - B_NO_REPLY (fatal) - standard error (fatal) @@ -74,6 +76,9 @@ on error: - B_NO_REPLY (fatal) message fields: - "reboot": If true, the system reboots instead of turning the power off. - "confirm": If true, the user will be asked to confirm to shut down the system. +- "synchronously": If true, the request sender gets a reply only, if the + shutdown process fails. Otherwise the reply will be sent + right before asking the user for confirmation (if desired). ----------------------------------------------------------------------- diff --git a/headers/os/app/Roster.h b/headers/os/app/Roster.h index d92dc77e96..87f11e45ca 100644 --- a/headers/os/app/Roster.h +++ b/headers/os/app/Roster.h @@ -143,7 +143,7 @@ private: class ArgVector; friend class Private; - status_t ShutDown(bool reboot, bool confirm); + status_t ShutDown(bool reboot, bool confirm, bool synchronous); status_t AddApplication(const char *mimeSig, const entry_ref *ref, uint32 flags, team_id team, thread_id thread, diff --git a/headers/private/app/RosterPrivate.h b/headers/private/app/RosterPrivate.h index 94525ac5ad..fcecffbe9f 100644 --- a/headers/private/app/RosterPrivate.h +++ b/headers/private/app/RosterPrivate.h @@ -20,8 +20,8 @@ public: status_t SendTo(BMessage *message, BMessage *reply, bool mime); bool IsMessengerValid(bool mime) const; - status_t ShutDown(bool reboot, bool confirm) - { return fRoster->ShutDown(reboot, confirm); } + status_t ShutDown(bool reboot, bool confirm, bool synchronous) + { return fRoster->ShutDown(reboot, confirm, synchronous); } // needed by BApplication diff --git a/src/apps/deskbar/BarApp.cpp b/src/apps/deskbar/BarApp.cpp index 4482e7a21f..ee6e1e1791 100644 --- a/src/apps/deskbar/BarApp.cpp +++ b/src/apps/deskbar/BarApp.cpp @@ -462,20 +462,17 @@ TBarApp::MessageReceived(BMessage *message) break; #if __HAIKU__ - case CMD_REBOOT_SYSTEM: case CMD_SUSPEND_SYSTEM: + break; + + case CMD_REBOOT_SYSTEM: case CMD_SHUTDOWN_SYSTEM: { - // TODO: Deskbar cannot quit because BRoster::Private::Shutdown() is synchronous, - // so we launch a thread which does the shutdown, this should be reworked so - // that we can simply send a message to the roster and be done with it - void* cookie = message->what == CMD_SHUTDOWN_SYSTEM ? NULL : (void*)1; - thread_id thread = spawn_thread(_shutdown, "shutdown thread", B_NORMAL_PRIORITY, cookie); - if (thread >= B_OK) { - status_t ret = resume_thread(thread); - if (ret < B_OK) - fprintf(stderr, "error resuming shutdown thread: %s\n", strerror(ret)); - } else - fprintf(stderr, "error spawning shutdown thread: %s\n", strerror(thread)); + bool reboot = (message->what == CMD_REBOOT_SYSTEM); + BRoster roster; + BRoster::Private rosterPrivate(roster); + status_t error = rosterPrivate.ShutDown(reboot, true, false); + if (error != B_OK) + fprintf(stderr, "Shutdown failed: %s\n", strerror(error)); break; } @@ -667,19 +664,6 @@ TBarApp::ShowConfigWindow() } } -#if __HAIKU__ -// _shutdown -int32 -TBarApp::_shutdown(void* cookie) -{ - BRoster roster; - BRoster::Private rosterPrivate(roster); - status_t error = rosterPrivate.ShutDown(cookie != NULL, false); - fprintf(stderr, "Shutdown failed: %s\n", strerror(error)); - return 0; -} -#endif // __HAIKU__ - // #pragma mark - diff --git a/src/bin/shutdown.cpp b/src/bin/shutdown.cpp index 431a8a2a43..fc90bede99 100644 --- a/src/bin/shutdown.cpp +++ b/src/bin/shutdown.cpp @@ -174,7 +174,7 @@ main(int argc, char **argv) } else { BRoster roster; BRoster::Private rosterPrivate(roster); - status_t error = rosterPrivate.ShutDown(gReboot, askUser); + status_t error = rosterPrivate.ShutDown(gReboot, askUser, true); fprintf(stderr, "Shutdown failed: %s\n", strerror(error)); return 2; } diff --git a/src/kits/app/Roster.cpp b/src/kits/app/Roster.cpp index 86571fafdc..864d415055 100644 --- a/src/kits/app/Roster.cpp +++ b/src/kits/app/Roster.cpp @@ -1269,12 +1269,15 @@ BRoster::AddToRecentFolders(const entry_ref *folder, const char *appSig) const // ShutDown /*! \brief Shuts down the system. - When the method succeeds, it doesn't return. + When \c synchronous is \c true and the method succeeds, it doesn't return. \param reboot If \c true, the system will be rebooted instead of being powered off. \param confirm If \c true, the user will be asked to confirm to shut down the system. + \param synchronous If \c false, the method will return as soon as the + shutdown process has been initiated successfully (or an error + occurred). Otherwise the method doesn't return, if successfully. \return - \c B_SHUTTING_DOWN, when there's already a shutdown process in progress, @@ -1282,7 +1285,7 @@ BRoster::AddToRecentFolders(const entry_ref *folder, const char *appSig) const - another error code in case something went wrong. */ status_t -BRoster::ShutDown(bool reboot, bool confirm) +BRoster::ShutDown(bool reboot, bool confirm, bool synchronous) { status_t error = B_OK; @@ -1292,6 +1295,8 @@ BRoster::ShutDown(bool reboot, bool confirm) error = request.AddBool("reboot", reboot); if (error == B_OK) error = request.AddBool("confirm", confirm); + if (error == B_OK) + error = request.AddBool("synchronous", synchronous); // send the request BMessage reply; diff --git a/src/servers/registrar/ShutdownProcess.cpp b/src/servers/registrar/ShutdownProcess.cpp index 8e8340468d..229310efb8 100644 --- a/src/servers/registrar/ShutdownProcess.cpp +++ b/src/servers/registrar/ShutdownProcess.cpp @@ -607,6 +607,7 @@ ShutdownProcess::ShutdownProcess(TRoster *roster, EventQueue *eventQueue) fShutdownError(B_ERROR), fHasGUI(false), fReboot(false), + fRequestReplySent(false), fWindow(NULL) { } @@ -656,7 +657,7 @@ ShutdownProcess::~ShutdownProcess() } // send a reply to the request and delete it - SendReply(fRequest, fShutdownError); + _SendReply(fShutdownError); delete fRequest; } @@ -856,6 +857,16 @@ ShutdownProcess::SendReply(BMessage *request, status_t error) } } +// _SendReply +void +ShutdownProcess::_SendReply(status_t error) +{ + if (!fRequestReplySent) { + SendReply(fRequest, error); + fRequestReplySent = true; + } +} + // _SetPhase void ShutdownProcess::_SetPhase(int32 phase) @@ -1216,6 +1227,15 @@ ShutdownProcess::_WorkerDoShutdown() { PRINT(("ShutdownProcess::_WorkerDoShutdown()\n")); + // If we are here, the shutdown process has been initiated successfully, + // that is, if an asynchronous BRoster::Shutdown() was requested, we + // notify the caller at this point. + bool synchronously; + if (fRequest->FindBool("synchronously", &synchronously) == B_OK + && !synchronously) { + _SendReply(B_OK); + } + // ask the user to confirm the shutdown, if desired bool askUser; if (fHasGUI && fRequest->FindBool("confirm", &askUser) == B_OK && askUser) { diff --git a/src/servers/registrar/ShutdownProcess.h b/src/servers/registrar/ShutdownProcess.h index ed8da8dd6f..5394a1782c 100644 --- a/src/servers/registrar/ShutdownProcess.h +++ b/src/servers/registrar/ShutdownProcess.h @@ -32,6 +32,8 @@ public: static void SendReply(BMessage *request, status_t error); private: + void _SendReply(status_t error); + void _NegativeQuitRequestReply(thread_id thread); void _PrepareShutdownMessage(BMessage &message) const; @@ -98,6 +100,7 @@ private: status_t fShutdownError; bool fHasGUI; bool fReboot; + bool fRequestReplySent; ShutdownWindow *fWindow; };