Bugfix: memory and thread-deleting problems
[monky] / src / common.c
index 4a8d78a..b9b093b 100644 (file)
@@ -84,9 +84,10 @@ char *strndup(const char *s, size_t n)
 }
 #endif /* HAVE_STRNDUP */
 
-void update_uname(void)
+int update_uname(void)
 {
        uname(&info.uname_s);
+       return 0;
 }
 
 double get_time(void)
@@ -268,7 +269,7 @@ void format_seconds_short(char *buf, unsigned int n, long seconds)
  * Populated while initialising text objects in construct_text_object(). */
 static struct update_cb {
        struct update_cb *next;
-       void (*func)(void);
+       int (*func)(void);
        pthread_t thread;
        sem_t start_wait, end_wait;
 
@@ -286,7 +287,7 @@ static int threading_started = 0;
 
 /* Register an update callback. Don't allow duplicates, to minimise side
  * effects and overhead. */
-void add_update_callback(void (*func)(void))
+void add_update_callback(int (*func)(void))
 {
        struct update_cb *uc = &update_cb_head;
 
@@ -376,7 +377,12 @@ static void *run_update_callback(void *data)
        while (1) {
                if (sem_wait(&ucb->start_wait)) pthread_exit(NULL);
                if (ucb->running == 0) pthread_exit(NULL);
-               (*ucb->func)();
+               if((*ucb->func)()) {
+                       ucb->next = ucb;        //this is normally not be possible, so we use it to show that there was a critical error
+                       sem_post(&ucb->end_wait);
+                       sem_post(&ucb->end_wait);
+                       pthread_exit(NULL);
+               }
                if (sem_post(&ucb->end_wait)) pthread_exit(NULL);
        }
 }
@@ -411,8 +417,14 @@ void update_stuff(void)
        }
        /* need to synchronise here, otherwise locking is needed (as data
         * would be printed with some update callbacks still running) */
-       for (uc = update_cb_head.next; uc; uc = uc->next)
+       for (uc = update_cb_head.next; uc; uc = uc->next) {
                sem_wait(&uc->end_wait);
+               if(uc == uc->next) {
+                       pthread_join(uc->thread, NULL);
+                       free(uc);
+                       exit(EXIT_FAILURE);
+               }
+       }
 
        /* XXX: move the following into the update_meminfo() functions? */
        if (no_buffers) {