X-Git-Url: http://git.archive.openwrt.org/?p=project%2Flibubox.git;a=blobdiff_plain;f=uloop.c;h=8517366a55f19154b25a67dd21ce1e08f09e1589;hp=e60fb09705aa8c0dc4768127eeac09f5298ee9e8;hb=f714be125c9b85e184a482bc22e958b5cadfad3a;hpb=c2f2c47f3e9a2d709ec82a79f6fadd3124c18781 diff --git a/uloop.c b/uloop.c index e60fb09..8517366 100644 --- a/uloop.c +++ b/uloop.c @@ -58,10 +58,13 @@ static struct list_head processes = LIST_HEAD_INIT(processes); static int poll_fd = -1; bool uloop_cancelled = false; +bool uloop_handle_sigchld = true; +static int uloop_status = 0; static bool do_sigchld = false; static struct uloop_fd_event cur_fds[ULOOP_MAX_EVENTS]; static int cur_fd, cur_nfds; +static int uloop_run_depth = 0; int uloop_fd_add(struct uloop_fd *sock, unsigned int flags); @@ -114,6 +117,8 @@ static int waker_init(void) return 0; } +static void uloop_setup_signals(bool add); + int uloop_init(void) { if (uloop_init_pollfd() < 0) @@ -124,6 +129,8 @@ int uloop_init(void) return -1; } + uloop_setup_signals(true); + return 0; } @@ -386,11 +393,18 @@ static void uloop_handle_processes(void) static void uloop_signal_wake(void) { - write(waker_pipe, "w", 1); + do { + if (write(waker_pipe, "w", 1) < 0) { + if (errno == EINTR) + continue; + } + break; + } while (1); } static void uloop_handle_sigint(int signo) { + uloop_status = signo; uloop_cancelled = true; uloop_signal_wake(); } @@ -453,7 +467,9 @@ static void uloop_setup_signals(bool add) uloop_install_handler(SIGINT, uloop_handle_sigint, &old_sigint, add); uloop_install_handler(SIGTERM, uloop_handle_sigint, &old_sigterm, add); - uloop_install_handler(SIGCHLD, uloop_sigchld, &old_sigchld, add); + + if (uloop_handle_sigchld) + uloop_install_handler(SIGCHLD, uloop_sigchld, &old_sigchld, add); uloop_ignore_signal(SIGPIPE, add); } @@ -506,20 +522,21 @@ static void uloop_clear_processes(void) uloop_process_delete(p); } -void uloop_run(void) +bool uloop_cancelling(void) { - static int recursive_calls = 0; + return uloop_run_depth > 0 && uloop_cancelled; +} + +int uloop_run_timeout(int timeout) +{ + int next_time = 0; struct timeval tv; - /* - * Handlers are only updated for the first call to uloop_run() (and restored - * when this call is done). - */ - if (!recursive_calls++) - uloop_setup_signals(true); + uloop_run_depth++; + uloop_status = 0; uloop_cancelled = false; - while(!uloop_cancelled) + while (!uloop_cancelled) { uloop_gettime(&tv); uloop_process_timeouts(&tv); @@ -531,15 +548,22 @@ void uloop_run(void) break; uloop_gettime(&tv); - uloop_run_events(uloop_get_next_timeout(&tv)); + + next_time = uloop_get_next_timeout(&tv); + if (timeout >= 0 && timeout < next_time) + next_time = timeout; + uloop_run_events(next_time); } - if (!--recursive_calls) - uloop_setup_signals(false); + --uloop_run_depth; + + return uloop_status; } void uloop_done(void) { + uloop_setup_signals(false); + if (poll_fd >= 0) { close(poll_fd); poll_fd = -1;