winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

ShutdownMonitoring.h (4168B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #pragma once
      4 #include <Windows.h>
      5 #include <AppInstallerProgress.h>
      6 #include <winrt/Windows.ApplicationModel.h>
      7 #include <wil/resource.h>
      8 #include <memory>
      9 #include <mutex>
     10 
     11 namespace AppInstaller::ShutdownMonitoring
     12 {
     13     // Type to contain the CTRL signal and window messages handler.
     14     struct TerminationSignalHandler
     15     {
     16         TerminationSignalHandler();
     17 
     18         ~TerminationSignalHandler();
     19 
     20         // Gets the singleton handler.
     21         static std::shared_ptr<TerminationSignalHandler> Instance();
     22 
     23         // Add a termination listener.
     24         void AddListener(ICancellable* cancellable);
     25 
     26         // Remove a termination listener.
     27         void RemoveListener(ICancellable* cancellable);
     28 
     29         // Add or remove the listener based on `enabled`.
     30         static void EnableListener(bool enabled, ICancellable* cancellable);
     31 
     32 #ifndef AICLI_DISABLE_TEST_HOOKS
     33         // Gets the window handle for the message window.
     34         HWND GetWindowHandle() const;
     35 
     36         // Waits for the shutdown event.
     37         bool WaitForAppShutdownEvent() const;
     38 #endif
     39 
     40     private:
     41         void StartAppShutdown();
     42 
     43         static BOOL WINAPI StaticCtrlHandlerFunction(DWORD ctrlType);
     44 
     45         static LRESULT WINAPI WindowMessageProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
     46 
     47         BOOL CtrlHandlerFunction(DWORD ctrlType);
     48 
     49         // Terminates the currently attached contexts.
     50         // Returns FALSE if no contexts attached; TRUE otherwise.
     51         BOOL InformListeners(CancelReason reason, bool force);
     52 
     53         void CreateWindowAndStartMessageLoop();
     54 
     55 #ifndef AICLI_DISABLE_TEST_HOOKS
     56         wil::unique_event m_appShutdownEvent;
     57 #endif
     58 
     59         std::mutex m_listenersLock;
     60         std::vector<ICancellable*> m_listeners;
     61         wil::unique_event m_messageQueueReady;
     62         wil::unique_hwnd m_windowHandle;
     63         std::thread m_windowThread;
     64         winrt::Windows::ApplicationModel::PackageCatalog m_catalog = nullptr;
     65         decltype(winrt::Windows::ApplicationModel::PackageCatalog{ nullptr }.PackageUpdating(winrt::auto_revoke, nullptr)) m_updatingEvent;
     66     };
     67 
     68     // Coordinates shutdown across server components
     69     struct ServerShutdownSynchronization : public ICancellable
     70     {
     71         using ShutdownCompleteCallback = void (*)();
     72 
     73         // Initializes the monitoring system and sets up a callback to be invoked when shutdown is completed.
     74         static void Initialize(ShutdownCompleteCallback callback);
     75 
     76         // "Interface" for a single component to synchronize with.
     77         struct ComponentSystem
     78         {
     79             // Initiate the shutdown process.
     80             // Components are expected to set flags to prevent any further work from beginning and return as quickly as possible.
     81             void (*BlockNewWork)(CancelReason reason) = nullptr;
     82 
     83             // Components are expected to cancel active or pending work as asynchronously as possible.
     84             void (*BeginShutdown)(CancelReason reason) = nullptr;
     85 
     86             // Components wait until all active and pending work have completed their 
     87             void (*Wait)() = nullptr;
     88         };
     89 
     90         // Adds a component to the system.
     91         static void AddComponent(const ComponentSystem& component);
     92 
     93         // Waits for the shutdown to complete.
     94         static void WaitForShutdown();
     95 
     96         // Listens for a termination signal.
     97         void Cancel(CancelReason reason, bool force) override;
     98 
     99     private:
    100         ServerShutdownSynchronization();
    101         ~ServerShutdownSynchronization();
    102 
    103         static ServerShutdownSynchronization& Instance();
    104 
    105         // Runs the actual shutdown process and invokes the callback.
    106         void SynchronizeShutdown(CancelReason reason);
    107 
    108         ShutdownCompleteCallback m_callback = nullptr;
    109         std::mutex m_componentsLock;
    110         std::vector<ComponentSystem> m_components;
    111         std::mutex m_threadLock;
    112         std::thread m_shutdownThread;
    113         wil::slim_event_manual_reset m_shutdownComplete;
    114     };
    115 }