1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-26 10:04:02 +03:00

s3-events: make the old timed events compatible with tevent

tevent ensures that a timed event is only called once. The old events
code relied on the called handler removing the event itself. If the
handler removed the event after calling a function which invoked the
event loop then the timed event could loop forever.

This change makes the two timed event systems more compatible, by
allowing the handler to free the te if it wants to, but ensuring it is
off the linked list of events before the handler is called, and
ensuring it is freed even if the handler doesn't free it.
This commit is contained in:
Andrew Tridgell 2010-02-05 19:14:45 -08:00 committed by Jeremy Allison
parent dd498d2eec
commit 5dbf175c75

View File

@ -105,12 +105,29 @@ bool run_events(struct tevent_context *ev,
if ((ev->timer_events != NULL)
&& (timeval_compare(&now, &ev->timer_events->next_event) >= 0)) {
/* this older events system did not auto-free timed
events on running them, and had a race condition
where the event could be called twice if the
talloc_free of the te happened after the callback
made a call which invoked the event loop. To avoid
this while still allowing old code which frees the
te, we need to create a temporary context which
will be used to ensure the te is freed. We also
remove the te from the timed event list before we
call the handler, to ensure we can't loop */
struct tevent_timer *te = ev->timer_events;
TALLOC_CTX *tmp_ctx = talloc_new(ev);
DEBUG(10, ("Running timed event \"%s\" %p\n",
ev->timer_events->handler_name, ev->timer_events));
ev->timer_events->handler(ev, ev->timer_events, now,
ev->timer_events->private_data);
DLIST_REMOVE(ev->timer_events, te);
talloc_steal(tmp_ctx, te);
te->handler(ev, te, now, te->private_data);
talloc_free(tmp_ctx);
return true;
}