diff --git a/src/AspNetCoreModuleV2/AspNetCore/ServerErrorApplication.h b/src/AspNetCoreModuleV2/AspNetCore/ServerErrorApplication.h index 1872675656..2162075950 100644 --- a/src/AspNetCoreModuleV2/AspNetCore/ServerErrorApplication.h +++ b/src/AspNetCoreModuleV2/AspNetCore/ServerErrorApplication.h @@ -13,7 +13,6 @@ public: : m_HR(hr), PollingAppOfflineApplication(pApplication, PollingAppOfflineApplicationMode::StopWhenAdded) { - m_status = APPLICATION_STATUS::RUNNING; } ~ServerErrorApplication() = default; diff --git a/src/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp b/src/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp index 307d669dbf..8f94f23b08 100644 --- a/src/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp +++ b/src/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp @@ -54,7 +54,7 @@ APPLICATION_INFO::GetOrCreateApplication( ) { HRESULT hr = S_OK; - + SRWExclusiveLock lock(m_applicationLock); auto& httpApplication = *pHttpContext->GetApplication(); @@ -72,7 +72,7 @@ APPLICATION_INFO::GetOrCreateApplication( else { // another thread created the application - FINISHED(S_OK); + FINISHED(S_OK); } } @@ -124,7 +124,7 @@ Finished: if (m_pApplication) { - pApplication = ReferenceApplication(m_pApplication.get()); + pApplication = ReferenceApplication(m_pApplication.get()); } return hr; @@ -410,7 +410,7 @@ APPLICATION_INFO::RecycleApplication() } -DWORD WINAPI +DWORD WINAPI APPLICATION_INFO::DoRecycleApplication( LPVOID lpParam) { diff --git a/src/AspNetCoreModuleV2/AspNetCore/proxymodule.cpp b/src/AspNetCoreModuleV2/AspNetCore/proxymodule.cpp index 0ed100fd47..1f0ed72db1 100644 --- a/src/AspNetCoreModuleV2/AspNetCore/proxymodule.cpp +++ b/src/AspNetCoreModuleV2/AspNetCore/proxymodule.cpp @@ -95,20 +95,12 @@ ASPNET_CORE_PROXY_MODULE::OnExecuteRequestHandler( // the error should already been logged to window event log for the first request FINISHED(E_APPLICATION_ACTIVATION_EXEC_FAILURE); } - + DBG_ASSERT(pHttpContext); std::unique_ptr pApplication; FINISHED_IF_FAILED(m_pApplicationInfo->GetOrCreateApplication(pHttpContext, pApplication)); - // We allow RECYCLED application to serve pages - if (pApplication->QueryStatus() != APPLICATION_STATUS::RUNNING && - pApplication->QueryStatus() != APPLICATION_STATUS::STARTING && - pApplication->QueryStatus() != APPLICATION_STATUS::RECYCLED) - { - FINISHED(HRESULT_FROM_WIN32(ERROR_SERVER_DISABLED)); - } - IREQUEST_HANDLER* pHandler; // Create RequestHandler and process the request FINISHED_IF_FAILED(pApplication->CreateHandler(pHttpContext, &pHandler)); diff --git a/src/AspNetCoreModuleV2/CommonLib/AppOfflineApplication.h b/src/AspNetCoreModuleV2/CommonLib/AppOfflineApplication.h index f6ec00cab0..71f79e5294 100644 --- a/src/AspNetCoreModuleV2/CommonLib/AppOfflineApplication.h +++ b/src/AspNetCoreModuleV2/CommonLib/AppOfflineApplication.h @@ -13,6 +13,7 @@ public: AppOfflineApplication(IHttpApplication& pApplication) : PollingAppOfflineApplication(pApplication, PollingAppOfflineApplicationMode::StopWhenRemoved) { + CheckAppOffline(); } HRESULT CreateHandler(IHttpContext* pHttpContext, IREQUEST_HANDLER** pRequestHandler) override; diff --git a/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.cpp b/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.cpp index 1468c7ee37..08491b0d76 100644 --- a/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.cpp +++ b/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.cpp @@ -9,11 +9,12 @@ APPLICATION_STATUS PollingAppOfflineApplication::QueryStatus() { - return (AppOfflineExists() == (m_mode == StopWhenRemoved)) ? APPLICATION_STATUS::RUNNING : APPLICATION_STATUS::RECYCLED; + CheckAppOffline(); + return APPLICATION::QueryStatus(); } -bool -PollingAppOfflineApplication::AppOfflineExists() +void +PollingAppOfflineApplication::CheckAppOffline() { const auto ulCurrentTime = GetTickCount64(); // @@ -29,12 +30,16 @@ PollingAppOfflineApplication::AppOfflineExists() m_fAppOfflineFound = is_regular_file(m_appOfflineLocation); if(m_fAppOfflineFound) { - LOG_IF_FAILED(OnAppOfflineFound()); + LOG_IF_FAILED(OnAppOfflineFound()); } m_ulLastCheckTime = ulCurrentTime; } } - return m_fAppOfflineFound; + + if (m_fAppOfflineFound != (m_mode == StopWhenRemoved)) + { + Stop(/* fServerInitiated */ false); + } } diff --git a/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.h b/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.h index 48e71f6641..98d32ae8d3 100644 --- a/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.h +++ b/src/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.h @@ -25,9 +25,9 @@ public: } APPLICATION_STATUS QueryStatus() override; - bool AppOfflineExists(); + void CheckAppOffline(); virtual HRESULT OnAppOfflineFound() = 0; - void Stop(bool fServerInitiated) override { UNREFERENCED_PARAMETER(fServerInitiated); } + void StopInternal(bool fServerInitiated) override { UNREFERENCED_PARAMETER(fServerInitiated); } protected: std::experimental::filesystem::path m_appOfflineLocation; @@ -36,7 +36,7 @@ protected: private: static const int c_appOfflineRefreshIntervalMS = 200; std::string m_strAppOfflineContent; - ULONGLONG m_ulLastCheckTime; + ULONGLONG m_ulLastCheckTime; bool m_fAppOfflineFound; SRWLOCK m_statusLock {}; PollingAppOfflineApplicationMode m_mode; diff --git a/src/AspNetCoreModuleV2/CommonLib/application.h b/src/AspNetCoreModuleV2/CommonLib/application.h index 1bc3d02f37..1167602327 100644 --- a/src/AspNetCoreModuleV2/CommonLib/application.h +++ b/src/AspNetCoreModuleV2/CommonLib/application.h @@ -7,11 +7,10 @@ #include "exceptions.h" #include "utility.h" #include "ntassert.h" - +#include "SRWExclusiveLock.h" class APPLICATION : public IAPPLICATION { - public: // Non-copyable APPLICATION(const APPLICATION&) = delete; @@ -20,24 +19,38 @@ public: APPLICATION_STATUS QueryStatus() override { - return m_status; + return m_fStopCalled ? APPLICATION_STATUS::RECYCLED : APPLICATION_STATUS::RUNNING; } APPLICATION() - : m_cRefs(1) + : m_fStopCalled(false), + m_cRefs(1) { InitializeSRWLock(&m_stateLock); } - + VOID Stop(bool fServerInitiated) override { - UNREFERENCED_PARAMETER(fServerInitiated); + SRWExclusiveLock stopLock(m_stateLock); + + if (m_fStopCalled) + { + return; + } m_fStopCalled = true; + + StopInternal(fServerInitiated); + } + + virtual + VOID + StopInternal(bool fServerInitiated) + { + UNREFERENCED_PARAMETER(fServerInitiated); } - VOID ReferenceApplication() override @@ -59,11 +72,9 @@ public: } protected: - volatile APPLICATION_STATUS m_status = APPLICATION_STATUS::UNKNOWN; SRWLOCK m_stateLock; - bool m_fStopCalled; + bool m_fStopCalled; private: - - mutable LONG m_cRefs; + mutable LONG m_cRefs; }; diff --git a/src/AspNetCoreModuleV2/CommonLib/iapplication.h b/src/AspNetCoreModuleV2/CommonLib/iapplication.h index cdfd17ec03..1f69a39bbb 100644 --- a/src/AspNetCoreModuleV2/CommonLib/iapplication.h +++ b/src/AspNetCoreModuleV2/CommonLib/iapplication.h @@ -8,12 +8,8 @@ enum APPLICATION_STATUS { - UNKNOWN = 0, - STARTING, RUNNING, - SHUTDOWN, RECYCLED, - FAIL }; struct APPLICATION_PARAMETER diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.cpp b/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.cpp index 3152b75cca..0abdc42025 100644 --- a/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.cpp +++ b/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.cpp @@ -15,9 +15,9 @@ InProcessApplicationBase::InProcessApplicationBase( } VOID -InProcessApplicationBase::Stop(bool fServerInitiated) +InProcessApplicationBase::StopInternal(bool fServerInitiated) { - AppOfflineTrackingApplication::Stop(fServerInitiated); + AppOfflineTrackingApplication::StopInternal(fServerInitiated); // Stop was initiated by server no need to do anything, server would stop on it's own if (fServerInitiated) diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.h b/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.h index 5df37d34b6..bb343725f5 100644 --- a/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.h +++ b/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.h @@ -18,7 +18,7 @@ public: ~InProcessApplicationBase() = default; - VOID Stop(bool fServerInitiated) override; + VOID StopInternal(bool fServerInitiated) override; protected: BOOL m_fRecycleCalled; diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/ShuttingDownApplication.h b/src/AspNetCoreModuleV2/InProcessRequestHandler/ShuttingDownApplication.h index 4528a3f2b4..6195877234 100644 --- a/src/AspNetCoreModuleV2/InProcessRequestHandler/ShuttingDownApplication.h +++ b/src/AspNetCoreModuleV2/InProcessRequestHandler/ShuttingDownApplication.h @@ -32,7 +32,6 @@ public: ShuttingDownApplication(IHttpServer& pHttpServer, IHttpApplication& pHttpApplication) : InProcessApplicationBase(pHttpServer, pHttpApplication) { - m_status = APPLICATION_STATUS::RUNNING; } ~ShuttingDownApplication() = default; diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/StartupExceptionApplication.h b/src/AspNetCoreModuleV2/InProcessRequestHandler/StartupExceptionApplication.h index 14d26bf3a4..369c57adfe 100644 --- a/src/AspNetCoreModuleV2/InProcessRequestHandler/StartupExceptionApplication.h +++ b/src/AspNetCoreModuleV2/InProcessRequestHandler/StartupExceptionApplication.h @@ -16,7 +16,6 @@ public: : m_disableLogs(disableLogs), InProcessApplicationBase(pServer, pApplication) { - m_status = APPLICATION_STATUS::RUNNING; html500Page = std::string(" \ \ \ diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp b/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp index 575d9180e4..7207f745c3 100644 --- a/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp +++ b/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp @@ -23,7 +23,6 @@ IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION( APPLICATION_PARAMETER *pParameters, DWORD nParameters) : InProcessApplicationBase(pHttpServer, pApplication), - m_pHttpServer(pHttpServer), m_ProcessExitCode(0), m_fBlockCallbacksIntoManaged(FALSE), m_fShutdownCalledFromNative(FALSE), @@ -40,7 +39,7 @@ IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION( } } - m_status = APPLICATION_STATUS::STARTING; + m_status = MANAGED_APPLICATION_STATUS::STARTING; } IN_PROCESS_APPLICATION::~IN_PROCESS_APPLICATION() @@ -63,22 +62,13 @@ IN_PROCESS_APPLICATION::DoShutDown( __override VOID -IN_PROCESS_APPLICATION::Stop(bool fServerInitiated) +IN_PROCESS_APPLICATION::StopInternal(bool fServerInitiated) { UNREFERENCED_PARAMETER(fServerInitiated); HRESULT hr = S_OK; CHandle hThread; DWORD dwThreadStatus = 0; - SRWExclusiveLock stopLock(m_stateLock); - - if (m_fStopCalled) - { - return; - } - - AppOfflineTrackingApplication::Stop(fServerInitiated); - DWORD dwTimeout = m_pConfig->QueryShutdownTimeLimitInMS(); if (IsDebuggerPresent()) @@ -137,7 +127,7 @@ Finished: m_pConfig->QueryConfigPath()->QueryStr()); } - InProcessApplicationBase::Stop(fServerInitiated); + InProcessApplicationBase::StopInternal(fServerInitiated); } VOID @@ -152,16 +142,16 @@ IN_PROCESS_APPLICATION::ShutDownInternal() } if (m_fShutdownCalledFromNative || - m_status == APPLICATION_STATUS::STARTING || - m_status == APPLICATION_STATUS::FAIL) + m_status == MANAGED_APPLICATION_STATUS::STARTING || + m_status == MANAGED_APPLICATION_STATUS::FAIL) { return; } { if (m_fShutdownCalledFromNative || - m_status == APPLICATION_STATUS::STARTING || - m_status == APPLICATION_STATUS::FAIL) + m_status == MANAGED_APPLICATION_STATUS::STARTING || + m_status == MANAGED_APPLICATION_STATUS::FAIL) { return; } @@ -171,7 +161,7 @@ IN_PROCESS_APPLICATION::ShutDownInternal() // managed. We still need to wait on main exiting no matter what. m_fShutdownCalledFromNative // is used for detecting redundant calls and blocking more requests to OnExecuteRequestHandler. m_fShutdownCalledFromNative = TRUE; - m_status = APPLICATION_STATUS::RECYCLED; + m_status = MANAGED_APPLICATION_STATUS::SHUTDOWN; if (!m_fShutdownCalledFromManaged) { @@ -249,18 +239,18 @@ IN_PROCESS_APPLICATION::LoadManagedApplication HRESULT hr = S_OK; DWORD dwTimeout; DWORD dwResult; - + ReferenceApplication(); - if (m_status != APPLICATION_STATUS::STARTING) + if (m_status != MANAGED_APPLICATION_STATUS::STARTING) { // Core CLR has already been loaded. // Cannot load more than once even there was a failure - if (m_status == APPLICATION_STATUS::FAIL) + if (m_status == MANAGED_APPLICATION_STATUS::FAIL) { hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE; } - else if (m_status == APPLICATION_STATUS::SHUTDOWN) + else if (m_status == MANAGED_APPLICATION_STATUS::SHUTDOWN) { hr = HRESULT_FROM_WIN32(ERROR_SHUTDOWN_IS_SCHEDULED); } @@ -289,13 +279,13 @@ IN_PROCESS_APPLICATION::LoadManagedApplication LOG_IF_FAILED(m_pLoggerProvider->Start()); } - if (m_status != APPLICATION_STATUS::STARTING) + if (m_status != MANAGED_APPLICATION_STATUS::STARTING) { - if (m_status == APPLICATION_STATUS::FAIL) + if (m_status == MANAGED_APPLICATION_STATUS::FAIL) { hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE; } - else if (m_status == APPLICATION_STATUS::SHUTDOWN) + else if (m_status == MANAGED_APPLICATION_STATUS::SHUTDOWN) { hr = HRESULT_FROM_WIN32(ERROR_SHUTDOWN_IS_SCHEDULED); } @@ -363,13 +353,13 @@ IN_PROCESS_APPLICATION::LoadManagedApplication goto Finished; } - m_status = APPLICATION_STATUS::RUNNING; + m_status = MANAGED_APPLICATION_STATUS::RUNNING_MANAGED; } Finished: if (FAILED(hr)) { - m_status = APPLICATION_STATUS::FAIL; + m_status = MANAGED_APPLICATION_STATUS::FAIL; UTILITY::LogEventF(g_hEventLog, EVENTLOG_ERROR_TYPE, @@ -444,7 +434,7 @@ IN_PROCESS_APPLICATION::ExecuteApplication( hostfxr_main_fn pProc; std::unique_ptr hostFxrOptions = NULL; - DBG_ASSERT(m_status == APPLICATION_STATUS::STARTING); + DBG_ASSERT(m_status == MANAGED_APPLICATION_STATUS::STARTING); pProc = s_fMainCallback; if (pProc == nullptr) @@ -502,7 +492,7 @@ Finished: // Don't bother locking here as there will always be a race between receiving a native shutdown // notification and unexpected managed exit. // - m_status = APPLICATION_STATUS::SHUTDOWN; + m_status = MANAGED_APPLICATION_STATUS::SHUTDOWN; m_fShutdownCalledFromManaged = TRUE; FreeLibrary(hModule); m_pLoggerProvider->Stop(); @@ -575,12 +565,12 @@ IN_PROCESS_APPLICATION::RunDotnetApplication(DWORD argc, CONST PCWSTR* argv, hos { hr = HRESULT_FROM_WIN32(GetLastError()); } - + LOG_INFOF("Managed application exited with code %d", m_ProcessExitCode); } __except(GetExceptionCode() != 0) { - + LOG_INFOF("Managed threw an exception %d", GetExceptionCode()); hr = HRESULT_FROM_WIN32(GetLastError()); } diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h b/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h index a18d85a617..8993d7fc8e 100644 --- a/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h +++ b/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h @@ -26,7 +26,7 @@ public: __override VOID - Stop(bool fServerInitiated) override; + StopInternal(bool fServerInitiated) override; VOID SetCallbackHandles( @@ -111,7 +111,14 @@ public: private: - IHttpServer & m_pHttpServer; + enum MANAGED_APPLICATION_STATUS + { + UNKNOWN = 0, + STARTING, + RUNNING_MANAGED, + SHUTDOWN, + FAIL + }; // Thread executing the .NET Core process HANDLE m_hThread; @@ -138,6 +145,7 @@ private: volatile BOOL m_fShutdownCalledFromNative; volatile BOOL m_fShutdownCalledFromManaged; BOOL m_fInitialized; + MANAGED_APPLICATION_STATUS m_status; std::unique_ptr m_pConfig; static IN_PROCESS_APPLICATION* s_Application; diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.cpp b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.cpp index 41835538a9..564adea383 100644 --- a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.cpp +++ b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.cpp @@ -12,7 +12,6 @@ OUT_OF_PROCESS_APPLICATION::OUT_OF_PROCESS_APPLICATION( m_fWebSocketSupported(WEBSOCKET_STATUS::WEBSOCKET_UNKNOWN), m_pConfig(std::move(pConfig)) { - m_status = APPLICATION_STATUS::RUNNING; m_pProcessManager = NULL; } @@ -62,16 +61,9 @@ OUT_OF_PROCESS_APPLICATION::GetProcess( __override VOID -OUT_OF_PROCESS_APPLICATION::Stop(bool fServerInitiated) -{ - SRWExclusiveLock lock(m_stateLock); - - if (m_fStopCalled) - { - return; - } - - AppOfflineTrackingApplication::Stop(fServerInitiated); +OUT_OF_PROCESS_APPLICATION::StopInternal(bool fServerInitiated) +{ + AppOfflineTrackingApplication::StopInternal(fServerInitiated); if (m_pProcessManager != NULL) { diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.h b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.h index 6ac813f6a7..43eca31f95 100644 --- a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.h +++ b/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.h @@ -32,7 +32,7 @@ public: __override VOID - Stop(bool fServerInitiated) + StopInternal(bool fServerInitiated) override; __override diff --git a/src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.cpp b/src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.cpp index ed465eb7c1..47a92d3daa 100644 --- a/src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.cpp +++ b/src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.cpp @@ -6,8 +6,6 @@ #include "EventLog.h" #include "exceptions.h" -extern HANDLE g_hEventLog; - HRESULT AppOfflineTrackingApplication::StartMonitoringAppOffline() { LOG_INFOF("Starting app_offline monitoring in application %S", m_applicationPath.c_str()); @@ -26,11 +24,9 @@ HRESULT AppOfflineTrackingApplication::StartMonitoringAppOffline() return hr; } -void AppOfflineTrackingApplication::Stop(bool fServerInitiated) +void AppOfflineTrackingApplication::StopInternal(bool fServerInitiated) { - APPLICATION::Stop(fServerInitiated); - - m_status = APPLICATION_STATUS::RECYCLED; + APPLICATION::StopInternal(fServerInitiated); if (m_fileWatcher) { diff --git a/src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.h b/src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.h index f104370c72..f2ce7a5c20 100644 --- a/src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.h +++ b/src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.h @@ -12,7 +12,8 @@ class AppOfflineTrackingApplication: public APPLICATION { public: AppOfflineTrackingApplication(const IHttpApplication& application) - : m_applicationPath(application.GetApplicationPhysicalPath()), + : APPLICATION(), + m_applicationPath(application.GetApplicationPhysicalPath()), m_fileWatcher(nullptr), m_fAppOfflineProcessed(false) { @@ -23,15 +24,15 @@ public: if (m_fileWatcher) { m_fileWatcher->StopMonitor(); - } + } }; HRESULT StartMonitoringAppOffline(); VOID - Stop(bool fServerInitiated) override; - + StopInternal(bool fServerInitiated) override; + virtual VOID OnAppOffline();