read some more battery data using new bme.c file but not stable, crashes after 23...
[monky] / src / timed_thread.c
index 678d0ab..ee4346d 100644 (file)
@@ -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 <config.h>
@@ -27,6 +30,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <time.h>
+#include <unistd.h>
 #ifndef HAVE_CLOCK_GETTIME
 #include <sys/time.h>
 #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);
 }