[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