Skip to content

Commit ff58d5f

Browse files
author
Daniel Stodden
committed
PR-1129: Fix main loop timeout bug.
Calls to scheduler_check_fd_events return prematurely, failing to mark a timeout pending, iff nfds is 0. This leads to a condition where the deadline never gets reset, so the next calculated timeout tv will be {0, 0} and we're left spinning in select()s. Fixed by separating fd and timeout checks. Signed-off-by: Daniel Stodden <[email protected]>
1 parent bfaa6b3 commit ff58d5f

File tree

1 file changed

+40
-14
lines changed

1 file changed

+40
-14
lines changed

drivers/scheduler.c

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
#include "scheduler.h"
3636
#include "tapdisk-log.h"
3737

38-
#define DBG(_f, _a...) tlog_write(TLOG_DBG, _f, ##_a)
38+
#define DBG(_f, _a...) if (0) { tlog_syslog(TLOG_DBG, _f, ##_a); }
3939
#define BUG_ON(_cond) if (_cond) td_panic()
4040

4141
#define SCHEDULER_MAX_TIMEOUT 600
@@ -117,17 +117,14 @@ scheduler_prepare_events(scheduler_t *s)
117117
}
118118

119119
static int
120-
scheduler_check_events(scheduler_t *s, int nfds)
120+
scheduler_check_fd_events(scheduler_t *s, int nfds)
121121
{
122122
event_t *event;
123-
struct timeval now;
124-
125-
if (nfds <= 0)
126-
return nfds;
127-
128-
gettimeofday(&now, NULL);
129123

130124
scheduler_for_each_event(s, event) {
125+
if (!nfds)
126+
break;
127+
131128
if (event->dead)
132129
continue;
133130

@@ -151,16 +148,45 @@ scheduler_check_events(scheduler_t *s, int nfds)
151148
event->pending |= SCHEDULER_POLL_EXCEPT_FD;
152149
--nfds;
153150
}
151+
}
152+
153+
return nfds;
154+
}
155+
156+
static void
157+
scheduler_check_timeouts(scheduler_t *s)
158+
{
159+
struct timeval now;
160+
event_t *event;
161+
162+
gettimeofday(&now, NULL);
163+
164+
scheduler_for_each_event(s, event) {
165+
BUG_ON(event->pending && event->masked);
154166

155-
if (event->pending) {
156-
BUG_ON(event->masked);
167+
if (event->dead)
168+
continue;
169+
170+
if (event->pending)
171+
continue;
172+
173+
if (!(event->mode & SCHEDULER_POLL_TIMEOUT))
157174
continue;
158-
}
159175

160-
if ((event->mode & SCHEDULER_POLL_TIMEOUT) &&
161-
(event->deadline <= now.tv_sec))
162-
event->pending = SCHEDULER_POLL_TIMEOUT;
176+
if (event->deadline > now.tv_sec)
177+
continue;
178+
179+
event->pending = SCHEDULER_POLL_TIMEOUT;
163180
}
181+
}
182+
183+
static int
184+
scheduler_check_events(scheduler_t *s, int nfds)
185+
{
186+
if (nfds)
187+
nfds = scheduler_check_fd_events(s, nfds);
188+
189+
scheduler_check_timeouts(s);
164190

165191
return nfds;
166192
}

0 commit comments

Comments
 (0)