Skip to content

Commit f02d70b

Browse files
authored
Fix overflow in timeout logic (#3046)
1 parent a920898 commit f02d70b

File tree

2 files changed

+13
-23
lines changed

2 files changed

+13
-23
lines changed

sdk/src/metrics/export/periodic_exporting_metric_reader.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ bool PeriodicExportingMetricReader::OnForceFlush(std::chrono::microseconds timeo
218218
// - If original `timeout` is `zero`, use that in exporter::forceflush
219219
// - Else if remaining `timeout_steady` more than zero, use that in exporter::forceflush
220220
// - Else don't invoke exporter::forceflush ( as remaining time is zero or less)
221-
if (timeout <= std::chrono::steady_clock::duration::zero())
221+
if (timeout <= std::chrono::milliseconds::duration::zero())
222222
{
223223
result =
224224
exporter_->ForceFlush(std::chrono::duration_cast<std::chrono::microseconds>(timeout));

sdk/src/metrics/meter_context.cc

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -168,46 +168,36 @@ bool MeterContext::ForceFlush(std::chrono::microseconds timeout) noexcept
168168
bool result = true;
169169
// Simultaneous flush not allowed.
170170
const std::lock_guard<opentelemetry::common::SpinLockMutex> locked(forceflush_lock_);
171-
// Convert to nanos to prevent overflow
172-
auto timeout_ns = (std::chrono::nanoseconds::max)();
173-
if (std::chrono::duration_cast<std::chrono::microseconds>(timeout_ns) > timeout)
174-
{
175-
timeout_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(timeout);
176-
}
177-
178-
auto current_time = std::chrono::system_clock::now();
179-
std::chrono::system_clock::time_point expire_time;
180-
auto overflow_checker = (std::chrono::system_clock::time_point::max)();
181171

182-
// check if the expected expire time doesn't overflow.
183-
if (overflow_checker - current_time > timeout_ns)
172+
auto time_remaining = (std::chrono::steady_clock::duration::max)();
173+
if (std::chrono::duration_cast<std::chrono::microseconds>(time_remaining) > timeout)
184174
{
185-
expire_time =
186-
current_time + std::chrono::duration_cast<std::chrono::system_clock::duration>(timeout_ns);
175+
time_remaining = timeout;
187176
}
188-
else
177+
178+
auto current_time = std::chrono::steady_clock::now();
179+
auto expire_time = (std::chrono::steady_clock::time_point::max)();
180+
if (expire_time - current_time > time_remaining)
189181
{
190-
// overflow happens, reset expire time to max.
191-
expire_time = overflow_checker;
182+
expire_time = current_time + time_remaining;
192183
}
193184

194185
for (auto &collector : collectors_)
195186
{
196187
if (!std::static_pointer_cast<MetricCollector>(collector)->ForceFlush(
197-
std::chrono::duration_cast<std::chrono::microseconds>(timeout_ns)))
188+
std::chrono::duration_cast<std::chrono::microseconds>(time_remaining)))
198189
{
199190
result = false;
200191
}
201192

202-
current_time = std::chrono::system_clock::now();
203-
193+
current_time = std::chrono::steady_clock::now();
204194
if (expire_time >= current_time)
205195
{
206-
timeout_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(expire_time - current_time);
196+
time_remaining = expire_time - current_time;
207197
}
208198
else
209199
{
210-
timeout_ns = std::chrono::nanoseconds::zero();
200+
time_remaining = std::chrono::steady_clock::duration::zero();
211201
}
212202
}
213203
if (!result)

0 commit comments

Comments
 (0)