winget-cli

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

Synchronization.cpp (2101B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #include "pch.h"
      4 #include <AppInstallerSynchronization.h>
      5 #include <AppInstallerStrings.h>
      6 
      7 
      8 namespace AppInstaller::Synchronization
      9 {
     10     // The amount of time that we wait in between checking for cancellation
     11     constexpr std::chrono::milliseconds s_CrossProcessInstallLock_WaitLoopTime = 250ms;
     12 
     13     CrossProcessLock::CrossProcessLock(std::string_view name) : CrossProcessLock(Utility::ConvertToUTF16(name))
     14     {
     15     }
     16 
     17     CrossProcessLock::CrossProcessLock(const std::wstring& name)
     18     {
     19         m_mutex.create(name.c_str(), 0, SYNCHRONIZE);
     20     }
     21 
     22     CrossProcessLock::~CrossProcessLock()
     23     {
     24         Release();
     25     }
     26 
     27     bool CrossProcessLock::Acquire(IProgressCallback& progress)
     28     {
     29         while (!progress.IsCancelledBy(CancelReason::Any))
     30         {
     31             auto lock = m_mutex.acquire(nullptr, static_cast<DWORD>(std::chrono::duration_cast<std::chrono::milliseconds>(s_CrossProcessInstallLock_WaitLoopTime).count()));
     32 
     33             if (lock)
     34             {
     35                 m_lockThreadId = GetCurrentThreadId();
     36                 m_lock = std::move(lock);
     37                 return true;
     38             }
     39         }
     40 
     41         return false;
     42     }
     43 
     44     void CrossProcessLock::Release()
     45     {
     46         if (m_lock)
     47         {
     48             // Ensure that we are in fact always releasing on the same thread that acquired the lock.
     49             // This is to force crashes rather than deadlocks in the event that we make a design error that leads to that.
     50             FAIL_FAST_IF(m_lockThreadId != GetCurrentThreadId());
     51             m_lock.reset();
     52         }
     53     }
     54 
     55     bool CrossProcessLock::TryAcquireNoWait()
     56     {
     57         auto lock = m_mutex.acquire(nullptr, 0);
     58 
     59         if (lock)
     60         {
     61             m_lockThreadId = GetCurrentThreadId();
     62             m_lock = std::move(lock);
     63             return true;
     64         }
     65 
     66         return false;
     67     }
     68 
     69     CrossProcessLock::operator bool() const
     70     {
     71         return static_cast<bool>(m_lock);
     72     }
     73 }