text: // Copyright (c) .NET Foundation. All rights reserved.
  // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  
  #include "PollingAppOfflineApplication.h"
  
  #include <filesystem>
  #include "SRWExclusiveLock.h"
  #include "HandleWrapper.h"
  #include "exceptions.h"
  
  HRESULT PollingAppOfflineApplication::TryCreateHandler(_In_ IHttpContext* pHttpContext, _Outptr_result_maybenull_ IREQUEST_HANDLER** pRequestHandler)
  {
      CheckAppOffline();
  
      return LOG_IF_FAILED(APPLICATION::TryCreateHandler(pHttpContext, pRequestHandler));
  }
  
  void
  PollingAppOfflineApplication::CheckAppOffline()
  {
      if (m_fStopCalled)
      {
          return;
      }
  
      const auto ulCurrentTime = GetTickCount64();
      //
      // we only care about app offline presented. If not, it means the application has started
      // and is monitoring  the app offline file
      // we cache the file exist check result for 200 ms
      //
      if (ulCurrentTime - m_ulLastCheckTime > c_appOfflineRefreshIntervalMS)
      {
          SRWExclusiveLock lock(m_statusLock);
          if (ulCurrentTime - m_ulLastCheckTime > c_appOfflineRefreshIntervalMS)
          {
              m_fAppOfflineFound = FileExists(m_appOfflineLocation);
              if(m_fAppOfflineFound)
              {
                  LOG_IF_FAILED(OnAppOfflineFound());
              }
              m_ulLastCheckTime = ulCurrentTime;
          }
      }
  
      if (m_fAppOfflineFound != (m_mode == StopWhenRemoved))
      {
          Stop(/* fServerInitiated */ false);
      }
  }
  
  
  std::filesystem::path PollingAppOfflineApplication::GetAppOfflineLocation(const IHttpApplication& pApplication)
  {
      return std::filesystem::path(pApplication.GetApplicationPhysicalPath()) / "app_offline.htm";
  }
  
  bool PollingAppOfflineApplication::FileExists(const std::filesystem::path& path) noexcept
  {
      std::error_code ec;
      return is_regular_file(path, ec) || ec.value() == ERROR_SHARING_VIOLATION;
  }
  