From 5fda87c6986d7a734b73b21afac13eb80242012b Mon Sep 17 00:00:00 2001 From: root Date: Tue, 14 Jul 2009 20:31:21 +0000 Subject: *** empty log message *** --- ev.c | 12 ++++++++++++ ev.h | 1 + ev.pod | 17 +++++++++++++---- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/ev.c b/ev.c index 82de10f..a6f414f 100644 --- a/ev.c +++ b/ev.c @@ -1842,6 +1842,18 @@ ev_invoke (EV_P_ void *w, int revents) EV_CB_INVOKE ((W)w, revents); } +unsigned int +ev_pending_count (EV_P) +{ + int pri; + unsigned int count = 0; + + for (pri = NUMPRI; pri--; ) + count += pendingcnt [pri]; + + return count; +} + void noinline ev_invoke_pending (EV_P) { diff --git a/ev.h b/ev.h index a40528c..0d00f0b 100644 --- a/ev.h +++ b/ev.h @@ -553,6 +553,7 @@ void *ev_userdata (EV_P); void ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P)); void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P)); +unsigned int ev_pending_count (EV_P); /* number of pending events, if any */ void ev_invoke_pending (EV_P); /* invoke all pending watchers */ /* diff --git a/ev.pod b/ev.pod index 0e32388..ec747e8 100644 --- a/ev.pod +++ b/ev.pod @@ -864,6 +864,11 @@ This call will simply invoke all pending watchers while resetting their pending state. Normally, C does this automatically when required, but when overriding the invoke callback this call comes handy. +=item int ev_pending_count (loop) + +Returns the number of pending watchers - zero indicates that no watchers +are pending. + =item ev_set_invoke_pending_cb (loop, void (*invoke_pending_cb)(EV_P)) This overrides the invoke pending functionality of the loop: Instead of @@ -4030,16 +4035,20 @@ into C: Instead of invoking all pending watchers, the C callback will signal the main thread via some unspecified mechanism (signals? pipe writes? C?) and then waits until all pending watchers -have been called: +have been called (in a while loop because a) spurious wakeups are possible +and b) skipping inter-thread-communication when there are no pending +watchers is very beneficial): static void l_invoke (EV_P) { userdata *u = ev_userdata (EV_A); - wake_up_other_thread_in_some_magic_or_not_so_magic_way (); - - pthread_cond_wait (&u->invoke_cv, &u->lock); + while (ev_pending_count (EV_A)) + { + wake_up_other_thread_in_some_magic_or_not_so_magic_way (); + pthread_cond_wait (&u->invoke_cv, &u->lock); + } } Now, whenever the main thread gets told to invoke pending watchers, it -- cgit v1.2.3