diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/sttimer.h b/src/AspNetCoreModuleV1/AspNetCore/Inc/sttimer.h index 1bd4b67543..dfb79e7a6a 100644 --- a/src/AspNetCoreModuleV1/AspNetCore/Inc/sttimer.h +++ b/src/AspNetCoreModuleV1/AspNetCore/Inc/sttimer.h @@ -22,9 +22,7 @@ public: if ( _pTimer ) { CancelTimer(); - CloseThreadpoolTimer( _pTimer ); - _pTimer = NULL; } } @@ -107,9 +105,10 @@ public: // have completed. // if (_pTimer != NULL) - WaitForThreadpoolTimerCallbacks( _pTimer, TRUE ); + { + WaitForThreadpoolTimerCallbacks(_pTimer, TRUE); + } - _pTimer = NULL; fInCanel = FALSE; } diff --git a/src/AspNetCoreModuleV2/AspNetCore/Inc/applicationmanager.h b/src/AspNetCoreModuleV2/AspNetCore/Inc/applicationmanager.h index 55c00a56e9..7201d7de49 100644 --- a/src/AspNetCoreModuleV2/AspNetCore/Inc/applicationmanager.h +++ b/src/AspNetCoreModuleV2/AspNetCore/Inc/applicationmanager.h @@ -79,18 +79,18 @@ public: ~APPLICATION_MANAGER() { + if (m_pFileWatcher != NULL) + { + delete m_pFileWatcher; + m_pFileWatcher = NULL; + } + if(m_pApplicationInfoHash != NULL) { m_pApplicationInfoHash->Clear(); delete m_pApplicationInfoHash; m_pApplicationInfoHash = NULL; } - - if( m_pFileWatcher!= NULL ) - { - delete m_pFileWatcher; - m_pFileWatcher = NULL; - } } FILE_WATCHER* diff --git a/src/AspNetCoreModuleV2/AspNetCore/src/applicationinfo.cpp b/src/AspNetCoreModuleV2/AspNetCore/src/applicationinfo.cpp index a7b96c4ddb..63efb9e889 100644 --- a/src/AspNetCoreModuleV2/AspNetCore/src/applicationinfo.cpp +++ b/src/AspNetCoreModuleV2/AspNetCore/src/applicationinfo.cpp @@ -18,6 +18,7 @@ APPLICATION_INFO::~APPLICATION_INFO() // the entry will delete itself when processing this FCN m_pFileWatcherEntry->MarkEntryInValid(); m_pFileWatcherEntry->StopMonitor(); + m_pFileWatcherEntry->DereferenceFileWatcherEntry(); m_pFileWatcherEntry = NULL; } @@ -587,6 +588,11 @@ APPLICATION_INFO::RecycleApplication() g_pHttpServer->RecycleProcess(L"On Demand by AspNetCore Module for recycle application failure"); } } + else + { + // Closing a thread handle does not terminate the associated thread or remove the thread object. + CloseHandle(hThread); + } if (fLockAcquired) { diff --git a/src/AspNetCoreModuleV2/AspNetCore/src/filewatcher.cxx b/src/AspNetCoreModuleV2/AspNetCore/src/filewatcher.cxx index d32aca37c0..4d3174937f 100644 --- a/src/AspNetCoreModuleV2/AspNetCore/src/filewatcher.cxx +++ b/src/AspNetCoreModuleV2/AspNetCore/src/filewatcher.cxx @@ -135,7 +135,6 @@ Win32 error INFINITE); DBG_ASSERT(fSuccess); - DebugPrint(1, "FILE_WATCHER::ChangeNotificationThread"); dwErrorStatus = fSuccess ? ERROR_SUCCESS : GetLastError(); if (completionKey == FILE_WATCHER_SHUTDOWN_KEY) @@ -186,7 +185,7 @@ None { FILE_WATCHER_ENTRY * pMonitorEntry; pMonitorEntry = CONTAINING_RECORD(pOverlapped, FILE_WATCHER_ENTRY, _overlapped); - pMonitorEntry->DereferenceFileWatcherEntry(); + DBG_ASSERT(pMonitorEntry != NULL); pMonitorEntry->HandleChangeCompletion(dwCompletionStatus, cbCompletion); @@ -198,14 +197,13 @@ None // pMonitorEntry->Monitor(); } - else - { - // - // Marked by application distructor - // Deference the entry to delete it - // - pMonitorEntry->DereferenceFileWatcherEntry(); - } + // + // Deference the counter not matter whether the monitor is valid + // Valid: Monitor increases the counter, need to reduce one + // InValid: Reduce the counter to free the entry + // + pMonitorEntry->DereferenceFileWatcherEntry(); + } @@ -279,9 +277,9 @@ HRESULT // From documentation it is not clear if that combination // of return values is specific to closing handles or whether // it could also mean an error condition. Hence we will maintain - // explicit flag that will help us determine if entry - // is being shutdown (StopMonitor() called) - // + // explicit flag that will help us determine if entry + // is being shutdown (StopMonitor() called) + // if (_lStopMonitorCalled) { goto Finished; @@ -364,6 +362,7 @@ FILE_WATCHER_ENTRY::Monitor(VOID) NULL)) { hr = HRESULT_FROM_WIN32(GetLastError()); + DereferenceFileWatcherEntry(); } ReleaseSRWLockExclusive(&_srwLock); @@ -380,15 +379,17 @@ FILE_WATCHER_ENTRY::StopMonitor(VOID) // InterlockedExchange(&_lStopMonitorCalled, 1); - AcquireSRWLockExclusive(&_srwLock); - if (_hDirectory != INVALID_HANDLE_VALUE) { - CloseHandle(_hDirectory); - _hDirectory = INVALID_HANDLE_VALUE; + AcquireSRWLockExclusive(&_srwLock); + if (_hDirectory != INVALID_HANDLE_VALUE) + { + CloseHandle(_hDirectory); + _hDirectory = INVALID_HANDLE_VALUE; + DereferenceFileWatcherEntry(); + } + ReleaseSRWLockExclusive(&_srwLock); } - - ReleaseSRWLockExclusive(&_srwLock); } HRESULT diff --git a/src/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.h b/src/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.h deleted file mode 100644 index ea975472ac..0000000000 --- a/src/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.h +++ /dev/null @@ -1,328 +0,0 @@ -/*++ - - Copyright (c) .NET Foundation. All rights reserved. - Licensed under the MIT License. See License.txt in the project root for license information. - -Module Name: - - aspnetcore_msg.mc - -Abstract: - - Asp.Net Core Module localizable messages. - ---*/ - - -#ifndef _ASPNETCORE_MSG_H_ -#define _ASPNETCORE_MSG_H_ - -// -// Values are 32 bit values laid out as follows: -// -// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 -// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 -// +---+-+-+-----------------------+-------------------------------+ -// |Sev|C|R| Facility | Code | -// +---+-+-+-----------------------+-------------------------------+ -// -// where -// -// Sev - is the severity code -// -// 00 - Success -// 01 - Informational -// 10 - Warning -// 11 - Error -// -// C - is the Customer code flag -// -// R - is a reserved bit -// -// Facility - is the facility code -// -// Code - is the facility's status code -// -// -// Define the facility codes -// - - -// -// Define the severity codes -// - - -// -// MessageId: ASPNETCORE_EVENT_PROCESS_START_ERROR -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_PROCESS_START_ERROR ((DWORD)0x000003E8L) - -// -// MessageId: ASPNETCORE_EVENT_PROCESS_START_SUCCESS -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_PROCESS_START_SUCCESS ((DWORD)0x000003E9L) - -// -// MessageId: ASPNETCORE_EVENT_PROCESS_CRASH -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_PROCESS_CRASH ((DWORD)0x000003EAL) - -// -// MessageId: ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED ((DWORD)0x000003EBL) - -// -// MessageId: ASPNETCORE_EVENT_CONFIG_ERROR -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_CONFIG_ERROR ((DWORD)0x000003ECL) - -// -// MessageId: ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE ((DWORD)0x000003EDL) - -// -// MessageId: ASPNETCORE_EVENT_SENT_SHUTDOWN_HTTP_REQUEST -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_SENT_SHUTDOWN_HTTP_REQUEST ((DWORD)0x000003EEL) - -// -// MessageId: ASPNETCORE_EVENT_LOAD_CLR_FALIURE -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_LOAD_CLR_FALIURE ((DWORD)0x000003EFL) - -// -// MessageId: ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_DUPLICATED_INPROCESS_APP ((DWORD)0x000003F0L) - -// -// MessageId: ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_MIXED_HOSTING_MODEL_ERROR ((DWORD)0x000003F1L) - -// -// MessageId: ASPNETCORE_EVENT_ADD_APPLICATION_ERROR -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_ADD_APPLICATION_ERROR ((DWORD)0x000003F2L) - -// -// MessageId: ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXIT ((DWORD)0x000003F3L) - -// -// MessageId: ASPNETCORE_EVENT_RECYCLE_APPOFFLINE -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_RECYCLE_APPOFFLINE ((DWORD)0x000003F4L) - -// -// MessageId: ASPNETCORE_EVENT_MODULE_DISABLED -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_MODULE_DISABLED ((DWORD)0x000003F5L) - -// -// MessageId: ASPNETCORE_EVENT_INPROCESS_FULL_FRAMEWORK_APP -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_INPROCESS_FULL_FRAMEWORK_APP ((DWORD)0x000003F6L) - -// -// MessageId: ASPNETCORE_EVENT_PORTABLE_APP_DOTNET_MISSING -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_PORTABLE_APP_DOTNET_MISSING ((DWORD)0x000003F7L) - -// -// MessageId: ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_HOSTFXR_DIRECTORY_NOT_FOUND ((DWORD)0x000003F8L) - -// -// MessageId: ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_HOSTFXR_DLL_NOT_FOUND ((DWORD)0x000003F9L) - -// -// MessageId: ASPNETCORE_EVENT_INPROCESS_THREAD_EXCEPTION -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXCEPTION ((DWORD)0x000003FAL) - -// -// MessageId: ASPNETCORE_EVENT_APPLICATION_EXE_NOT_FOUND -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_APPLICATION_EXE_NOT_FOUND ((DWORD)0x000003FBL) - -// -// MessageId: ASPNETCORE_EVENT_PROCESS_START_FAILURE -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_PROCESS_START_FAILURE ((DWORD)0x000003FCL) - -// -// MessageId: ASPNETCORE_EVENT_RECYCLE_CONFIGURATION -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_RECYCLE_CONFIGURATION ((DWORD)0x000003FDL) - -// -// MessageId: ASPNETCORE_EVENT_RECYCLE_APP_FAILURE -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_RECYCLE_APP_FAILURE ((DWORD)0x000003FEL) - -// -// MessageId: ASPNETCORE_EVENT_APP_IN_SHUTDOWN -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_APP_IN_SHUTDOWN ((DWORD)0x000003FFL) - -// -// MessageId: ASPNETCORE_EVENT_RECYCLE_APPOFFLINE_REMOVED -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_RECYCLE_APPOFFLINE_REMOVED ((DWORD)0x00000400L) - -// -// MessageId: ASPNETCORE_EVENT_GENERAL_INFO_MSG -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_GENERAL_INFO_MSG ((DWORD)0x00000401L) - -// -// MessageId: ASPNETCORE_EVENT_GENERAL_WARNING_MSG -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_GENERAL_WARNING_MSG ((DWORD)0x00000402L) - -// -// MessageId: ASPNETCORE_EVENT_GENERAL_ERROR_MSG -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_GENERAL_ERROR_MSG ((DWORD)0x00000403L) - -// -// MessageId: ASPNETCORE_EVENT_INPROCESS_RH_MISSING -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_INPROCESS_RH_MISSING ((DWORD)0x00000404L) - -// -// MessageId: ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING -// -// MessageText: -// -// %1 -// -#define ASPNETCORE_EVENT_OUT_OF_PROCESS_RH_MISSING ((DWORD)0x00000405L) - - -#endif // _ASPNETCORE_MODULE_MSG_H_ - diff --git a/src/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.mc b/src/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.mc index 860a78ffc6..96cf5fec0c 100644 --- a/src/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.mc +++ b/src/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.mc @@ -206,6 +206,12 @@ Language=English %1 . +Messageid=1030 +SymbolicName=ASPNETCORE_EVENT_PROCESS_SHUTDOWN +Language=English +%1 +. + ; ;#endif // _ASPNETCORE_MODULE_MSG_H_ ; diff --git a/src/AspNetCoreModuleV2/CommonLib/resources.h b/src/AspNetCoreModuleV2/CommonLib/resources.h index 36f252f5ac..140a573f3f 100644 --- a/src/AspNetCoreModuleV2/CommonLib/resources.h +++ b/src/AspNetCoreModuleV2/CommonLib/resources.h @@ -10,14 +10,15 @@ #define ASPNETCORE_IISEXPRESS_EVENT_PROVIDER L"IIS Express AspNetCore Module" #define ASPNETCORE_EVENT_MSG_BUFFER_SIZE 256 -#define ASPNETCORE_EVENT_PROCESS_START_SUCCESS_MSG L"Application '%s' started process '%d' successfully and is listening on port '%d'." +#define ASPNETCORE_EVENT_PROCESS_START_SUCCESS_MSG L"Application '%s' started process '%d' successfully and process '%d' is listening on port '%d'." #define ASPNETCORE_EVENT_RAPID_FAIL_COUNT_EXCEEDED_MSG L"Maximum rapid fail count per minute of '%d' exceeded." #define ASPNETCORE_EVENT_PROCESS_START_ERROR_MSG L"Application '%s' with physical root '%s' failed to start process with commandline '%s' at stage '%s', ErrorCode = '0x%x', assigned port %d, retryCounter '%d'." #define ASPNETCORE_EVENT_PROCESS_START_FAILURE_MSG L"Application '%s' with physical root '%s' failed to start process with commandline '%s' with multiple retries. The last try of listening port is '%d'. See pervious warnings for details." -#define ASPNETCORE_EVENT_PROCESS_START_STATUS_ERROR_MSG L"Application '%s' with physical root '%s' failed to start process with commandline '%s' , ErrorCode = '0x%x', processStatus '%d'." +#define ASPNETCORE_EVENT_PROCESS_START_STATUS_ERROR_MSG L"Application '%s' with physical root '%s' failed to start process with commandline '%s' , ErrorCode = '0x%x', processId '%d', processStatus '%d'." #define ASPNETCORE_EVENT_PROCESS_START_PORTSETUP_ERROR_MSG L"Application '%s' with physical root '%s' failed to choose listen port '%d' given port rang '%d - %d', EorrorCode = '0x%x'. If environment variable 'ASPNETCORE_PORT' was set, try removing it such that a random port is selected instead." #define ASPNETCORE_EVENT_PROCESS_START_WRONGPORT_ERROR_MSG L"Application '%s' with physical root '%s' created process with commandline '%s' but failed to listen on the given port '%d'" #define ASPNETCORE_EVENT_PROCESS_START_NOTREADY_ERROR_MSG L"Application '%s' with physical root '%s' created process with commandline '%s' but either crashed or did not respond or did not listen on the given port '%d', ErrorCode = '0x%x'" +#define ASPNETCORE_EVENT_PROCESS_SHUTDOWN_MSG L"Application '%s' with physical root '%s' shut down process with Id '%d' listening on port '%d'" #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'." diff --git a/src/AspNetCoreModuleV2/CommonLib/utility.cxx b/src/AspNetCoreModuleV2/CommonLib/utility.cxx index 9a857921df..cb762f21bc 100644 --- a/src/AspNetCoreModuleV2/CommonLib/utility.cxx +++ b/src/AspNetCoreModuleV2/CommonLib/utility.cxx @@ -642,7 +642,7 @@ UTILITY::LogEventF( STACK_STRU ( strEventMsg, 256 ); - if (SUCCEEDED(strEventMsg.SafeSnwprintf( + if (SUCCEEDED(strEventMsg.SafeVsnwprintf( pstrMsg, argsList))) { diff --git a/src/AspNetCoreModuleV2/RequestHandler/outofprocess/serverprocess.cxx b/src/AspNetCoreModuleV2/RequestHandler/outofprocess/serverprocess.cxx index 6d0a6de6aa..de309bf643 100644 --- a/src/AspNetCoreModuleV2/RequestHandler/outofprocess/serverprocess.cxx +++ b/src/AspNetCoreModuleV2/RequestHandler/outofprocess/serverprocess.cxx @@ -523,15 +523,20 @@ SERVER_PROCESS::PostStartCheck( // make sure the process is still running if (processStatus != STILL_ACTIVE) { - hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE; - strEventMsg.SafeSnwprintf( - ASPNETCORE_EVENT_PROCESS_START_STATUS_ERROR_MSG, - m_struAppFullPath.QueryStr(), - m_struPhysicalPath.QueryStr(), - m_struCommandLine.QueryStr(), - hr, - processStatus); - goto Finished; + // double check + if (GetExitCodeProcess(m_hProcessHandle, &processStatus) && processStatus != STILL_ACTIVE) + { + hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE; + strEventMsg.SafeSnwprintf( + ASPNETCORE_EVENT_PROCESS_START_STATUS_ERROR_MSG, + m_struAppFullPath.QueryStr(), + m_struPhysicalPath.QueryStr(), + m_struCommandLine.QueryStr(), + hr, + m_dwProcessId, + processStatus); + goto Finished; + } } } // @@ -552,6 +557,7 @@ SERVER_PROCESS::PostStartCheck( if (!fReady) { hr = E_APPLICATION_ACTIVATION_TIMED_OUT; + goto Finished; } // register call back with the created process @@ -569,6 +575,7 @@ SERVER_PROCESS::PostStartCheck( // some error occurred - assume debugger is not attached; fDebuggerAttached = FALSE; } + if (!g_fNsiApiNotSupported) { // @@ -720,11 +727,14 @@ Finished: m_pForwarderConnection = NULL; } - UTILITY::LogEvent( - g_hEventLog, - EVENTLOG_WARNING_TYPE, - ASPNETCORE_EVENT_PROCESS_START_ERROR, - strEventMsg.QueryStr()); + if (!strEventMsg.IsEmpty()) + { + UTILITY::LogEvent( + g_hEventLog, + EVENTLOG_WARNING_TYPE, + ASPNETCORE_EVENT_PROCESS_START_ERROR, + strEventMsg.QueryStr()); + } } return hr; } @@ -890,6 +900,7 @@ SERVER_PROCESS::StartProcess( ASPNETCORE_EVENT_PROCESS_START_SUCCESS_MSG, m_struAppFullPath.QueryStr(), m_dwProcessId, + m_dwListeningProcessId, m_dwPort); goto Finished; @@ -1104,10 +1115,10 @@ SERVER_PROCESS::CheckIfServerIsUp( ) { HRESULT hr = S_OK; - DWORD dwResult = 0; + DWORD dwResult = ERROR_INSUFFICIENT_BUFFER; MIB_TCPTABLE_OWNER_PID *pTCPInfo = NULL; MIB_TCPROW_OWNER_PID *pOwner = NULL; - DWORD dwSize = 0; + DWORD dwSize = 1000; // Initial size for pTCPInfo buffer int iResult = 0; SOCKADDR_IN sockAddr; SOCKET socketCheck = INVALID_SOCKET; @@ -1123,36 +1134,36 @@ SERVER_PROCESS::CheckIfServerIsUp( if (!g_fNsiApiNotSupported) { - dwResult = GetExtendedTcpTable(NULL, - &dwSize, - FALSE, - AF_INET, - TCP_TABLE_OWNER_PID_LISTENER, - 0); - - if (dwResult != NO_ERROR && dwResult != ERROR_INSUFFICIENT_BUFFER) + while (dwResult == ERROR_INSUFFICIENT_BUFFER) { - hr = HRESULT_FROM_WIN32(dwResult); - goto Finished; - } + // Increase the buffer size with additional space, MIB_TCPROW 20 bytes + // New entries may be added by other processes before calling GetExtendedTcpTable + dwSize += 200; - pTCPInfo = (MIB_TCPTABLE_OWNER_PID*)HeapAlloc(GetProcessHeap(), 0, dwSize); - if (pTCPInfo == NULL) - { - hr = E_OUTOFMEMORY; - goto Finished; - } + if (pTCPInfo != NULL) + { + HeapFree(GetProcessHeap(), 0, pTCPInfo); + } - dwResult = GetExtendedTcpTable(pTCPInfo, - &dwSize, - FALSE, - AF_INET, - TCP_TABLE_OWNER_PID_LISTENER, - 0); - if (dwResult != NO_ERROR) - { - hr = HRESULT_FROM_WIN32(dwResult); - goto Finished; + pTCPInfo = (MIB_TCPTABLE_OWNER_PID*)HeapAlloc(GetProcessHeap(), 0, dwSize); + if (pTCPInfo == NULL) + { + hr = E_OUTOFMEMORY; + goto Finished; + } + + dwResult = GetExtendedTcpTable(pTCPInfo, + &dwSize, + FALSE, + AF_INET, + TCP_TABLE_OWNER_PID_LISTENER, + 0); + + if (dwResult != NO_ERROR && dwResult != ERROR_INSUFFICIENT_BUFFER) + { + hr = HRESULT_FROM_WIN32(dwResult); + goto Finished; + } } // iterate pTcpInfo struct to find PID/PORT entry @@ -1199,6 +1210,12 @@ SERVER_PROCESS::CheckIfServerIsUp( if (iResult == SOCKET_ERROR) { hr = HRESULT_FROM_WIN32(WSAGetLastError()); + if (hr == HRESULT_FROM_WIN32(WSAECONNREFUSED)) + { + // WSAECONNREFUSED means no application listen on the given port. + // This is not a failure. Reset the hresult to S_OK and return fReady to false + hr = S_OK; + } goto Finished; } *pfReady = TRUE; @@ -1860,25 +1877,33 @@ Finished: return hr; } -HRESULT +VOID SERVER_PROCESS::HandleProcessExit( VOID ) { - HRESULT hr = S_OK; BOOL fReady = FALSE; DWORD dwProcessId = 0; + if (InterlockedCompareExchange(&m_lStopping, 1L, 0L) == 0L) { CheckIfServerIsUp(m_dwPort, &dwProcessId, &fReady); if (!fReady) { + UTILITY::LogEventF( + g_hEventLog, + EVENTLOG_INFORMATION_TYPE, + ASPNETCORE_EVENT_PROCESS_SHUTDOWN, + ASPNETCORE_EVENT_PROCESS_SHUTDOWN_MSG, + m_struAppFullPath.QueryStr(), + m_struPhysicalPath.QueryStr(), + m_dwProcessId, + m_dwPort); + m_pProcessManager->ShutdownProcess(this); } DereferenceServerProcess(); } - - return hr; } HRESULT diff --git a/src/AspNetCoreModuleV2/RequestHandler/outofprocess/serverprocess.h b/src/AspNetCoreModuleV2/RequestHandler/outofprocess/serverprocess.h index cef9446c15..ff76297a1c 100644 --- a/src/AspNetCoreModuleV2/RequestHandler/outofprocess/serverprocess.h +++ b/src/AspNetCoreModuleV2/RequestHandler/outofprocess/serverprocess.h @@ -99,7 +99,7 @@ public: _In_ BOOL ); - HRESULT + VOID HandleProcessExit( VOID );