X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Ftimed_thread.c;h=ee4346dcdca5a7369c947f7c9d2837fe65e5945a;hb=b951f0f45f60917eea7104e44d0f14c3e0d1f189;hp=678d0ab2235b75b01b0ec2081612eee782ec5322;hpb=7de6c1d06199e2dc00ed6b147542ce75a33bc0fe;p=monky diff --git a/src/timed_thread.c b/src/timed_thread.c index 678d0ab..ee4346d 100644 --- a/src/timed_thread.c +++ b/src/timed_thread.c @@ -1,6 +1,7 @@ -/* $Id$ */ - -/* timed_thread.c: Abstraction layer for timed threads +/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*- + * vim: ts=4 sw=4 noet ai cindent syntax=c + * + * timed_thread.c: Abstraction layer for timed threads * * Copyright (C) 2006-2007 Philip Kovacs pkovacs@users.sourceforge.net * @@ -17,7 +18,9 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 - * USA. */ + * USA. + * + */ #ifdef HAVE_CONFIG_H #include @@ -27,6 +30,7 @@ #include #include #include +#include #ifndef HAVE_CLOCK_GETTIME #include #endif @@ -47,6 +51,8 @@ struct _timed_thread { void *arg; /* thread function argument */ struct timespec interval_time; /* interval_usecs as a struct timespec */ struct timespec wait_time; /* absolute future time next timed_thread_test will wait until */ + int pipefd[2]; + int die; }; /* linked list of created threads */ @@ -59,6 +65,11 @@ typedef struct _timed_thread_list { static timed_thread_list *p_timed_thread_list_head = NULL; static timed_thread_list *p_timed_thread_list_tail = NULL; +int timed_thread_readfd(timed_thread *p_timed_thread) +{ + return p_timed_thread->pipefd[0]; +} + static int now(struct timespec *abstime) { #ifndef HAVE_CLOCK_GETTIME @@ -96,6 +107,11 @@ timed_thread *timed_thread_create(void *start_routine(void *), void *arg, return NULL; } + /* create thread pipe (used to tell threads to die) */ + if (pipe(p_timed_thread->pipefd)) { + return NULL; + } + /* init attributes, e.g. joinable thread */ pthread_attr_init(&p_timed_thread->thread_attr); pthread_attr_setdetachstate(&p_timed_thread->thread_attr, @@ -146,7 +162,9 @@ void timed_thread_destroy(timed_thread *p_timed_thread, /* signal thread to stop */ pthread_mutex_lock(&p_timed_thread->runnable_mutex); pthread_cond_signal(&p_timed_thread->runnable_cond); + p_timed_thread->die = 1; pthread_mutex_unlock(&p_timed_thread->runnable_mutex); + write(p_timed_thread->pipefd[1], "die", 3); /* join the terminating thread */ if (p_timed_thread->thread) { @@ -184,7 +202,7 @@ int timed_thread_unlock(timed_thread *p_timed_thread) /* thread waits interval_usecs for runnable_cond to be signaled. * returns 1 if signaled, -1 on error, and 0 otherwise. * caller should call timed_thread_exit() on any non-zero return value. */ -int timed_thread_test(timed_thread *p_timed_thread) +int timed_thread_test(timed_thread *p_timed_thread, int override_wait_time) { struct timespec now_time; int rc; @@ -198,6 +216,15 @@ int timed_thread_test(timed_thread *p_timed_thread) return -1; } + if (p_timed_thread->die) { + /* if we were kindly asked to die, then die */ + return 1; + } + + if (override_wait_time && now(&p_timed_thread->wait_time)) { + return -1; + } + /* release mutex and wait until future time for runnable_cond to signal */ rc = pthread_cond_timedwait(&p_timed_thread->runnable_cond, &p_timed_thread->runnable_mutex, &p_timed_thread->wait_time); @@ -236,6 +263,9 @@ void timed_thread_exit(timed_thread *p_timed_thread) { assert(p_timed_thread != NULL); + close(p_timed_thread->pipefd[0]); + close(p_timed_thread->pipefd[1]); + pthread_exit(NULL); }