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
