9
9
#include " StdWrapper.h"
10
10
#include " ntassert.h"
11
11
#include " StringHelpers.h"
12
-
13
- #define LOG_IF_DUPFAIL (err ) do { if (err == -1 ) { LOG_IF_FAILED (HRESULT_FROM_WIN32 (_doserrno)); } } while (0 , 0 );
14
- #define LOG_IF_ERRNO (err ) do { if (err != 0 ) { LOG_IF_FAILED (HRESULT_FROM_WIN32 (_doserrno)); } } while (0 , 0 );
15
-
12
+ #include " Environment.h"
16
13
17
14
StandardStreamRedirection::StandardStreamRedirection (RedirectionOutput& output, bool commandLineLaunch) :
18
15
m_output(output),
@@ -23,6 +20,28 @@ StandardStreamRedirection::StandardStreamRedirection(RedirectionOutput& output,
23
20
m_commandLineLaunch(commandLineLaunch)
24
21
{
25
22
TryStartRedirection ();
23
+
24
+ // Allow users to override the default termination timeout for the redirection thread.
25
+ auto timeoutMsStr = Environment::GetEnvironmentVariableValue (L" ASPNETCORE_OUTPUT_REDIRECTION_TERMINATION_TIMEOUT_MS" );
26
+ if (timeoutMsStr.has_value ())
27
+ {
28
+ try
29
+ {
30
+ int timeoutMs = std::stoi (timeoutMsStr.value ());
31
+ if (timeoutMs > 0 && timeoutMs <= PIPE_OUTPUT_THREAD_TIMEOUT_MS_MAX)
32
+ {
33
+ m_terminationTimeoutMs = timeoutMs;
34
+ }
35
+ else
36
+ {
37
+ LOG_WARN (L" ASPNETCORE_OUTPUT_REDIRECTION_TERMINATION_TIMEOUT_MS must be an integer between 0 and 1800000. Ignoring." );
38
+ }
39
+ }
40
+ catch (...)
41
+ {
42
+ LOG_WARN (L" ASPNETCORE_OUTPUT_REDIRECTION_TERMINATION_TIMEOUT_MS must be an integer between 0 and 1800000. Ignoring." );
43
+ }
44
+ }
26
45
}
27
46
28
47
StandardStreamRedirection::~StandardStreamRedirection () noexcept (false )
@@ -80,8 +99,6 @@ void StandardStreamRedirection::Start()
80
99
// be thrown away.
81
100
void StandardStreamRedirection::Stop ()
82
101
{
83
- DWORD dwThreadStatus = 0 ;
84
-
85
102
if (m_disposed)
86
103
{
87
104
return ;
@@ -126,12 +143,13 @@ void StandardStreamRedirection::Stop()
126
143
}
127
144
128
145
// GetExitCodeThread returns 0 on failure; thread status code is invalid.
146
+ DWORD dwThreadStatus = 0 ;
129
147
if (m_hErrThread != nullptr &&
130
148
!LOG_LAST_ERROR_IF (!GetExitCodeThread (m_hErrThread, &dwThreadStatus)) &&
131
149
dwThreadStatus == STILL_ACTIVE)
132
150
{
133
151
// Wait for graceful shutdown, i.e., the exit of the background thread or timeout
134
- if (WaitForSingleObject (m_hErrThread, PIPE_OUTPUT_THREAD_TIMEOUT ) != WAIT_OBJECT_0)
152
+ if (WaitForSingleObject (m_hErrThread, m_terminationTimeoutMs ) != WAIT_OBJECT_0)
135
153
{
136
154
// If the thread is still running, we need kill it first before exit to avoid AV
137
155
if (!LOG_LAST_ERROR_IF (GetExitCodeThread (m_hErrThread, &dwThreadStatus) == 0 ) &&
0 commit comments