support shutdown timeout for inprocess application (#703)
This commit is contained in:
parent
5baa53393f
commit
ffeebfc8b9
|
|
@ -21,6 +21,7 @@
|
|||
#define ASPNETCORE_EVENT_INVALID_STDOUT_LOG_FILE_MSG L"Warning: Could not create stdoutLogFile %s, ErrorCode = '0x%x'."
|
||||
#define ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE_MSG L"Failed to gracefully shutdown process '%d'."
|
||||
#define ASPNETCORE_EVENT_SENT_SHUTDOWN_HTTP_REQUEST_MSG L"Sent shutdown HTTP message to process '%d' and received http status '%d'."
|
||||
#define ASPNETCORE_EVENT_APP_SHUTDOWN_FAILURE_MSG L"Failed to gracefully shutdown application '%s'."
|
||||
#define ASPNETCORE_EVENT_LOAD_CLR_FALIURE_MSG L"Application '%s' with physical root '%s' failed to load clr and managed application, ErrorCode = '0x%x."
|
||||
#define ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP_MSG L"Only one inprocess application is allowed per IIS application pool. Please assign the application '%s' to a different IIS application pool."
|
||||
#define ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR_MSG L"Mixed hosting model is not supported. Application '%s' configured with different hostingModel value '%d' other than the one of running application(s)."
|
||||
|
|
|
|||
|
|
@ -40,9 +40,90 @@ IN_PROCESS_APPLICATION::~IN_PROCESS_APPLICATION()
|
|||
s_Application = NULL;
|
||||
}
|
||||
|
||||
//static
|
||||
VOID
|
||||
IN_PROCESS_APPLICATION::DoShutDown(
|
||||
LPVOID lpParam
|
||||
)
|
||||
{
|
||||
IN_PROCESS_APPLICATION* pApplication = static_cast<IN_PROCESS_APPLICATION*>(lpParam);
|
||||
DBG_ASSERT(pApplication);
|
||||
pApplication->ShutDownInternal();
|
||||
}
|
||||
|
||||
__override
|
||||
VOID
|
||||
IN_PROCESS_APPLICATION::ShutDown()
|
||||
IN_PROCESS_APPLICATION::ShutDown(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
HANDLE hThread = NULL;
|
||||
HRESULT hr = S_OK;
|
||||
DWORD dwThreadStatus = 0;
|
||||
DWORD dwTimeout = m_pConfig->QueryShutdownTimeLimitInMS();
|
||||
|
||||
if (IsDebuggerPresent())
|
||||
{
|
||||
dwTimeout = INFINITE;
|
||||
}
|
||||
|
||||
hThread = CreateThread(
|
||||
NULL, // default security attributes
|
||||
0, // default stack size
|
||||
(LPTHREAD_START_ROUTINE)DoShutDown,
|
||||
this, // thread function arguments
|
||||
0, // default creation flags
|
||||
NULL); // receive thread identifier
|
||||
|
||||
if (hThread == NULL)
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
if (WaitForSingleObject(hThread, dwTimeout) != WAIT_OBJECT_0)
|
||||
{
|
||||
// if the thread is still running, we need kill it first before exit to avoid AV
|
||||
if (GetExitCodeThread(m_hThread, &dwThreadStatus) != 0 && dwThreadStatus == STILL_ACTIVE)
|
||||
{
|
||||
// Calling back into managed at this point is prone to have AVs
|
||||
// Calling terminate thread here may be our best solution.
|
||||
TerminateThread(hThread, STATUS_CONTROL_C_EXIT);
|
||||
hr = HRESULT_FROM_WIN32(ERROR_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
Finished:
|
||||
|
||||
if (hThread != NULL)
|
||||
{
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
m_hThread = NULL;
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
STACK_STRU(strEventMsg, 256);
|
||||
//
|
||||
// Assumption: inprocess application shutdown will be called only at process shutdown
|
||||
// Based on this assumption, we just let shutdown continue and process will exit
|
||||
// Log a warning for ungraceful shutdown
|
||||
//
|
||||
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
|
||||
ASPNETCORE_EVENT_APP_SHUTDOWN_FAILURE_MSG,
|
||||
m_pConfig->QueryConfigPath()->QueryStr())))
|
||||
{
|
||||
UTILITY::LogEvent(g_hEventLog,
|
||||
EVENTLOG_WARNING_TYPE,
|
||||
ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE,
|
||||
strEventMsg.QueryStr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
IN_PROCESS_APPLICATION::ShutDownInternal()
|
||||
{
|
||||
DWORD dwThreadStatus = 0;
|
||||
DWORD dwTimeout = m_pConfig->QueryShutdownTimeLimitInMS();
|
||||
|
|
@ -54,10 +135,6 @@ IN_PROCESS_APPLICATION::ShutDown()
|
|||
{
|
||||
dwTimeout = INFINITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dwTimeout = m_pConfig->QueryShutdownTimeLimitInMS();
|
||||
}
|
||||
|
||||
if (m_fShutdownCalledFromNative ||
|
||||
m_status == APPLICATION_STATUS::STARTING ||
|
||||
|
|
|
|||
|
|
@ -99,6 +99,17 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
static
|
||||
VOID
|
||||
DoShutDown(
|
||||
LPVOID lpParam
|
||||
);
|
||||
|
||||
VOID
|
||||
ShutDownInternal(
|
||||
VOID
|
||||
);
|
||||
|
||||
// Thread executing the .NET Core process
|
||||
HANDLE m_hThread;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue