-/* $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
*
* 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 <config.h>
#include <assert.h>
#include <errno.h>
#include <time.h>
+#include <unistd.h>
#ifndef HAVE_CLOCK_GETTIME
#include <sys/time.h>
#endif
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 */
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
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,
/* 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) {
/* 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;
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);
{
assert(p_timed_thread != NULL);
+ close(p_timed_thread->pipefd[0]);
+ close(p_timed_thread->pipefd[1]);
+
pthread_exit(NULL);
}