X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=ucw%2Fmainloop.c;h=091b5f186957c152ee3a4bc437679f6a4b7953d6;hb=1d62db61c7a34454ee9380c08c0fc8ebcc262687;hp=b7ee5bf989c52baac52b3e988d567e20ffea415c;hpb=cd7dce2a6e06894c5e8c24ae399fe1900d6462e1;p=libucw.git diff --git a/ucw/mainloop.c b/ucw/mainloop.c index b7ee5bf9..091b5f18 100644 --- a/ucw/mainloop.c +++ b/ucw/mainloop.c @@ -1,7 +1,7 @@ /* * UCW Library -- Main Loop * - * (c) 2004--2011 Martin Mares + * (c) 2004--2012 Martin Mares * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -9,11 +9,13 @@ #undef LOCAL_DEBUG -#include "ucw/lib.h" -#include "ucw/heap.h" -#include "ucw/mainloop.h" -#include "ucw/threads.h" -#include "ucw/gary.h" +#include +#include +#include +#include +#include +#include +#include #include #include @@ -49,10 +51,7 @@ static void signal_del_ctx(struct main_context *m, struct main_signal *ms); static void main_get_time_ctx(struct main_context *m) { - struct timeval tv; - gettimeofday(&tv, NULL); - m->now_seconds = tv.tv_sec; - m->now = (timestamp_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; + m->now = get_timestamp(); } static struct main_context * @@ -75,7 +74,7 @@ main_is_current(struct main_context *m) return (m == main_current_nocheck()); } -static inline uns +static inline uint count_timers(struct main_context *m) { if (m->timer_table) @@ -100,7 +99,7 @@ main_new(void) m->epoll_fd = epoll_create(64); if (m->epoll_fd < 0) die("epoll_create() failed: %m"); - m->epoll_events = xmalloc(EPOLL_BUF_SIZE * sizeof(struct epoll_event *)); + m->epoll_events = xmalloc(EPOLL_BUF_SIZE * sizeof(struct epoll_event)); clist_init(&m->file_recalc_list); #else m->poll_table_obsolete = 1; @@ -254,20 +253,20 @@ timer_add(struct main_timer *tm, timestamp_t expires) DBG("MAIN: Setting timer %p (expire at now+%lld)", tm, (long long)(expires - m->now)); else DBG("MAIN: Clearing timer %p", tm); - uns num_timers = count_timers(m); + uint num_timers = count_timers(m); if (tm->expires < expires) { if (!tm->expires) { tm->expires = expires; tm->index = num_timers + 1; - *GARY_PUSH(m->timer_table, 1) = tm; - HEAP_INSERT(struct main_timer *, m->timer_table, tm->index, MAIN_TIMER_LESS, MAIN_TIMER_SWAP); + GARY_RESIZE(m->timer_table, num_timers + 2); + HEAP_INSERT(struct main_timer *, m->timer_table, num_timers, MAIN_TIMER_LESS, MAIN_TIMER_SWAP, tm); } else { tm->expires = expires; - HEAP_INCREASE(struct main_timer *, m->timer_table, num_timers, MAIN_TIMER_LESS, MAIN_TIMER_SWAP, tm->index); + HEAP_INCREASE(struct main_timer *, m->timer_table, num_timers, MAIN_TIMER_LESS, MAIN_TIMER_SWAP, tm->index, tm); } } else if (tm->expires > expires) @@ -278,12 +277,12 @@ timer_add(struct main_timer *tm, timestamp_t expires) HEAP_DELETE(struct main_timer *, m->timer_table, num_timers, MAIN_TIMER_LESS, MAIN_TIMER_SWAP, tm->index); tm->index = 0; tm->expires = 0; - GARY_POP(m->timer_table, 1); + GARY_POP(m->timer_table); } else { tm->expires = expires; - HEAP_DECREASE(struct main_timer *, m->timer_table, num_timers, MAIN_TIMER_LESS, MAIN_TIMER_SWAP, tm->index); + HEAP_DECREASE(struct main_timer *, m->timer_table, num_timers, MAIN_TIMER_LESS, MAIN_TIMER_SWAP, tm->index, tm); } } } @@ -301,10 +300,10 @@ timer_del(struct main_timer *tm) timer_add(tm, 0); } -static uns +static uint file_want_events(struct main_file *fi) { - uns events = 0; + uint events = 0; if (fi->read_handler) events |= POLLIN; if (fi->write_handler) @@ -355,7 +354,8 @@ file_del_ctx(struct main_context *m, struct main_file *fi) // XXX: Can be called on a non-current context DBG("MAIN: Deleting file %p (fd=%d)", fi, fi->fd); - ASSERT(file_is_active(fi)); + if (!file_is_active(fi)) + return; clist_unlink(&fi->n); m->file_cnt--; #ifdef CONFIG_UCW_EPOLL @@ -378,7 +378,8 @@ hook_add(struct main_hook *ho) struct main_context *m = main_current(); DBG("MAIN: Adding hook %p", ho); - ASSERT(!hook_is_active(ho)); + if (hook_is_active(ho)) + clist_unlink(&ho->n); clist_add_tail(&m->hook_list, &ho->n); } @@ -386,8 +387,8 @@ void hook_del(struct main_hook *ho) { DBG("MAIN: Deleting hook %p", ho); - ASSERT(hook_is_active(ho)); - clist_unlink(&ho->n); + if (hook_is_active(ho)) + clist_unlink(&ho->n); } static void @@ -436,8 +437,8 @@ void process_del(struct main_process *mp) { DBG("MAIN: Deleting process %p (pid=%d)", mp, mp->pid); - ASSERT(process_is_active(mp)); - clist_unlink(&mp->n); + if (process_is_active(mp)) + clist_unlink(&mp->n); } int @@ -533,7 +534,9 @@ signal_handler_pipe(int signum) #ifdef LOCAL_DEBUG msg(L_DEBUG | L_SIGHANDLER, "MAIN: Sigpipe: sending signal %d down the drain", signum); #endif - write(m->sig_pipe_send, &signum, sizeof(signum)); + if (write(m->sig_pipe_send, &signum, sizeof(signum)) < 0) + { + } } void @@ -568,7 +571,8 @@ signal_del_ctx(struct main_context *m, struct main_signal *ms) // XXX: Can be called on a non-current context DBG("MAIN: Deleting signal %p (sig=%d)", ms, ms->signum); - ASSERT(signal_is_active(ms)); + if (!signal_is_active(ms)) + return; clist_unlink(&ms->n); int another = 0; @@ -594,7 +598,7 @@ signal_del(struct main_signal *ms) signal_del_ctx(main_current(), ms); } -#ifdef CONFIG_DEBUG +#ifdef CONFIG_UCW_DEBUG void file_debug(struct main_file *fi) @@ -641,8 +645,8 @@ main_debug_context(struct main_context *m UNUSED) { msg(L_DEBUG, "### Main loop status on %lld", (long long) m->now); msg(L_DEBUG, "\tActive timers:"); - uns num_timers = count_timers(m); - for (uns i = 1; i <= num_timers; i++) + uint num_timers = count_timers(m); + for (uint i = 1; i <= num_timers; i++) timer_debug(m->timer_table[i]); msg(L_DEBUG, "\tActive files:"); CLIST_FOR_EACH(struct main_file *, fi, m->file_list) @@ -836,7 +840,7 @@ main_loop(void) #else struct pollfd *p = m->poll_table; struct main_file **pf = m->poll_file_table; - for (uns i=0; i < m->file_cnt; i++) + for (uint i=0; i < m->file_cnt; i++) if (p[i].revents) { struct main_file *fi = pf[i]; @@ -856,14 +860,6 @@ main_loop(void) struct main_file *fi; while (fi = clist_head(&m->file_active_list)) { - if (fi->write_handler && (fi->events & (POLLOUT | POLLHUP | POLLERR))) - { - fi->events &= ~(POLLOUT | POLLHUP | POLLERR); - do - DBG("MAIN: Write event on fd %d", fi->fd); - while (fi->write_handler && fi->write_handler(fi)); - continue; - } if (fi->read_handler && (fi->events & (POLLIN | POLLHUP))) { fi->events &= ~(POLLIN | POLLHUP); @@ -872,6 +868,14 @@ main_loop(void) while (fi->read_handler && fi->read_handler(fi)); continue; } + if (fi->write_handler && (fi->events & (POLLOUT | POLLHUP | POLLERR))) + { + fi->events &= ~(POLLOUT | POLLHUP | POLLERR); + do + DBG("MAIN: Write event on fd %d", fi->fd); + while (fi->write_handler && fi->write_handler(fi)); + continue; + } clist_remove(&fi->n); clist_add_tail(&m->file_list, &fi->n); }