[sheepdog] [PATCH] collie: allow calling queue_work() in done()

MORITA Kazutaka morita.kazutaka at gmail.com
Tue May 14 16:56:11 CEST 2013


From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>

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 <morita.kazutaka at lab.ntt.co.jp>
---
 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




More information about the sheepdog mailing list