diff options
Diffstat (limited to 'lib/thread.c')
| -rw-r--r-- | lib/thread.c | 126 |
1 files changed, 81 insertions, 45 deletions
diff --git a/lib/thread.c b/lib/thread.c index 3fb28bce26..e4dbebe1c4 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -454,6 +454,7 @@ thread_add_unuse (struct thread_master *m, struct thread *thread) assert (m != NULL && thread != NULL); assert (thread->next == NULL); assert (thread->prev == NULL); + thread->ref = NULL; thread->type = THREAD_UNUSED; thread->hist->total_active--; @@ -725,6 +726,7 @@ fd_select (struct thread_master *m, int size, thread_fd_set *read, thread_fd_set num = poll (m->handler.pfds, m->handler.pfdcount + m->handler.pfdcountsnmp, timeout); #else struct timeval timeout; + if (m->selectpoll_timeout > 0) // use the user's timeout { timeout.tv_sec = m->selectpoll_timeout / 1000; @@ -774,15 +776,21 @@ fd_clear_read_write (struct thread *thread) } /* Add new read thread. */ -struct thread * +void funcname_thread_add_read_write (int dir, struct thread_master *m, - int (*func) (struct thread *), void *arg, int fd, - debugargdef) + int (*func) (struct thread *), void *arg, int fd, struct thread **t_ptr, + debugargdef) { struct thread *thread = NULL; pthread_mutex_lock (&m->mtx); { + if (t_ptr && *t_ptr) // thread is already scheduled; don't reschedule + { + pthread_mutex_unlock (&m->mtx); + return; + } + #if defined (HAVE_POLL_CALL) thread = generic_thread_add(m, func, arg, fd, dir, debugargpass); #else @@ -822,19 +830,20 @@ funcname_thread_add_read_write (int dir, struct thread_master *m, } pthread_mutex_unlock (&thread->mtx); } + + if (t_ptr) + { + *t_ptr = thread; + thread->ref = t_ptr; + } } pthread_mutex_unlock (&m->mtx); - - return thread; } -static struct thread * +static void funcname_thread_add_timer_timeval (struct thread_master *m, - int (*func) (struct thread *), - int type, - void *arg, - struct timeval *time_relative, - debugargdef) + int (*func) (struct thread *), int type, void *arg, + struct timeval *time_relative, struct thread **t_ptr, debugargdef) { struct thread *thread; struct pqueue *queue; @@ -846,6 +855,12 @@ funcname_thread_add_timer_timeval (struct thread_master *m, pthread_mutex_lock (&m->mtx); { + if (t_ptr && *t_ptr) // thread is already scheduled; don't reschedule + { + pthread_mutex_unlock (&m->mtx); + return; + } + queue = ((type == THREAD_TIMER) ? m->timer : m->background); thread = thread_get (m, type, func, arg, debugargpass); @@ -856,19 +871,22 @@ funcname_thread_add_timer_timeval (struct thread_master *m, pqueue_enqueue(thread, queue); } pthread_mutex_unlock (&thread->mtx); + + if (t_ptr) + { + *t_ptr = thread; + thread->ref = t_ptr; + } } pthread_mutex_unlock (&m->mtx); - - return thread; } /* Add timer event thread. */ -struct thread * +void funcname_thread_add_timer (struct thread_master *m, - int (*func) (struct thread *), - void *arg, long timer, - debugargdef) + int (*func) (struct thread *), void *arg, long timer, + struct thread **t_ptr, debugargdef) { struct timeval trel; @@ -877,16 +895,15 @@ funcname_thread_add_timer (struct thread_master *m, trel.tv_sec = timer; trel.tv_usec = 0; - return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, arg, - &trel, debugargpass); + return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, arg, &trel, + t_ptr, debugargpass); } /* Add timer event thread with "millisecond" resolution */ -struct thread * +void funcname_thread_add_timer_msec (struct thread_master *m, - int (*func) (struct thread *), - void *arg, long timer, - debugargdef) + int (*func) (struct thread *), void *arg, long timer, + struct thread **t_ptr, debugargdef) { struct timeval trel; @@ -895,27 +912,25 @@ funcname_thread_add_timer_msec (struct thread_master *m, trel.tv_sec = timer / 1000; trel.tv_usec = 1000*(timer % 1000); - return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, - arg, &trel, debugargpass); + funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, arg, &trel, + t_ptr, debugargpass); } /* Add timer event thread with "millisecond" resolution */ -struct thread * +void funcname_thread_add_timer_tv (struct thread_master *m, - int (*func) (struct thread *), - void *arg, struct timeval *tv, - debugargdef) + int (*func) (struct thread *), void *arg, struct timeval *tv, + struct thread **t_ptr, debugargdef) { - return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, - arg, tv, debugargpass); + funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, arg, tv, t_ptr, + debugargpass); } /* Add a background thread, with an optional millisec delay */ -struct thread * +void funcname_thread_add_background (struct thread_master *m, - int (*func) (struct thread *), - void *arg, long delay, - debugargdef) + int (*func) (struct thread *), void *arg, long delay, + struct thread **t_ptr, debugargdef) { struct timeval trel; @@ -932,15 +947,15 @@ funcname_thread_add_background (struct thread_master *m, trel.tv_usec = 0; } - return funcname_thread_add_timer_timeval (m, func, THREAD_BACKGROUND, - arg, &trel, debugargpass); + funcname_thread_add_timer_timeval (m, func, THREAD_BACKGROUND, arg, &trel, + t_ptr, debugargpass); } /* Add simple event thread. */ -struct thread * +void funcname_thread_add_event (struct thread_master *m, - int (*func) (struct thread *), void *arg, int val, - debugargdef) + int (*func) (struct thread *), void *arg, int val, + struct thread **t_ptr, debugargdef) { struct thread *thread; @@ -948,6 +963,12 @@ funcname_thread_add_event (struct thread_master *m, pthread_mutex_lock (&m->mtx); { + if (t_ptr && *t_ptr) // thread is already scheduled; don't reschedule + { + pthread_mutex_unlock (&m->mtx); + return; + } + thread = thread_get (m, THREAD_EVENT, func, arg, debugargpass); pthread_mutex_lock (&thread->mtx); { @@ -955,10 +976,14 @@ funcname_thread_add_event (struct thread_master *m, thread_list_add (&m->event, thread); } pthread_mutex_unlock (&thread->mtx); + + if (t_ptr) + { + *t_ptr = thread; + thread->ref = t_ptr; + } } pthread_mutex_unlock (&m->mtx); - - return thread; } static void @@ -1056,6 +1081,9 @@ thread_cancel (struct thread *thread) assert(!"Thread should be either in queue or list or array!"); } + if (thread->ref) + *thread->ref = NULL; + thread_add_unuse (thread->master, thread); done: @@ -1085,6 +1113,8 @@ thread_cancel_event (struct thread_master *m, void *arg) { ret++; thread_list_delete (&m->event, t); + if (t->ref) + *t->ref = NULL; thread_add_unuse (m, t); } } @@ -1104,6 +1134,8 @@ thread_cancel_event (struct thread_master *m, void *arg) { ret++; thread_list_delete (&m->ready, t); + if (t->ref) + *t->ref = NULL; thread_add_unuse (m, t); } } @@ -1285,6 +1317,8 @@ thread_fetch (struct thread_master *m, struct thread *fetch) if ((thread = thread_trim_head (&m->ready)) != NULL) { fetch = thread_run (m, thread, fetch); + if (fetch->ref) + *fetch->ref = NULL; pthread_mutex_unlock (&m->mtx); return fetch; } @@ -1354,6 +1388,8 @@ thread_fetch (struct thread_master *m, struct thread *fetch) if ((thread = thread_trim_head (&m->ready)) != NULL) { fetch = thread_run (m, thread, fetch); + if (fetch->ref) + *fetch->ref = NULL; pthread_mutex_unlock (&m->mtx); return fetch; } @@ -1365,6 +1401,8 @@ thread_fetch (struct thread_master *m, struct thread *fetch) if ((thread = thread_trim_head (&m->ready)) != NULL) { fetch = thread_run (m, thread, fetch); + if (fetch->ref) + *fetch->ref = NULL; pthread_mutex_unlock (&m->mtx); return fetch; } @@ -1472,7 +1510,7 @@ thread_call (struct thread *thread) } /* Execute thread */ -struct thread * +void funcname_thread_execute (struct thread_master *m, int (*func)(struct thread *), void *arg, @@ -1504,6 +1542,4 @@ funcname_thread_execute (struct thread_master *m, dummy.schedfrom_line = fromln; thread_call (&dummy); - - return NULL; } |
