1/*
2 * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
3 * Copyright 2021, Jacob Secunda.
4 *
5 * Distributed under the terms of the MIT License.
6 *
7 * Manages the shutdown process.
8 */
9#ifndef SHUTDOWN_PROCESS_H
10#define SHUTDOWN_PROCESS_H
11
12#include <HashMap.h>
13#include <HashSet.h>
14#include <Locker.h>
15#include <Looper.h>
16
17#include "AppInfoList.h"
18#include "EventMaskWatcher.h"
19#include "RosterAppInfo.h"
20
21class EventQueue;
22class TRoster;
23
24// Note: EventMaskWatcher is inherited public due to a gcc bug/C++ feature:
25// Once cast into a Watcher dynamic_cast<>()ing it back into an
26// EventMaskWatcher fails otherwise.
27class ShutdownProcess : public BLooper, public EventMaskWatcher {
28public:
29								ShutdownProcess(TRoster* roster,
30									EventQueue* eventQueue);
31	virtual						~ShutdownProcess();
32
33			status_t			Init(BMessage* request);
34
35	virtual	void				MessageReceived(BMessage* message);
36
37	static	void				SendReply(BMessage* request, status_t error);
38
39private:
40			void				_SendReply(status_t error);
41
42			void				_NegativeQuitRequestReply(thread_id thread);
43
44			void				_PrepareShutdownMessage(BMessage& message) const;
45			status_t			_ShutDown();
46
47			status_t			_PushEvent(uint32 eventType, team_id team,
48									int32 phase);
49			status_t			_GetNextEvent(uint32& eventType, team_id& team,
50									int32& phase, bool block);
51
52			void				_SetPhase(int32 phase);
53			void				_ScheduleTimeoutEvent(bigtime_t timeout,
54									team_id team = -1);
55
56			bool				_LockAppLists();
57			void				_UnlockAppLists();
58
59			void				_InitShutdownWindow();
60			void				_SetShowShutdownWindow(bool show);
61			void				_AddShutdownWindowApps(AppInfoList& infos);
62			void				_RemoveShutdownWindowApp(team_id team);
63			void				_SetShutdownWindowCurrentApp(team_id team);
64			void				_SetShutdownWindowText(const char* text);
65			void				_SetShutdownWindowCancelButtonEnabled(
66									bool enabled);
67			void				_SetShutdownWindowKillButtonEnabled(
68									bool enabled);
69			void				_SetShutdownWindowWaitAnimationEnabled(
70									bool enabled);
71			void				_SetShutdownWindowWaitForShutdown();
72			void				_SetShutdownWindowWaitForAbortedOK();
73
74	static	status_t			_WorkerEntry(void* data);
75			status_t			_Worker();
76
77			void				_WorkerDoShutdown();
78			bool				_WaitForApp(team_id team, AppInfoList* list,
79									bool systemApps);
80			void				_QuitApps(AppInfoList& list, bool systemApps);
81			void				_QuitBackgroundApps();
82			void				_WaitForBackgroundApps();
83			void				_KillBackgroundApps();
84			void				_QuitNonApps();
85			void				_QuitBlockingApp(AppInfoList& list, team_id team,
86									const char* appName, bool cancelAllowed);
87			void				_DisplayAbortingApp(team_id team);
88			void				_WaitForDebuggedTeams();
89
90private:
91	class TimeoutEvent;
92	class InternalEvent;
93	struct InternalEventList;
94	class QuitRequestReplyHandler;
95	class ShutdownWindow;
96
97	typedef HashSet<HashKey32<team_id> > TeamHash;
98
99	friend class QuitRequestReplyHandler;
100
101			BLocker				fWorkerLock;
102									// protects fields shared by looper
103									// and worker
104			BMessage*			fRequest;
105			TRoster*			fRoster;
106			EventQueue*			fEventQueue;
107			TeamHash			fVitalSystemApps;
108			AppInfoList			fSystemApps;
109			AppInfoList			fUserApps;
110			AppInfoList			fBackgroundApps;
111			TeamHash			fDebuggedTeams;
112			TimeoutEvent*		fTimeoutEvent;
113			InternalEventList*	fInternalEvents;
114			sem_id				fInternalEventSemaphore;
115			QuitRequestReplyHandler* fQuitRequestReplyHandler;
116			thread_id			fWorker;
117			int32				fCurrentPhase;
118			status_t			fShutdownError;
119			bool				fHasGUI;
120			bool				fReboot;
121			bool				fRequestReplySent;
122			ShutdownWindow*		fWindow;
123};
124
125#endif	// SHUTDOWN_PROCESS_H
126