Skip to content

Commit 34a3d4a

Browse files
Make stdout/stderr redirection thread timeout configurable. (#49942)
1 parent 13bc23b commit 34a3d4a

File tree

2 files changed

+35
-10
lines changed

2 files changed

+35
-10
lines changed

src/Servers/IIS/AspNetCoreModuleV2/CommonLib/StandardStreamRedirection.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@
99
#include "StdWrapper.h"
1010
#include "ntassert.h"
1111
#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"
1613

1714
StandardStreamRedirection::StandardStreamRedirection(RedirectionOutput& output, bool commandLineLaunch) :
1815
m_output(output),
@@ -23,6 +20,28 @@ StandardStreamRedirection::StandardStreamRedirection(RedirectionOutput& output,
2320
m_commandLineLaunch(commandLineLaunch)
2421
{
2522
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+
}
2645
}
2746

2847
StandardStreamRedirection::~StandardStreamRedirection() noexcept(false)
@@ -80,8 +99,6 @@ void StandardStreamRedirection::Start()
8099
// be thrown away.
81100
void StandardStreamRedirection::Stop()
82101
{
83-
DWORD dwThreadStatus = 0;
84-
85102
if (m_disposed)
86103
{
87104
return;
@@ -126,12 +143,13 @@ void StandardStreamRedirection::Stop()
126143
}
127144

128145
// GetExitCodeThread returns 0 on failure; thread status code is invalid.
146+
DWORD dwThreadStatus = 0;
129147
if (m_hErrThread != nullptr &&
130148
!LOG_LAST_ERROR_IF(!GetExitCodeThread(m_hErrThread, &dwThreadStatus)) &&
131149
dwThreadStatus == STILL_ACTIVE)
132150
{
133151
// 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)
135153
{
136154
// If the thread is still running, we need kill it first before exit to avoid AV
137155
if (!LOG_LAST_ERROR_IF(GetExitCodeThread(m_hErrThread, &dwThreadStatus) == 0) &&

src/Servers/IIS/AspNetCoreModuleV2/CommonLib/StandardStreamRedirection.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@
99

1010
class StandardStreamRedirection : NonCopyable
1111
{
12-
// Timeout to be used if a thread never exits
13-
#define PIPE_OUTPUT_THREAD_TIMEOUT 2000
14-
#define PIPE_READ_SIZE 4096
12+
// Default timeout for the redirection thread to exit before it is forcefully terminated
13+
// This can be overridden with ASPNETCORE_OUTPUT_REDIRECTION_TERMINATION_TIMEOUT_MS
14+
static constexpr int PIPE_OUTPUT_THREAD_TIMEOUT_MS_DEFAULT = 2000;
15+
16+
// Maximum allowed timeout value
17+
static constexpr int PIPE_OUTPUT_THREAD_TIMEOUT_MS_MAX = 1800000; // 30 minutes
18+
19+
// Size of the buffer used to read from the pipe
20+
static constexpr int PIPE_READ_SIZE = 4096;
1521

1622
public:
1723
StandardStreamRedirection(RedirectionOutput& output, bool commandLineLaunch);
@@ -63,4 +69,5 @@ class StandardStreamRedirection : NonCopyable
6369
std::unique_ptr<StdWrapper> stdoutWrapper;
6470
std::unique_ptr<StdWrapper> stderrWrapper;
6571
RedirectionOutput& m_output;
72+
int m_terminationTimeoutMs = PIPE_OUTPUT_THREAD_TIMEOUT_MS_DEFAULT;
6673
};

0 commit comments

Comments
 (0)