1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef AppShutdown_h
8 #define AppShutdown_h
9 
10 #include <type_traits>
11 #include "ShutdownPhase.h"
12 
13 namespace mozilla {
14 
15 enum class AppShutdownMode {
16   Normal,
17   Restart,
18 };
19 
20 class AppShutdown {
21  public:
22   static bool IsShuttingDown();
23   static ShutdownPhase GetCurrentShutdownPhase();
24   static bool IsInOrBeyond(ShutdownPhase aPhase);
25 
26   /**
27    * Returns the current exit code that the process will be terminated with.
28    */
29   static int GetExitCode();
30 
31   /**
32    * Save environment variables that we might need if the app initiates a
33    * restart later in its lifecycle.
34    */
35   static void SaveEnvVarsForPotentialRestart();
36 
37   /**
38    * Init the shutdown with the requested shutdown mode and exit code.
39    */
40   static void Init(AppShutdownMode aMode, int aExitCode);
41 
42   /**
43    * Confirm that we are in fact going to be shutting down.
44    */
45   static void OnShutdownConfirmed();
46 
47   /**
48    * If we've attempted to initiate a restart, this call will set up the
49    * necessary environment variables and launch the new process.
50    */
51   static void MaybeDoRestart();
52 
53   /**
54    * The _exit() call is not a safe way to terminate your own process on
55    * Windows, because _exit runs DLL detach callbacks which run static
56    * destructors for xul.dll.
57    *
58    * This method terminates the current process without those issues.
59    *
60    * Optionally a custom exit code can be supplied.
61    */
62   static void DoImmediateExit(int aExitCode = 0);
63 
64   /**
65    * True if the application is currently attempting to shut down in order to
66    * restart.
67    */
68   static bool IsRestarting();
69 
70   /**
71    * Wrapper for shutdown notifications that informs the terminator before
72    * we notify other observers. Calls MaybeFastShutdown.
73    */
74   static void AdvanceShutdownPhase(
75       ShutdownPhase aPhase, const char16_t* aNotificationData = nullptr,
76       const nsCOMPtr<nsISupports>& aNotificationSubject =
77           nsCOMPtr<nsISupports>(nullptr));
78 
79   /**
80    * XXX: Before tackling bug 1697745 we need the
81    * possibility to advance the phase without notification
82    * in the content process.
83    */
84   static void AdvanceShutdownPhaseWithoutNotify(ShutdownPhase aPhase);
85 
86   /**
87    * This will perform a fast shutdown via _exit(0) or similar if the user's
88    * prefs are configured to do so at this phase.
89    */
90   static void MaybeFastShutdown(ShutdownPhase aPhase);
91 
92   /**
93    * Map shutdown phase to observer key
94    */
95   static const char* GetObserverKey(ShutdownPhase aPhase);
96 
97   /**
98    * Map observer topic key to shutdown phase
99    */
100   static ShutdownPhase GetShutdownPhaseFromTopic(const char* aTopic);
101 
102 #ifdef DEBUG
103   /**
104    * Check, if we are allowed to send a shutdown notification.
105    * Shutdown specific topics are only allowed during calls to
106    * AdvanceShutdownPhase itself.
107    */
108   static bool IsNoOrLegalShutdownTopic(const char* aTopic);
109 #endif
110 };
111 
112 }  // namespace mozilla
113 
114 #endif  // AppShutdown_h
115