diff options
author | Jim Ma <mazong1123@gmail.com> | 2017-04-13 23:50:05 +0800 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2017-04-13 08:50:05 -0700 |
commit | 5e138a6d69215546e9bf4b38ec9bdd1c436fca5b (patch) | |
tree | 5f774a383b9ffeba11b93907d0b0c1e690919506 /src/vm/corhost.cpp | |
parent | 7f1ebe17e63bf7670c8fc3393a82b2b1ed978762 (diff) | |
download | coreclr-5e138a6d69215546e9bf4b38ec9bdd1c436fca5b.tar.gz coreclr-5e138a6d69215546e9bf4b38ec9bdd1c436fca5b.tar.bz2 coreclr-5e138a6d69215546e9bf4b38ec9bdd1c436fca5b.zip |
Ensure Environment.ExitCode works correctly after app domain unloaded. (#10842)
* Ensure Environment.ExitCode works correctly after app domain unloaded.
This PR addresses 2 problems of Environment.ExitCode:
1. Can't get correct exit code of main function.
2. Can't set %errorlevel%.
Details can be found on #6206
Fix #6206
Diffstat (limited to 'src/vm/corhost.cpp')
-rw-r--r-- | src/vm/corhost.cpp | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/src/vm/corhost.cpp b/src/vm/corhost.cpp index 75adbada94..d935ddd8c8 100644 --- a/src/vm/corhost.cpp +++ b/src/vm/corhost.cpp @@ -1201,6 +1201,11 @@ HRESULT GetCLRRuntimeHost(REFIID riid, IUnknown **ppUnk) STDMETHODIMP CorHost2::UnloadAppDomain(DWORD dwDomainId, BOOL fWaitUntilDone) { + return UnloadAppDomain2(dwDomainId, fWaitUntilDone, nullptr); +} + +STDMETHODIMP CorHost2::UnloadAppDomain2(DWORD dwDomainId, BOOL fWaitUntilDone, int *pLatchedExitCode) +{ WRAPPER_NO_CONTRACT; STATIC_CONTRACT_SO_TOLERANT; @@ -1249,14 +1254,23 @@ STDMETHODIMP CorHost2::UnloadAppDomain(DWORD dwDomainId, BOOL fWaitUntilDone) } END_ENTRYPOINT_NOTHROW; + if (pLatchedExitCode) + { + *pLatchedExitCode = GetLatchedExitCode(); + } + return hr; } - else - return CorRuntimeHostBase::UnloadAppDomain(dwDomainId, fWaitUntilDone); + return CorRuntimeHostBase::UnloadAppDomain2(dwDomainId, fWaitUntilDone, pLatchedExitCode); } -HRESULT CorRuntimeHostBase::UnloadAppDomain(DWORD dwDomainId, BOOL fSync) +HRESULT CorRuntimeHostBase::UnloadAppDomain(DWORD dwDomainId, BOOL fWaitUntilDone) +{ + return UnloadAppDomain2(dwDomainId, fWaitUntilDone, nullptr); +} + +HRESULT CorRuntimeHostBase::UnloadAppDomain2(DWORD dwDomainId, BOOL fWaitUntilDone, int *pLatchedExitCode) { CONTRACTL { @@ -1282,7 +1296,7 @@ HRESULT CorRuntimeHostBase::UnloadAppDomain(DWORD dwDomainId, BOOL fSync) // // However, for a thread that holds the loader lock, unloading the appDomain is // not a supported scenario. Thus, we should not be ending up in this code - // path for the FAULT violation. + // path for the FAULT violation. // // Hence, the CONTRACT_VIOLATION below for overriding the FORBID_FAULT // for this scope only. @@ -1292,18 +1306,23 @@ HRESULT CorRuntimeHostBase::UnloadAppDomain(DWORD dwDomainId, BOOL fSync) ) { return HOST_E_CLRNOTAVAILABLE; - } + } } - + BEGIN_ENTRYPOINT_NOTHROW; // We do not use BEGIN_EXTERNAL_ENTRYPOINT here because // we do not want to setup Thread. Process may be OOM, and we want Unload // to work. - hr = AppDomain::UnloadById(ADID(dwDomainId), fSync); + hr = AppDomain::UnloadById(ADID(dwDomainId), fWaitUntilDone); END_ENTRYPOINT_NOTHROW; + if (pLatchedExitCode) + { + *pLatchedExitCode = GetLatchedExitCode(); + } + return hr; } @@ -1404,6 +1423,14 @@ HRESULT CorHost2::QueryInterface(REFIID riid, void **ppUnk) *ppUnk = static_cast<ICLRRuntimeHost2 *>(this); } + else if (riid == IID_ICLRRuntimeHost4) + { + ULONG version = 4; + if (m_Version == 0) + FastInterlockCompareExchange((LONG*)&m_Version, version, 0); + + *ppUnk = static_cast<ICLRRuntimeHost4 *>(this); + } else if (riid == IID_ICLRExecutionManager) { ULONG version = 2; |