summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/lib/events/events_aio.c7
-rw-r--r--source4/lib/events/events_epoll.c7
-rw-r--r--source4/lib/events/events_internal.h3
-rw-r--r--source4/lib/events/events_select.c7
-rw-r--r--source4/lib/events/events_standard.c10
-rw-r--r--source4/lib/events/events_timed.c74
6 files changed, 60 insertions, 48 deletions
diff --git a/source4/lib/events/events_aio.c b/source4/lib/events/events_aio.c
index 9f4e9c5612..0eadcf5fec 100644
--- a/source4/lib/events/events_aio.c
+++ b/source4/lib/events/events_aio.c
@@ -250,7 +250,8 @@ static int aio_event_loop(struct aio_event_context *aio_ev, struct timeval *tval
}
if (ret == 0 && tvalp) {
- common_event_loop_timer(aio_ev->ev);
+ /* we don't care about a possible delay here */
+ common_event_loop_timer_delay(aio_ev->ev);
return 0;
}
@@ -431,10 +432,8 @@ static int aio_event_loop_once(struct event_context *ev)
struct aio_event_context);
struct timeval tval;
- tval = common_event_loop_delay(ev);
-
+ tval = common_event_loop_timer_delay(ev);
if (timeval_is_zero(&tval)) {
- common_event_loop_timer(ev);
return 0;
}
diff --git a/source4/lib/events/events_epoll.c b/source4/lib/events/events_epoll.c
index 41a6509e36..2f879cc410 100644
--- a/source4/lib/events/events_epoll.c
+++ b/source4/lib/events/events_epoll.c
@@ -233,7 +233,8 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
}
if (ret == 0 && tvalp) {
- common_event_loop_timer(epoll_ev->ev);
+ /* we don't care about a possible delay here */
+ common_event_loop_timer_delay(epoll_ev->ev);
return 0;
}
@@ -376,10 +377,8 @@ static int epoll_event_loop_once(struct event_context *ev)
struct epoll_event_context);
struct timeval tval;
- tval = common_event_loop_delay(ev);
-
+ tval = common_event_loop_timer_delay(ev);
if (timeval_is_zero(&tval)) {
- common_event_loop_timer(ev);
return 0;
}
diff --git a/source4/lib/events/events_internal.h b/source4/lib/events/events_internal.h
index 04b92df550..fb15665c0a 100644
--- a/source4/lib/events/events_internal.h
+++ b/source4/lib/events/events_internal.h
@@ -117,8 +117,7 @@ bool event_register_backend(const char *name, const struct event_ops *ops);
struct timed_event *common_event_add_timed(struct event_context *, TALLOC_CTX *,
struct timeval, event_timed_handler_t, void *);
-void common_event_loop_timer(struct event_context *);
-struct timeval common_event_loop_delay(struct event_context *);
+struct timeval common_event_loop_timer_delay(struct event_context *);
struct signal_event *common_event_add_signal(struct event_context *ev,
TALLOC_CTX *mem_ctx,
diff --git a/source4/lib/events/events_select.c b/source4/lib/events/events_select.c
index 291ddbde2b..b2f9cacf5f 100644
--- a/source4/lib/events/events_select.c
+++ b/source4/lib/events/events_select.c
@@ -218,7 +218,8 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru
}
if (selrtn == 0 && tvalp) {
- common_event_loop_timer(select_ev->ev);
+ /* we don't care about a possible delay here */
+ common_event_loop_timer_delay(select_ev->ev);
return 0;
}
@@ -252,10 +253,8 @@ static int select_event_loop_once(struct event_context *ev)
struct select_event_context);
struct timeval tval;
- tval = common_event_loop_delay(ev);
-
+ tval = common_event_loop_timer_delay(ev);
if (timeval_is_zero(&tval)) {
- common_event_loop_timer(ev);
return 0;
}
diff --git a/source4/lib/events/events_standard.c b/source4/lib/events/events_standard.c
index 8495ccdec0..dcf890ac12 100644
--- a/source4/lib/events/events_standard.c
+++ b/source4/lib/events/events_standard.c
@@ -248,7 +248,8 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
}
if (ret == 0 && tvalp) {
- common_event_loop_timer(std_ev->ev);
+ /* we don't care about a possible delay here */
+ common_event_loop_timer_delay(std_ev->ev);
return 0;
}
@@ -471,7 +472,8 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
}
if (selrtn == 0 && tvalp) {
- common_event_loop_timer(std_ev->ev);
+ /* we don't care about a possible delay here */
+ common_event_loop_timer_delay(std_ev->ev);
return 0;
}
@@ -505,10 +507,8 @@ static int std_event_loop_once(struct event_context *ev)
struct std_event_context);
struct timeval tval;
- tval = common_event_loop_delay(ev);
-
+ tval = common_event_loop_timer_delay(ev);
if (timeval_is_zero(&tval)) {
- common_event_loop_timer(ev);
return 0;
}
diff --git a/source4/lib/events/events_timed.c b/source4/lib/events/events_timed.c
index c85f8371c1..31619dcb5f 100644
--- a/source4/lib/events/events_timed.c
+++ b/source4/lib/events/events_timed.c
@@ -68,9 +68,7 @@ struct timed_event *common_event_add_timed(struct event_context *ev, TALLOC_CTX
last_te = NULL;
for (cur_te = ev->timed_events; cur_te; cur_te = cur_te->next) {
/* if the new event comes before the current one break */
- if (!timeval_is_zero(&cur_te->next_event) &&
- timeval_compare(&te->next_event,
- &cur_te->next_event) < 0) {
+ if (timeval_compare(&te->next_event, &cur_te->next_event) < 0) {
break;
}
@@ -85,17 +83,47 @@ struct timed_event *common_event_add_timed(struct event_context *ev, TALLOC_CTX
}
/*
- a timer has gone off - call it
+ do a single event loop using the events defined in ev
+
+ return the delay untill the next timed event,
+ or zero if a timed event was triggered
*/
-void common_event_loop_timer(struct event_context *ev)
+struct timeval common_event_loop_timer_delay(struct event_context *ev)
{
- struct timeval t = timeval_current();
+ struct timeval current_time = timeval_zero();
struct timed_event *te = ev->timed_events;
- if (te == NULL) {
- return;
+ if (!te) {
+ /* have a default tick time of 30 seconds. This guarantees
+ that code that uses its own timeout checking will be
+ able to proceeed eventually */
+ return timeval_set(30, 0);
}
+ /*
+ * work out the right timeout for the next timed event
+ *
+ * avoid the syscall to gettimeofday() if the timed event should
+ * be triggered directly
+ *
+ * if there's a delay till the next timed event, we're done
+ * with just returning the delay
+ */
+ if (!timeval_is_zero(&te->next_event)) {
+ struct timeval delay;
+
+ current_time = timeval_current();
+
+ delay = timeval_until(&current_time, &te->next_event);
+ if (!timeval_is_zero(&delay)) {
+ return delay;
+ }
+ }
+
+ /*
+ * ok, we have a timed event that we'll process ...
+ */
+
/* deny the handler to free the event */
talloc_set_destructor(te, common_event_timed_deny_destructor);
@@ -104,33 +132,21 @@ void common_event_loop_timer(struct event_context *ev)
* handler we don't want to come across this event again -- vl */
DLIST_REMOVE(ev->timed_events, te);
- te->handler(ev, te, t, te->private_data);
+ /*
+ * If the timed event was registered for a zero current_time,
+ * then we pass a zero timeval here too! To avoid the
+ * overhead of gettimeofday() calls.
+ *
+ * otherwise we pass the current time
+ */
+ te->handler(ev, te, current_time, te->private_data);
/* The destructor isn't necessary anymore, we've already removed the
* event from the list. */
talloc_set_destructor(te, NULL);
talloc_free(te);
-}
-/*
- do a single event loop using the events defined in ev
-*/
-struct timeval common_event_loop_delay(struct event_context *ev)
-{
- struct timeval tval;
-
- /* work out the right timeout for all timed events */
- if (ev->timed_events) {
- struct timeval t = timeval_current();
- tval = timeval_until(&t, &ev->timed_events->next_event);
- } else {
- /* have a default tick time of 30 seconds. This guarantees
- that code that uses its own timeout checking will be
- able to proceeed eventually */
- tval = timeval_set(30, 0);
- }
-
- return tval;
+ return timeval_zero();
}