From: MORITA Kazutaka <[email protected]>

Currently, if we call queue_work() in the second event_loop(),
work_queue_wait() cannot wait for completion of the work.  This fixes
the problem.

Signed-off-by: MORITA Kazutaka <[email protected]>
---
 collie/common.c |   19 ++++++++++++-------
 include/event.h |    4 ++--
 lib/event.c     |   19 ++++++++++---------
 3 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/collie/common.c b/collie/common.c
index 0646587..bf52e0c 100644
--- a/collie/common.c
+++ b/collie/common.c
@@ -251,11 +251,16 @@ void work_queue_wait(struct work_queue *q)
 {
        assert(is_main_thread());
 
-       while (!work_queue_empty(q))
-               event_loop(-1);
-       /*
-        * We have to call event_loop() again because some works are remained in
-        * the finished list.
-        */
-       event_loop(-1);
+       while (true) {
+               if (work_queue_empty(q)) {
+                       /*
+                        * If there is no pending works, exit event_loop()
+                        * immediately even if no events are available.
+                        */
+                       if (event_loop(0) == 0)
+                               break;
+               } else
+                       /* wait for at least one event */
+                       event_loop(-1);
+       }
 }
diff --git a/include/event.h b/include/event.h
index 8f8b21f..555d856 100644
--- a/include/event.h
+++ b/include/event.h
@@ -12,8 +12,8 @@ int init_event(int nr);
 int register_event_prio(int fd, event_handler_t h, void *data, int prio);
 void unregister_event(int fd);
 int modify_event(int fd, unsigned int events);
-void event_loop(int timeout);
-void event_loop_prio(int timeout);
+int event_loop(int timeout);
+int event_loop_prio(int timeout);
 void event_force_refresh(void);
 
 struct timer {
diff --git a/lib/event.c b/lib/event.c
index 5b15925..5926650 100644
--- a/lib/event.c
+++ b/lib/event.c
@@ -24,8 +24,6 @@
 static int efd;
 static LIST_HEAD(events_list);
 
-#define TICK 1
-
 static void timer_handler(int fd, int events, void *data)
 {
        struct timer *t = data;
@@ -189,18 +187,19 @@ static int epoll_event_cmp(const void *_a, const void *_b)
        return 0;
 }
 
-static void do_event_loop(int timeout, bool sort_with_prio)
+/* return the number of processed events */
+static int do_event_loop(int timeout, bool sort_with_prio)
 {
        int i, nr;
 
 refresh:
-       nr = epoll_wait(efd, events, nr_events, TICK * 1000);
+       nr = epoll_wait(efd, events, nr_events, timeout);
        if (sort_with_prio)
                qsort(events, nr, sizeof(struct epoll_event), epoll_event_cmp);
 
        if (nr < 0) {
                if (errno == EINTR)
-                       return;
+                       return nr;
                sd_eprintf("epoll_wait failed: %m");
                exit(1);
        } else if (nr) {
@@ -216,14 +215,16 @@ refresh:
                        }
                }
        }
+
+       return nr;
 }
 
-void event_loop(int timeout)
+int event_loop(int timeout)
 {
-       do_event_loop(timeout, false);
+       return do_event_loop(timeout, false);
 }
 
-void event_loop_prio(int timeout)
+int event_loop_prio(int timeout)
 {
-       do_event_loop(timeout, true);
+       return do_event_loop(timeout, true);
 }
-- 
1.7.9.5

-- 
sheepdog mailing list
[email protected]
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to