CPP
This commit is contained in:
parent
6e54256fca
commit
d63e8c5558
|
|
@ -179,6 +179,7 @@
|
||||||
<ClInclude Include="hostfxr_utility.h" />
|
<ClInclude Include="hostfxr_utility.h" />
|
||||||
<ClInclude Include="requesthandler.h" />
|
<ClInclude Include="requesthandler.h" />
|
||||||
<ClInclude Include="resources.h" />
|
<ClInclude Include="resources.h" />
|
||||||
|
<ClInclude Include="SRWLockWrapper.h" />
|
||||||
<ClInclude Include="stdafx.h" />
|
<ClInclude Include="stdafx.h" />
|
||||||
<ClInclude Include="utility.h" />
|
<ClInclude Include="utility.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
@ -188,6 +189,7 @@
|
||||||
<ClCompile Include="fx_ver.cxx" />
|
<ClCompile Include="fx_ver.cxx" />
|
||||||
<ClCompile Include="hostfxr_utility.cpp" />
|
<ClCompile Include="hostfxr_utility.cpp" />
|
||||||
<ClCompile Include="requesthandler.cxx" />
|
<ClCompile Include="requesthandler.cxx" />
|
||||||
|
<ClCompile Include="SRWLockWrapper.cpp" />
|
||||||
<ClCompile Include="stdafx.cpp">
|
<ClCompile Include="stdafx.cpp">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "SRWLockWrapper.h"
|
||||||
|
|
||||||
|
SRWLockWrapper::SRWLockWrapper(const SRWLOCK& lock)
|
||||||
|
: m_lock(lock)
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive(const_cast<SRWLOCK*>(&m_lock));
|
||||||
|
}
|
||||||
|
|
||||||
|
SRWLockWrapper::~SRWLockWrapper()
|
||||||
|
{
|
||||||
|
ReleaseSRWLockExclusive(const_cast<SRWLOCK*>(&m_lock));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
class SRWLockWrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SRWLockWrapper(const SRWLOCK& lock);
|
||||||
|
~SRWLockWrapper();
|
||||||
|
private:
|
||||||
|
const SRWLOCK& m_lock;
|
||||||
|
};
|
||||||
|
|
@ -7,10 +7,10 @@ APPLICATION::APPLICATION(
|
||||||
_In_ IHttpServer* pHttpServer,
|
_In_ IHttpServer* pHttpServer,
|
||||||
_In_ ASPNETCORE_CONFIG* pConfig) :
|
_In_ ASPNETCORE_CONFIG* pConfig) :
|
||||||
m_cRefs(1),
|
m_cRefs(1),
|
||||||
m_pHttpServer(pHttpServer),
|
|
||||||
m_pConfig(pConfig),
|
m_pConfig(pConfig),
|
||||||
m_status(APPLICATION_STATUS::UNKNOWN)
|
m_status(APPLICATION_STATUS::UNKNOWN)
|
||||||
{
|
{
|
||||||
|
UNREFERENCED_PARAMETER(pHttpServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
APPLICATION::~APPLICATION()
|
APPLICATION::~APPLICATION()
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ class APPLICATION
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
APPLICATION(
|
APPLICATION(
|
||||||
_In_ IHttpServer* pHttpServer,
|
_In_ IHttpServer* pHttpServer,
|
||||||
_In_ ASPNETCORE_CONFIG* pConfig);
|
_In_ ASPNETCORE_CONFIG* pConfig);
|
||||||
|
|
||||||
virtual
|
virtual
|
||||||
|
|
@ -49,6 +49,5 @@ public:
|
||||||
protected:
|
protected:
|
||||||
mutable LONG m_cRefs;
|
mutable LONG m_cRefs;
|
||||||
volatile APPLICATION_STATUS m_status;
|
volatile APPLICATION_STATUS m_status;
|
||||||
IHttpServer* m_pHttpServer;
|
|
||||||
ASPNETCORE_CONFIG* m_pConfig;
|
ASPNETCORE_CONFIG* m_pConfig;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include "..\IISLib\dbgutil.h"
|
#include "..\IISLib\dbgutil.h"
|
||||||
#include "..\IISLib\ahutil.h"
|
#include "..\IISLib\ahutil.h"
|
||||||
#include "..\IISLib\hashfn.h"
|
#include "..\IISLib\hashfn.h"
|
||||||
|
#include "SRWLockWrapper.h"
|
||||||
#include "environmentvariablehash.h"
|
#include "environmentvariablehash.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "aspnetcoreconfig.h"
|
#include "aspnetcoreconfig.h"
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION(
|
||||||
IHttpServer* pHttpServer,
|
IHttpServer* pHttpServer,
|
||||||
ASPNETCORE_CONFIG* pConfig) :
|
ASPNETCORE_CONFIG* pConfig) :
|
||||||
APPLICATION(pHttpServer, pConfig),
|
APPLICATION(pHttpServer, pConfig),
|
||||||
|
m_pHttpServer(pHttpServer),
|
||||||
m_ProcessExitCode(0),
|
m_ProcessExitCode(0),
|
||||||
m_hLogFileHandle(INVALID_HANDLE_VALUE),
|
m_hLogFileHandle(INVALID_HANDLE_VALUE),
|
||||||
m_hErrReadPipe(INVALID_HANDLE_VALUE),
|
m_hErrReadPipe(INVALID_HANDLE_VALUE),
|
||||||
|
|
@ -15,7 +16,8 @@ IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION(
|
||||||
m_fBlockCallbacksIntoManaged(FALSE),
|
m_fBlockCallbacksIntoManaged(FALSE),
|
||||||
m_fInitialized(FALSE),
|
m_fInitialized(FALSE),
|
||||||
m_fShutdownCalledFromNative(FALSE),
|
m_fShutdownCalledFromNative(FALSE),
|
||||||
m_fShutdownCalledFromManaged(FALSE)
|
m_fShutdownCalledFromManaged(FALSE),
|
||||||
|
m_srwLock()
|
||||||
{
|
{
|
||||||
// is it guaranteed that we have already checked app offline at this point?
|
// is it guaranteed that we have already checked app offline at this point?
|
||||||
// If so, I don't think there is much to do here.
|
// If so, I don't think there is much to do here.
|
||||||
|
|
@ -57,8 +59,8 @@ IN_PROCESS_APPLICATION::ShutDown(
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
HANDLE hThread = NULL;
|
HRESULT hr = S_OK;
|
||||||
HRESULT hr = S_OK;
|
CHandle hThread;
|
||||||
DWORD dwThreadStatus = 0;
|
DWORD dwThreadStatus = 0;
|
||||||
DWORD dwTimeout = m_pConfig->QueryShutdownTimeLimitInMS();
|
DWORD dwTimeout = m_pConfig->QueryShutdownTimeLimitInMS();
|
||||||
|
|
||||||
|
|
@ -67,15 +69,15 @@ IN_PROCESS_APPLICATION::ShutDown(
|
||||||
dwTimeout = INFINITE;
|
dwTimeout = INFINITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
hThread = CreateThread(
|
hThread.Attach(CreateThread(
|
||||||
NULL, // default security attributes
|
NULL, // default security attributes
|
||||||
0, // default stack size
|
0, // default stack size
|
||||||
(LPTHREAD_START_ROUTINE)DoShutDown,
|
(LPTHREAD_START_ROUTINE)DoShutDown,
|
||||||
this, // thread function arguments
|
this, // thread function arguments
|
||||||
0, // default creation flags
|
0, // default creation flags
|
||||||
NULL); // receive thread identifier
|
NULL)); // receive thread identifier
|
||||||
|
|
||||||
if (hThread == NULL)
|
if ((HANDLE)hThread == NULL)
|
||||||
{
|
{
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
goto Finished;
|
goto Finished;
|
||||||
|
|
@ -95,12 +97,6 @@ IN_PROCESS_APPLICATION::ShutDown(
|
||||||
|
|
||||||
Finished:
|
Finished:
|
||||||
|
|
||||||
if (hThread != NULL)
|
|
||||||
{
|
|
||||||
CloseHandle(hThread);
|
|
||||||
}
|
|
||||||
m_hThread = NULL;
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
UTILITY::LogEventF(g_hEventLog,
|
UTILITY::LogEventF(g_hEventLog,
|
||||||
|
|
@ -126,7 +122,6 @@ IN_PROCESS_APPLICATION::ShutDownInternal()
|
||||||
DWORD dwTimeout = m_pConfig->QueryShutdownTimeLimitInMS();
|
DWORD dwTimeout = m_pConfig->QueryShutdownTimeLimitInMS();
|
||||||
HANDLE handle = NULL;
|
HANDLE handle = NULL;
|
||||||
WIN32_FIND_DATA fileData;
|
WIN32_FIND_DATA fileData;
|
||||||
BOOL fLocked = FALSE;
|
|
||||||
|
|
||||||
if (IsDebuggerPresent())
|
if (IsDebuggerPresent())
|
||||||
{
|
{
|
||||||
|
|
@ -137,41 +132,43 @@ IN_PROCESS_APPLICATION::ShutDownInternal()
|
||||||
m_status == APPLICATION_STATUS::STARTING ||
|
m_status == APPLICATION_STATUS::STARTING ||
|
||||||
m_status == APPLICATION_STATUS::FAIL)
|
m_status == APPLICATION_STATUS::FAIL)
|
||||||
{
|
{
|
||||||
goto Finished;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AcquireSRWLockExclusive(&m_srwLock);
|
|
||||||
fLocked = TRUE;
|
|
||||||
|
|
||||||
if (m_fShutdownCalledFromNative ||
|
|
||||||
m_status == APPLICATION_STATUS::STARTING ||
|
|
||||||
m_status == APPLICATION_STATUS::FAIL)
|
|
||||||
{
|
{
|
||||||
goto Finished;
|
SRWLockWrapper lock(m_srwLock);
|
||||||
}
|
|
||||||
|
|
||||||
// We need to keep track of when both managed and native initiate shutdown
|
if (m_fShutdownCalledFromNative ||
|
||||||
// to avoid AVs. If shutdown has already been initiated in managed, we don't want to call into
|
m_status == APPLICATION_STATUS::STARTING ||
|
||||||
// managed. We still need to wait on main exiting no matter what. m_fShutdownCalledFromNative
|
m_status == APPLICATION_STATUS::FAIL)
|
||||||
// is used for detecting redundant calls and blocking more requests to OnExecuteRequestHandler.
|
{
|
||||||
m_fShutdownCalledFromNative = TRUE;
|
return;
|
||||||
m_status = APPLICATION_STATUS::SHUTDOWN;
|
}
|
||||||
|
|
||||||
|
// We need to keep track of when both managed and native initiate shutdown
|
||||||
|
// to avoid AVs. If shutdown has already been initiated in managed, we don't want to call into
|
||||||
|
// 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::SHUTDOWN;
|
||||||
|
|
||||||
|
if (!m_fShutdownCalledFromManaged)
|
||||||
|
{
|
||||||
|
// We cannot call into managed if the dll is detaching from the process.
|
||||||
|
// Calling into managed code when the dll is detaching is strictly a bad idea,
|
||||||
|
// and usually results in an AV saying "The string binding is invalid"
|
||||||
|
if (!g_fProcessDetach)
|
||||||
|
{
|
||||||
|
m_ShutdownHandler(m_ShutdownHandlerContext);
|
||||||
|
m_ShutdownHandler = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release the lock before we wait on the thread to exit.
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_fShutdownCalledFromManaged)
|
if (!m_fShutdownCalledFromManaged)
|
||||||
{
|
{
|
||||||
// We cannot call into managed if the dll is detaching from the process.
|
|
||||||
// Calling into managed code when the dll is detaching is strictly a bad idea,
|
|
||||||
// and usually results in an AV saying "The string binding is invalid"
|
|
||||||
if (!g_fProcessDetach)
|
|
||||||
{
|
|
||||||
m_ShutdownHandler(m_ShutdownHandlerContext);
|
|
||||||
m_ShutdownHandler = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleaseSRWLockExclusive(&m_srwLock);
|
|
||||||
fLocked = FALSE;
|
|
||||||
|
|
||||||
// Release the lock before we wait on the thread to exit.
|
|
||||||
if (m_hThread != NULL &&
|
if (m_hThread != NULL &&
|
||||||
GetExitCodeThread(m_hThread, &dwThreadStatus) != 0 &&
|
GetExitCodeThread(m_hThread, &dwThreadStatus) != 0 &&
|
||||||
dwThreadStatus == STILL_ACTIVE)
|
dwThreadStatus == STILL_ACTIVE)
|
||||||
|
|
@ -221,36 +218,32 @@ IN_PROCESS_APPLICATION::ShutDownInternal()
|
||||||
// as nothing can be done
|
// as nothing can be done
|
||||||
DeleteFile(m_struLogFilePath.QueryStr());
|
DeleteFile(m_struLogFilePath.QueryStr());
|
||||||
}
|
}
|
||||||
|
|
||||||
Finished:
|
|
||||||
|
|
||||||
if (fLocked)
|
|
||||||
{
|
|
||||||
ReleaseSRWLockExclusive(&m_srwLock);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__override
|
||||||
VOID
|
VOID
|
||||||
IN_PROCESS_APPLICATION::Recycle(
|
IN_PROCESS_APPLICATION::Recycle(
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
BOOL fLockAcquired = FALSE;
|
|
||||||
// We need to guarantee that recycle is only called once, as calling pHttpServer->RecycleProcess
|
// We need to guarantee that recycle is only called once, as calling pHttpServer->RecycleProcess
|
||||||
// multiple times can lead to AVs.
|
// multiple times can lead to AVs.
|
||||||
if (m_fRecycleCalled)
|
if (m_fRecycleCalled)
|
||||||
{
|
{
|
||||||
goto Finished;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AcquireSRWLockExclusive(&m_srwLock);
|
|
||||||
fLockAcquired = TRUE;
|
|
||||||
|
|
||||||
if (m_fRecycleCalled)
|
|
||||||
{
|
{
|
||||||
goto Finished;
|
SRWLockWrapper lock(m_srwLock);
|
||||||
|
|
||||||
|
if (m_fRecycleCalled)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fRecycleCalled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_pHttpServer->IsCommandLineLaunch())
|
if (!m_pHttpServer->IsCommandLineLaunch())
|
||||||
{
|
{
|
||||||
// IIS scenario.
|
// IIS scenario.
|
||||||
|
|
@ -260,20 +253,10 @@ IN_PROCESS_APPLICATION::Recycle(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// IISExpress scenario
|
// IISExpress scenario
|
||||||
// Release the lock first as Shutdown will acquire lock later
|
|
||||||
ReleaseSRWLockExclusive(&m_srwLock);
|
|
||||||
fLockAcquired = FALSE;
|
|
||||||
|
|
||||||
// Shutdown the managed application and call exit to terminate current process
|
// Shutdown the managed application and call exit to terminate current process
|
||||||
ShutDown();
|
ShutDown();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Finished:
|
|
||||||
if (fLockAcquired)
|
|
||||||
{
|
|
||||||
ReleaseSRWLockExclusive(&m_srwLock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
REQUEST_NOTIFICATION_STATUS
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
|
@ -392,7 +375,6 @@ IN_PROCESS_APPLICATION::SetStdOut(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
BOOL fLocked = FALSE;
|
|
||||||
STRU struPath;
|
STRU struPath;
|
||||||
SYSTEMTIME systemTime;
|
SYSTEMTIME systemTime;
|
||||||
SECURITY_ATTRIBUTES saAttr = { 0 };
|
SECURITY_ATTRIBUTES saAttr = { 0 };
|
||||||
|
|
@ -402,8 +384,7 @@ IN_PROCESS_APPLICATION::SetStdOut(
|
||||||
if (!m_fDoneStdRedirect)
|
if (!m_fDoneStdRedirect)
|
||||||
{
|
{
|
||||||
// Have not set stdout yet, redirect stdout to log file
|
// Have not set stdout yet, redirect stdout to log file
|
||||||
AcquireSRWLockExclusive(&m_srwLock);
|
SRWLockWrapper lock(m_srwLock);
|
||||||
fLocked = TRUE;
|
|
||||||
if (!m_fDoneStdRedirect)
|
if (!m_fDoneStdRedirect)
|
||||||
{
|
{
|
||||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
|
@ -553,10 +534,6 @@ IN_PROCESS_APPLICATION::SetStdOut(
|
||||||
|
|
||||||
Finished:
|
Finished:
|
||||||
m_fDoneStdRedirect = TRUE;
|
m_fDoneStdRedirect = TRUE;
|
||||||
if (fLocked)
|
|
||||||
{
|
|
||||||
ReleaseSRWLockExclusive(&m_srwLock);
|
|
||||||
}
|
|
||||||
if (FAILED(hr) && m_pConfig->QueryStdoutLogEnabled())
|
if (FAILED(hr) && m_pConfig->QueryStdoutLogEnabled())
|
||||||
{
|
{
|
||||||
UTILITY::LogEventF(g_hEventLog,
|
UTILITY::LogEventF(g_hEventLog,
|
||||||
|
|
@ -651,7 +628,6 @@ IN_PROCESS_APPLICATION::LoadManagedApplication
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
DWORD dwTimeout;
|
DWORD dwTimeout;
|
||||||
DWORD dwResult;
|
DWORD dwResult;
|
||||||
BOOL fLocked = FALSE;
|
|
||||||
|
|
||||||
ReferenceApplication();
|
ReferenceApplication();
|
||||||
|
|
||||||
|
|
@ -674,84 +650,84 @@ IN_PROCESS_APPLICATION::LoadManagedApplication
|
||||||
// Set up stdout redirect
|
// Set up stdout redirect
|
||||||
SetStdOut();
|
SetStdOut();
|
||||||
|
|
||||||
AcquireSRWLockExclusive(&m_srwLock);
|
|
||||||
fLocked = TRUE;
|
|
||||||
if (m_status != APPLICATION_STATUS::STARTING)
|
|
||||||
{
|
{
|
||||||
if (m_status == APPLICATION_STATUS::FAIL)
|
SRWLockWrapper lock(m_srwLock);
|
||||||
|
if (m_status != APPLICATION_STATUS::STARTING)
|
||||||
|
{
|
||||||
|
if (m_status == APPLICATION_STATUS::FAIL)
|
||||||
|
{
|
||||||
|
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
|
||||||
|
}
|
||||||
|
else if (m_status == APPLICATION_STATUS::SHUTDOWN)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(ERROR_SHUTDOWN_IS_SCHEDULED);
|
||||||
|
}
|
||||||
|
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
m_hThread = CreateThread(
|
||||||
|
NULL, // default security attributes
|
||||||
|
0, // default stack size
|
||||||
|
(LPTHREAD_START_ROUTINE)ExecuteAspNetCoreProcess,
|
||||||
|
this, // thread function arguments
|
||||||
|
0, // default creation flags
|
||||||
|
NULL); // receive thread identifier
|
||||||
|
|
||||||
|
if (m_hThread == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pInitalizeEvent = CreateEvent(
|
||||||
|
NULL, // default security attributes
|
||||||
|
TRUE, // manual reset event
|
||||||
|
FALSE, // not set
|
||||||
|
NULL); // name
|
||||||
|
|
||||||
|
if (m_pInitalizeEvent == NULL)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the debugger is attached, never timeout
|
||||||
|
if (IsDebuggerPresent())
|
||||||
|
{
|
||||||
|
dwTimeout = INFINITE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dwTimeout = m_pConfig->QueryStartupTimeLimitInMS();
|
||||||
|
}
|
||||||
|
|
||||||
|
const HANDLE pHandles[2]{ m_hThread, m_pInitalizeEvent };
|
||||||
|
|
||||||
|
// Wait on either the thread to complete or the event to be set
|
||||||
|
dwResult = WaitForMultipleObjects(2, pHandles, FALSE, dwTimeout);
|
||||||
|
|
||||||
|
// It all timed out
|
||||||
|
if (dwResult == WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
// kill the backend thread as loading dotnet timedout
|
||||||
|
TerminateThread(m_hThread, 0);
|
||||||
|
hr = HRESULT_FROM_WIN32(dwResult);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
else if (dwResult == WAIT_FAILED)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The thread ended it means that something failed
|
||||||
|
if (dwResult == WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
|
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
|
||||||
}
|
goto Finished;
|
||||||
else if (m_status == APPLICATION_STATUS::SHUTDOWN)
|
|
||||||
{
|
|
||||||
hr = HRESULT_FROM_WIN32(ERROR_SHUTDOWN_IS_SCHEDULED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
goto Finished;
|
m_status = APPLICATION_STATUS::RUNNING;
|
||||||
}
|
}
|
||||||
m_hThread = CreateThread(
|
|
||||||
NULL, // default security attributes
|
|
||||||
0, // default stack size
|
|
||||||
(LPTHREAD_START_ROUTINE)ExecuteAspNetCoreProcess,
|
|
||||||
this, // thread function arguments
|
|
||||||
0, // default creation flags
|
|
||||||
NULL); // receive thread identifier
|
|
||||||
|
|
||||||
if (m_hThread == NULL)
|
|
||||||
{
|
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pInitalizeEvent = CreateEvent(
|
|
||||||
NULL, // default security attributes
|
|
||||||
TRUE, // manual reset event
|
|
||||||
FALSE, // not set
|
|
||||||
NULL); // name
|
|
||||||
|
|
||||||
if (m_pInitalizeEvent == NULL)
|
|
||||||
{
|
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the debugger is attached, never timeout
|
|
||||||
if (IsDebuggerPresent())
|
|
||||||
{
|
|
||||||
dwTimeout = INFINITE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dwTimeout = m_pConfig->QueryStartupTimeLimitInMS();
|
|
||||||
}
|
|
||||||
|
|
||||||
const HANDLE pHandles[2]{ m_hThread, m_pInitalizeEvent };
|
|
||||||
|
|
||||||
// Wait on either the thread to complete or the event to be set
|
|
||||||
dwResult = WaitForMultipleObjects(2, pHandles, FALSE, dwTimeout);
|
|
||||||
|
|
||||||
// It all timed out
|
|
||||||
if (dwResult == WAIT_TIMEOUT)
|
|
||||||
{
|
|
||||||
// kill the backend thread as loading dotnet timedout
|
|
||||||
TerminateThread(m_hThread, 0);
|
|
||||||
hr = HRESULT_FROM_WIN32(dwResult);
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
else if (dwResult == WAIT_FAILED)
|
|
||||||
{
|
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The thread ended it means that something failed
|
|
||||||
if (dwResult == WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
hr = E_APPLICATION_ACTIVATION_EXEC_FAILURE;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_status = APPLICATION_STATUS::RUNNING;
|
|
||||||
|
|
||||||
Finished:
|
Finished:
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
|
@ -766,12 +742,6 @@ Finished:
|
||||||
m_pConfig->QueryApplicationPhysicalPath()->QueryStr(),
|
m_pConfig->QueryApplicationPhysicalPath()->QueryStr(),
|
||||||
hr);
|
hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fLocked)
|
|
||||||
{
|
|
||||||
ReleaseSRWLockExclusive(&m_srwLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
DereferenceApplication();
|
DereferenceApplication();
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,8 @@ private:
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
IHttpServer* const m_pHttpServer;
|
||||||
|
|
||||||
// Thread executing the .NET Core process
|
// Thread executing the .NET Core process
|
||||||
HANDLE m_hThread;
|
HANDLE m_hThread;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue