Fix shutdown timeout handling in completion wait function (#21395)
Stelios Fragkakis committed
Dec 4, 2025 at 09:17 UTC
edb587b89cc2c4983d97fd6751dea3bc0c09f2b6
1 file changed
+16
-16
src/libnetdata/completion/completion.c
+16
-16
@@ -36,33 +36,33 @@ ALWAYS_INLINE void completion_wait_for(struct completion *p)
36
37
ALWAYS_INLINE bool completion_timedwait_for(struct completion *p, uint64_t timeout_s)
38
{
39
- timeout_s *= NSEC_PER_SEC;
39
+ uint64_t timeout_ns = timeout_s * NSEC_PER_SEC;
40
+ if (timeout_ns == 0) timeout_ns = 1;
41
41
- uint64_t start_time = uv_hrtime();
42
+ uint64_t deadline_ns = uv_hrtime() + timeout_ns;
43
bool result = true;
44
45
netdata_mutex_lock(&p->mutex);
45
- while (!p->completed) {
46
- int rc = netdata_cond_timedwait(&p->cond, &p->mutex, timeout_s);
46
+ while (!p->completed && result) {
47
+ uint64_t current_time_ns = uv_hrtime();
48
48
- if (rc == 0) {
49
- result = true;
50
- break;
51
- } else if (rc == UV_ETIMEDOUT) {
49
+ // Check if we've already exceeded the deadline
50
+ if (current_time_ns >= deadline_ns) {
51
result = false;
52
break;
53
}
54
56
- /*
57
- * handle spurious wakeups
58
- */
55
+ uint64_t remaining_timeout_ns = deadline_ns - current_time_ns;
56
60
- uint64_t elapsed = uv_hrtime() - start_time;
61
- if (elapsed >= timeout_s) {
57
+ int rc = netdata_cond_timedwait(&p->cond, &p->mutex, remaining_timeout_ns);
58
+
59
+ if (rc == UV_ETIMEDOUT)
60
result = false;
63
- break;
64
- }
65
- timeout_s -= elapsed;
61
+
62
+ // Condition was signaled (or spurious wakeup).
63
+ // The loop condition `!p->completed` will be re-evaluated.
64
+ // If p->completed is true, the loop exits.
65
+ // If p->completed is false (spurious wakeup), the loop continues with a new remaining_timeout_ns.
66
}
67
netdata_mutex_unlock(&p->mutex);
68