/* * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net. * Copyright 2021, Jacob Secunda. * * Distributed under the terms of the MIT License. * * Manages the shutdown process. */ #ifndef SHUTDOWN_PROCESS_H #define SHUTDOWN_PROCESS_H #include #include #include #include #include "AppInfoList.h" #include "EventMaskWatcher.h" #include "RosterAppInfo.h" class EventQueue; class TRoster; // Note: EventMaskWatcher is inherited public due to a gcc bug/C++ feature: // Once cast into a Watcher dynamic_cast<>()ing it back into an // EventMaskWatcher fails otherwise. class ShutdownProcess : public BLooper, public EventMaskWatcher { public: ShutdownProcess(TRoster* roster, EventQueue* eventQueue); virtual ~ShutdownProcess(); status_t Init(BMessage* request); virtual void MessageReceived(BMessage* message); static void SendReply(BMessage* request, status_t error); private: void _SendReply(status_t error); void _NegativeQuitRequestReply(thread_id thread); void _PrepareShutdownMessage(BMessage& message) const; status_t _ShutDown(); status_t _PushEvent(uint32 eventType, team_id team, int32 phase); status_t _GetNextEvent(uint32& eventType, team_id& team, int32& phase, bool block); void _SetPhase(int32 phase); void _ScheduleTimeoutEvent(bigtime_t timeout, team_id team = -1); bool _LockAppLists(); void _UnlockAppLists(); void _InitShutdownWindow(); void _SetShowShutdownWindow(bool show); void _AddShutdownWindowApps(AppInfoList& infos); void _RemoveShutdownWindowApp(team_id team); void _SetShutdownWindowCurrentApp(team_id team); void _SetShutdownWindowText(const char* text); void _SetShutdownWindowCancelButtonEnabled( bool enabled); void _SetShutdownWindowKillButtonEnabled( bool enabled); void _SetShutdownWindowWaitAnimationEnabled( bool enabled); void _SetShutdownWindowWaitForShutdown(); void _SetShutdownWindowWaitForAbortedOK(); static status_t _WorkerEntry(void* data); status_t _Worker(); void _WorkerDoShutdown(); bool _WaitForApp(team_id team, AppInfoList* list, bool systemApps); void _QuitApps(AppInfoList& list, bool systemApps); void _QuitBackgroundApps(); void _WaitForBackgroundApps(); void _KillBackgroundApps(); void _QuitNonApps(); void _QuitBlockingApp(AppInfoList& list, team_id team, const char* appName, bool cancelAllowed); void _DisplayAbortingApp(team_id team); void _WaitForDebuggedTeams(); private: class TimeoutEvent; class InternalEvent; struct InternalEventList; class QuitRequestReplyHandler; class ShutdownWindow; typedef HashSet > TeamHash; friend class QuitRequestReplyHandler; BLocker fWorkerLock; // protects fields shared by looper // and worker BMessage* fRequest; TRoster* fRoster; EventQueue* fEventQueue; TeamHash fVitalSystemApps; AppInfoList fSystemApps; AppInfoList fUserApps; AppInfoList fBackgroundApps; TeamHash fDebuggedTeams; TimeoutEvent* fTimeoutEvent; InternalEventList* fInternalEvents; sem_id fInternalEventSemaphore; QuitRequestReplyHandler* fQuitRequestReplyHandler; thread_id fWorker; int32 fCurrentPhase; status_t fShutdownError; bool fHasGUI; bool fReboot; bool fRequestReplySent; ShutdownWindow* fWindow; }; #endif // SHUTDOWN_PROCESS_H