summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2009-01-27 19:45:51 +0100
committerVolker Lendecke <vl@samba.org>2009-01-28 16:18:16 +0100
commit4c7296cc0c0770ea547b67d668d5b42ab00a27da (patch)
tree0a3dd81890d71c83b88432d250727be355cff77d
parentc001b456cf0c9fdfd90a5239e3b86168d0fbb5aa (diff)
downloadsamba-4c7296cc0c0770ea547b67d668d5b42ab00a27da.tar.gz
samba-4c7296cc0c0770ea547b67d668d5b42ab00a27da.tar.bz2
samba-4c7296cc0c0770ea547b67d668d5b42ab00a27da.zip
Avoid valgrind errors
In event handlers, we might destroy other events that are pending in the lists. We can only run one event safely per select call. Yes, I've seen these valgrind errors :-) Jeremy, with ccdd921e61 you had checked in the change to run multiple events. Do you remember why it was necessary and could not be solved in a different way? Volker
-rw-r--r--source3/lib/events.c48
1 files changed, 13 insertions, 35 deletions
diff --git a/source3/lib/events.c b/source3/lib/events.c
index 4484d5323b..44b4562757 100644
--- a/source3/lib/events.c
+++ b/source3/lib/events.c
@@ -83,45 +83,24 @@ bool event_add_to_select_args(struct tevent_context *ev,
bool run_events(struct tevent_context *ev,
int selrtn, fd_set *read_fds, fd_set *write_fds)
{
- bool fired = false;
- struct tevent_fd *fde, *next;
+ struct tevent_fd *fde;
+ struct timeval now;
if (ev->signal_events &&
tevent_common_check_signal(ev)) {
return true;
}
- /* Run all events that are pending, not just one (as we
- did previously. */
-
- while (ev->timer_events) {
- struct timeval now;
- GetTimeOfDay(&now);
-
- if (timeval_compare(
- &now, &ev->timer_events->next_event) < 0) {
- /* Nothing to do yet */
- DEBUG(11, ("run_events: Nothing to do\n"));
- break;
- }
-
- DEBUG(10, ("Running event \"%s\" %p\n",
- ev->timer_events->handler_name,
- ev->timer_events));
+ GetTimeOfDay(&now);
- ev->timer_events->handler(
- ev,
- ev->timer_events, now,
- ev->timer_events->private_data);
+ if ((ev->timer_events != NULL)
+ && (timeval_compare(&now, &ev->timer_events->next_event) >= 0)) {
- fired = true;
- }
+ DEBUG(10, ("Running timed event \"%s\" %p\n",
+ ev->timer_events->handler_name, ev->timer_events));
- if (fired) {
- /*
- * We might have changed the socket status during the timed
- * events, return to run select again.
- */
+ ev->timer_events->handler(ev, ev->timer_events, now,
+ ev->timer_events->private_data);
return true;
}
@@ -129,23 +108,22 @@ bool run_events(struct tevent_context *ev,
/*
* No fd ready
*/
- return fired;
+ return false;
}
- for (fde = ev->fd_events; fde; fde = next) {
+ for (fde = ev->fd_events; fde; fde = fde->next) {
uint16 flags = 0;
- next = fde->next;
if (FD_ISSET(fde->fd, read_fds)) flags |= EVENT_FD_READ;
if (FD_ISSET(fde->fd, write_fds)) flags |= EVENT_FD_WRITE;
if (flags & fde->flags) {
fde->handler(ev, fde, flags, fde->private_data);
- fired = true;
+ return true;
}
}
- return fired;
+ return false;
}