convert all thread activity to timed thread abstraction
authorPhilip Kovacs <pkovacs@users.sourceforge.net>
Wed, 15 Nov 2006 01:20:49 +0000 (01:20 +0000)
committerPhilip Kovacs <pkovacs@users.sourceforge.net>
Wed, 15 Nov 2006 01:20:49 +0000 (01:20 +0000)
git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky1@772 7f574dfc-610e-0410-a909-a81674777703

ChangeLog
src/audacious.c
src/conky.c
src/conky.h
src/timed_thread.c
src/timed_thread.h

index 3cbd71f..b05c9ac 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,8 @@
 2006-11-14
        * Fix compile error with --disable-x11.
        * Add new timed thread abstraction file.
+       * Convert thread activity to timed threads, including
+       texeci, imap, pop3, audacious.
 
 2006-11-13
        * Use pthread_cond_timedwait() instead of sleep() in audacious
index a601e90..b4b6147 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  * --------------------------------------------------------------------------- */
 
-#include <pthread.h>
-#include <errno.h>
 #include <stdio.h>
 #include <string.h>
-#include <unistd.h>
 
 #include <glib.h>
 #include <audacious/beepctrl.h>
@@ -32,6 +29,7 @@
 #include "config.h"
 #include "conky.h"
 #include "audacious.h"
+#include "timed_thread.h"
 
 /* access to this item array is synchronized */
 static audacious_t audacious_items;
@@ -46,9 +44,12 @@ void update_audacious(void)
       conky thread.  We merely copy the audacious_items array into the main thread's 
       info structure when the main thread's update cycle fires. 
     */
-    pthread_mutex_lock(&info.audacious.item_mutex);
+    if (!info.audacious.p_timed_thread)
+       return;
+
+    timed_thread_lock (info.audacious.p_timed_thread);
     memcpy(&info.audacious.items,audacious_items,sizeof(audacious_items));
-    pthread_mutex_unlock(&info.audacious.item_mutex);
+    timed_thread_unlock (info.audacious.p_timed_thread);
 }
 
 
@@ -59,20 +60,11 @@ void update_audacious(void)
  * ------------------------------------------------------------*/
 int create_audacious_thread(void)
 {
-    /* Is a worker is thread already running? */
-    if (info.audacious.thread)
-       return(-1);
-
-    /* Joinable thread for audacious activity */
-    pthread_attr_init(&info.audacious.thread_attr);
-    pthread_attr_setdetachstate(&info.audacious.thread_attr, PTHREAD_CREATE_JOINABLE);
-    /* Init mutexes */
-    pthread_mutex_init(&info.audacious.item_mutex, NULL);
-    pthread_mutex_init(&info.audacious.runnable_mutex, NULL);
-    /* Init runnable condition for worker thread */
-    pthread_cond_init(&info.audacious.runnable_cond, NULL);
-    if (pthread_create(&info.audacious.thread, &info.audacious.thread_attr, audacious_thread_func, NULL))
-        return(-1);
+    if (!info.audacious.p_timed_thread)
+       info.audacious.p_timed_thread = timed_thread_create (audacious_thread_func, NULL, 1000000);
+
+    if (!info.audacious.p_timed_thread)
+       return (-1);
 
     return 0;
 }
@@ -85,25 +77,11 @@ int create_audacious_thread(void)
 int destroy_audacious_thread(void)
 {
     /* Is a worker is thread running? If not, no error. */
-    if (!info.audacious.thread)
+    if (!info.audacious.p_timed_thread)
         return(0);
 
-    /* Signal audacious thread to terminate */
-    pthread_mutex_lock (&info.audacious.runnable_mutex);
-    pthread_cond_signal (&info.audacious.runnable_cond);
-    pthread_mutex_unlock (&info.audacious.runnable_mutex);
-
-    /* Destroy thread attribute and wait for thread */
-    pthread_attr_destroy(&info.audacious.thread_attr);
-    if (pthread_join(info.audacious.thread, NULL))
-        return(-1);
+    timed_thread_destroy (info.audacious.p_timed_thread, &info.audacious.p_timed_thread);
 
-    /* Destroy mutexes and cond */
-    pthread_mutex_destroy(&info.audacious.item_mutex);
-    pthread_mutex_destroy(&info.audacious.runnable_mutex);
-    pthread_cond_destroy(&info.audacious.runnable_cond);
-
-    info.audacious.thread=(pthread_t)0;
     return 0;
 }
 
@@ -112,20 +90,18 @@ int destroy_audacious_thread(void)
  * --------------------------------------------------- */ 
 void *audacious_thread_func(void *pvoid)
 {
-    int runnable=1;
     static audacious_t items;
     gint session,playpos,frames,length;
     gint rate,freq,chans;
     gchar *psong,*pfilename;
-    struct timespec abstime;
 
     pvoid=(void *)pvoid;  /* avoid warning */
     session=0;
     psong=NULL;
     pfilename=NULL;
 
-    /* Loop until the main thread sets the runnable signal to 0. */
-    while(runnable) {
+    /* Loop until the main thread sets the runnable signal to 0i via timed_thread_destroy. */
+    while (1) {
 
         if (!xmms_remote_is_running (session)) {
             memset(&items,0,sizeof(items));
@@ -199,24 +175,12 @@ void *audacious_thread_func(void *pvoid)
 next_iter:
 
         /* Deliver the refreshed items array to audacious_items. */
-        pthread_mutex_lock(&info.audacious.item_mutex);
+       timed_thread_lock (info.audacious.p_timed_thread);
         memcpy(&audacious_items,items,sizeof(items));
-        pthread_mutex_unlock(&info.audacious.item_mutex);
-
-        /* Get absolute time 1 sec in the future. */
-       clock_gettime (CLOCK_REALTIME, &abstime);
-       abstime.tv_sec += 1;
+       timed_thread_unlock (info.audacious.p_timed_thread);
 
-       /* Wait for a second before looping or until signalled to stop. */
-       if (pthread_cond_timedwait (&info.audacious.runnable_cond, 
-                                    &info.audacious.runnable_mutex, 
-                                    &abstime) != ETIMEDOUT)
-       {
-           runnable=0;
-           pthread_mutex_unlock (&info.audacious.runnable_mutex);
-       }
+       if (timed_thread_test (info.audacious.p_timed_thread))
+           timed_thread_exit (info.audacious.p_timed_thread);
 
     }
-
-    pthread_exit(NULL);
 }
index 8d52c0b..dbae057 100644 (file)
@@ -1138,11 +1138,17 @@ struct text_object {
                        char *cmd;
                        char *buffer;
                        double data;
-                       int pos;
-                       struct thread_info_s thread_info;
                } execi;        /* 5 */
 
                struct {
+                       float interval;
+                       char *cmd;
+                       char *buffer;
+                       double data;
+                       timed_thread *p_timed_thread;
+               } texeci;
+
+               struct {
                        int a, b;
                } pair;         /* 2 */
 #ifdef TCP_PORT_MONITOR
@@ -1172,25 +1178,6 @@ static unsigned int text_object_count;
 static struct text_object *text_objects;
 static void generate_text_internal(char *p, int p_max_size, struct text_object *objs, unsigned int object_count, struct information *cur);
 
-#define MAX_THREADS 512 // sure whatever
-typedef struct thread_info_s *thread_info;
-static thread_info thread_list[MAX_THREADS];
-static int thread_count = 0;
-static int threads_runnable = 1;
-
-int register_thread(struct thread_info_s *new_thread)
-{
-       if (thread_count >= MAX_THREADS) {
-               CRIT_ERR("Uh oh, tried to register too many threads");
-       } else {
-               thread_list[thread_count] = new_thread;
-               thread_count++;
-               // may as well fix the mutex for them as well
-               pthread_mutex_init(&(new_thread->mutex), NULL);
-       }
-       return thread_count - 1;
-}
-
 #define MAXDATASIZE 1000
 #define POP3 1
 #define IMAP 2
@@ -1262,15 +1249,12 @@ struct mail_s* parse_mail_args(char type, const char *arg) {
        } else {
                mail->command[0] = '\0';
        }
-       mail->pos = -1;
+       mail->p_timed_thread = NULL;
        return mail;
 }
 
 void *imap_thread(struct mail_s* mail)
-{                              // pthreads are really beginning to piss me off
-       double update_time;
-       int run_code = threads_runnable;
-       update_time = get_time();
+{
        int sockfd, numbytes;
        char recvbuf[MAXDATASIZE];
        char sendbuf[MAXDATASIZE];
@@ -1284,12 +1268,11 @@ void *imap_thread(struct mail_s* mail)
                herror("gethostbyname");
                exit(1);
        }
-       while (threads_runnable == run_code && fail < 5) {
+       while (fail < 5) {
                if (fail > 0) {
                        ERR("Trying IMAP connection again for %s@%s (try %i/5)", mail->user, mail->host, fail + 1);
                        sleep((int)mail->interval);
                }
-               update_time = get_time();
                if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
                        perror("socket");
                        fail++;
@@ -1406,11 +1389,11 @@ void *imap_thread(struct mail_s* mail)
                        fail++;
                        continue;
                } else {
-                       pthread_mutex_lock(&(mail->thread_info.mutex));
+                       timed_thread_lock (mail->p_timed_thread);
                        sscanf(reply, "MESSAGES %lu UNSEEN %lu",
                               &mail->messages,
                               &mail->unseen);
-                       pthread_mutex_unlock(&(mail->thread_info.mutex));
+                       timed_thread_unlock (mail->p_timed_thread);
                }
                strncpy(sendbuf, "a3 logout\n", MAXDATASIZE);
                if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
@@ -1447,32 +1430,14 @@ void *imap_thread(struct mail_s* mail)
                fail = 0;
                old_unseen = mail->unseen;
                old_messages = mail->messages;
-               mail->last_update = update_time;
-               usleep(100);    // prevent race condition
-               if (get_time() - mail->last_update >
-                   mail->interval) {
-                       continue;
-               } else {
-                       unsigned int delay =
-                           1000000.0 * (mail->interval -
-                                        (get_time() -
-                                         mail->last_update));
-                       if (delay < update_interval * 500000) {
-                               delay = update_interval * 1000000;
-                       }
-                       usleep(delay);
-               }
+               if (timed_thread_test (mail->p_timed_thread))
+                   timed_thread_exit (mail->p_timed_thread);
        }
-       ERR("exiting imap thread");
-       pthread_exit(NULL);
        return 0;
 }
 
 void *pop3_thread(struct mail_s *mail)
-{                              // pthreads are really beginning to piss me off
-       double update_time;
-       int run_code = threads_runnable;
-       update_time = get_time();
+{
        int sockfd, numbytes;
        char recvbuf[MAXDATASIZE];
        char sendbuf[MAXDATASIZE];
@@ -1485,12 +1450,11 @@ void *pop3_thread(struct mail_s *mail)
                herror("gethostbyname");
                exit(1);
        }
-       while (threads_runnable == run_code && fail < 5) {
+       while (fail < 5) {
                if (fail > 0) {
                        ERR("Trying POP3 connection again for %s@%s (try %i/5)", mail->user, mail->host, fail + 1);
                        sleep((int)mail->interval);
                }
-               update_time = get_time();
                if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
                        perror("socket");
                        fail++;
@@ -1627,11 +1591,10 @@ void *pop3_thread(struct mail_s *mail)
                        fail++;
                        continue;
                } else {
-                       pthread_mutex_lock(&(mail->thread_info.mutex));
+                       timed_thread_lock (mail->p_timed_thread);
                        sscanf(reply, "%lu %lu", &mail->unseen,
                               &mail->used);
-//                     sleep(60);
-                       pthread_mutex_unlock(&(mail->thread_info.mutex));
+                       timed_thread_unlock (mail->p_timed_thread);
                }
                strncpy(sendbuf, "QUIT\n", MAXDATASIZE);
                if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
@@ -1667,36 +1630,18 @@ void *pop3_thread(struct mail_s *mail)
                }
                fail = 0;
                old_unseen = mail->unseen;
-               mail->last_update = update_time;
-               usleep(100);    // prevent race condition
-               if (get_time() - mail->last_update >
-                   mail->interval) {
-                       continue;
-               } else {
-                       unsigned int delay =
-                           1000000.0 * (mail->interval -
-                                        (get_time() -
-                                         mail->last_update));
-                       if (delay < update_interval * 500000) {
-                               delay = update_interval * 1000000;
-                       }
-                       usleep(delay);
-               }
+               if (timed_thread_test (mail->p_timed_thread))
+                   timed_thread_exit (mail->p_timed_thread);
        }
-       ERR("exiting pop3 thread");
-       pthread_exit(NULL);
        return 0;
 }
 
 
-void *threaded_exec(struct text_object *obj) { // pthreads are really beginning to piss me off
-       double update_time;
-       int run_code = threads_runnable;
-       while (threads_runnable == run_code) {
-               update_time = get_time();
-               char *p2 = obj->data.execi.buffer;
-               FILE *fp = popen(obj->data.execi.cmd,"r");
-               pthread_mutex_lock(&(obj->data.execi.thread_info.mutex));
+void *threaded_exec(struct text_object *obj) { 
+       while (1) {
+               char *p2 = obj->data.texeci.buffer;
+               FILE *fp = popen(obj->data.texeci.cmd,"r");
+               timed_thread_lock (obj->data.texeci.p_timed_thread);
                int n2 = fread(p2, 1, TEXT_BUFFER_SIZE, fp);
                (void) pclose(fp);
                p2[n2] = '\0';
@@ -1709,21 +1654,10 @@ void *threaded_exec(struct text_object *obj) { // pthreads are really beginning
                        }
                        p2++;
                }
-               pthread_mutex_unlock(&(obj->data.execi.thread_info.mutex));
-               obj->data.execi.last_update = update_time;
-               usleep(100); // prevent race condition
-               if (get_time() - obj->data.execi.last_update > obj->data.execi.interval) {
-                       continue;
-               } else {
-                       unsigned int delay = 1000000.0 * (obj->data.execi.interval -(get_time() - obj->data.execi.last_update));
-                       if (delay < update_interval * 500000) {
-                               delay = update_interval * 1000000;
-                       }
-                       usleep(delay);
-               }
+               timed_thread_unlock (obj->data.texeci.p_timed_thread);
+               if (timed_thread_test (obj->data.texeci.p_timed_thread))
+                   timed_thread_exit (obj->data.texeci.p_timed_thread);
        }
-       ERR("exiting thread");
-       pthread_exit(NULL);
        return 0;
 }
 
@@ -1984,8 +1918,8 @@ static void free_text_objects(unsigned int count, struct text_object *objs)
                                free(objs[i].data.execi.buffer);
                                break;
                        case OBJ_texeci:
-                               free(objs[i].data.execi.cmd);
-                               free(objs[i].data.execi.buffer);
+                               free(objs[i].data.texeci.cmd);
+                               free(objs[i].data.texeci.buffer);
                                break;
                        case OBJ_top:
                                if (info.first_process) {
@@ -2278,9 +2212,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                obj->data.execi.cmd = strdup(arg + n);
        }
        END OBJ(execi, 0) unsigned int n;
-
-       if (!arg
-                       || sscanf(arg, "%f %n", &obj->data.execi.interval, &n) <= 0) {
+       if (!arg || sscanf(arg, "%f %n", &obj->data.execi.interval, &n) <= 0) {
                char buf[256];
                ERR("${execi <interval> command}");
                obj->type = OBJ_text;
@@ -2292,19 +2224,18 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                        (char *) calloc(1, TEXT_BUFFER_SIZE);
        }
        END OBJ(texeci, 0) unsigned int n;
-
-       if (!arg || sscanf(arg, "%f %n", &obj->data.execi.interval, &n) <= 0) {
+       if (!arg || sscanf(arg, "%f %n", &obj->data.texeci.interval, &n) <= 0) {
                char buf[256];
                ERR("${texeci <interval> command}");
                obj->type = OBJ_text;
                snprintf(buf, 256, "${%s}", s);
                obj->data.s = strdup(buf);
        } else {
-               obj->data.execi.cmd = strdup(arg + n);
-               obj->data.execi.buffer =
+               obj->data.texeci.cmd = strdup(arg + n);
+               obj->data.texeci.buffer =
                        (char *) calloc(1, TEXT_BUFFER_SIZE);
        }
-       obj->data.execi.pos = -1;
+       obj->data.texeci.p_timed_thread = NULL;
        END OBJ(pre_exec, 0) obj->type = OBJ_text;
        if (arg) {
                FILE *fp = popen(arg, "r");
@@ -3697,42 +3628,52 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                        //parse_conky_vars(output, p, cur);
                                }
                                OBJ(texeci) {
-                                       if (obj->data.execi.pos < 0) {
-                                               obj->data.execi.last_update = current_update_time;
-                                               if (pthread_create(&(obj->data.execi.thread_info.thread), NULL, (void*)threaded_exec, (void*) obj)) {
-                                                       ERR("Error starting thread");
-                                               }
-                                               obj->data.execi.pos = register_thread(&(obj->data.execi.thread_info));
+                                       if (!obj->data.texeci.p_timed_thread)
+                                       {
+                                           obj->data.texeci.p_timed_thread=
+                                           timed_thread_create ((void*)threaded_exec, (void*) obj, 
+                                                                obj->data.texeci.interval * 1000000);
+                                           if (!obj->data.texeci.p_timed_thread)
+                                               ERR("Error starting texeci thread");
+                                           timed_thread_register (obj->data.texeci.p_timed_thread,
+                                                                  &obj->data.texeci.p_timed_thread);
                                        }
-                                       pthread_mutex_lock(&(obj->data.execi.thread_info.mutex));
-                                       snprintf(p, p_max_size, "%s", obj->data.execi.buffer);
-                                       pthread_mutex_unlock(&(obj->data.execi.thread_info.mutex));
+                                       timed_thread_lock (obj->data.texeci.p_timed_thread);
+                                       snprintf(p, p_max_size, "%s", obj->data.texeci.buffer);
+                                       timed_thread_unlock (obj->data.texeci.p_timed_thread);
                                }
 #endif /* HAVE_POPEN */
                                OBJ(imap_unseen) {
                                        if (obj->global_mode && info.mail) { // this means we use info
-                                               if (info.mail->pos < 0) {
-                                                       info.mail->last_update = current_update_time;
-                                                       if (pthread_create(&(info.mail->thread_info.thread), NULL, (void*)imap_thread, (void*) info.mail)) {
-                                                               ERR("Error starting thread");
-                                                       }
-                                                       info.mail->pos = register_thread(&(info.mail->thread_info));
+                                               if (!info.mail->p_timed_thread)
+                                               {
+                                                   info.mail->p_timed_thread = 
+                                                   timed_thread_create ((void*)imap_thread, 
+                                                                        (void*)info.mail,
+                                                                        info.mail->interval * 1000000);
+                                                   if (!info.mail->p_timed_thread)
+                                                        ERR("Error starting imap thread");
+                                                   timed_thread_register (info.mail->p_timed_thread,
+                                                                          &info.mail->p_timed_thread);
                                                }
-                                               // get a lock before reading
-                                               pthread_mutex_lock(&(info.mail->thread_info.mutex));
+                                               timed_thread_lock (info.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%lu", info.mail->unseen);
-                                               pthread_mutex_unlock(&(info.mail->thread_info.mutex));
+                                               timed_thread_unlock (info.mail->p_timed_thread);
                                        } else if (obj->data.mail) { // this means we use obj
-                                               if (obj->data.mail->pos < 0) {
-                                                       obj->data.mail->last_update = current_update_time;
-                                                       if (pthread_create(&(obj->data.mail->thread_info.thread), NULL, (void*)imap_thread, (void*) obj->data.mail)) {
-                                                               ERR("Error starting thread");
-                                                       }
-                                                       obj->data.mail->pos = register_thread(&(obj->data.mail->thread_info));
+                                               if (!obj->data.mail->p_timed_thread)
+                                               {
+                                                   obj->data.mail->p_timed_thread = 
+                                                   timed_thread_create ((void*)imap_thread, 
+                                                                        (void*)obj->data.mail,
+                                                                        obj->data.mail->interval * 1000000);
+                                                   if (!obj->data.mail->p_timed_thread)
+                                                       ERR("Error starting imap thread");
+                                                   timed_thread_register (obj->data.mail->p_timed_thread,
+                                                                          &obj->data.mail->p_timed_thread);
                                                }
-                                               pthread_mutex_lock(&(obj->data.mail->thread_info.mutex));
+                                               timed_thread_lock (obj->data.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%lu", obj->data.mail->unseen);
-                                               pthread_mutex_unlock(&(obj->data.mail->thread_info.mutex));
+                                               timed_thread_unlock (obj->data.mail->p_timed_thread);
                                        } else if (!obj->a) { // something is wrong, warn once then stop
                                                ERR("Theres a problem with your imap_unseen settings.  Check that the global IMAP settings are defined properly (line %li).", obj->line);
                                                        obj->a++;
@@ -3740,27 +3681,35 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                }
                                OBJ(imap_messages) {
                                        if (obj->global_mode && info.mail) { // this means we use info
-                                               if (info.mail->pos < 0) {
-                                                       info.mail->last_update = current_update_time;
-                                                       if (pthread_create(&(info.mail->thread_info.thread), NULL, (void*)imap_thread, (void*) info.mail)) {
-                                                               ERR("Error starting thread");
-                                                       }
-                                                       info.mail->pos = register_thread(&(info.mail->thread_info));
+                                               if (!info.mail->p_timed_thread)
+                                               {
+                                                   info.mail->p_timed_thread =
+                                                    timed_thread_create ((void*)imap_thread, 
+                                                                        (void*)info.mail,
+                                                                         info.mail->interval * 1000000);
+                                                    if (!info.mail->p_timed_thread)
+                                                         ERR("Error starting imap thread");
+                                                    timed_thread_register (info.mail->p_timed_thread,
+                                                                           &info.mail->p_timed_thread);
                                                }
-                                               pthread_mutex_lock(&(info.mail->thread_info.mutex));
+                                               timed_thread_lock (info.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%lu", info.mail->messages);
-                                               pthread_mutex_unlock(&(info.mail->thread_info.mutex));
+                                               timed_thread_unlock (info.mail->p_timed_thread);
                                        } else if (obj->data.mail) { // this means we use obj
-                                               if (obj->data.mail->pos < 0) {
-                                                       obj->data.mail->last_update = current_update_time;
-                                                       if (pthread_create(&(obj->data.mail->thread_info.thread), NULL, (void*)imap_thread, (void*) obj->data.mail)) {
-                                                               ERR("Error starting thread");
-                                                       }
-                                                       obj->data.mail->pos = register_thread(&(obj->data.mail->thread_info));
-                                               }
-                                               pthread_mutex_lock(&(obj->data.mail->thread_info.mutex));
+                                               if (!obj->data.mail->p_timed_thread)
+                                                {
+                                                    obj->data.mail->p_timed_thread =
+                                                    timed_thread_create ((void*)imap_thread,
+                                                                         (void*)obj->data.mail,
+                                                                         obj->data.mail->interval * 1000000);
+                                                    if (!obj->data.mail->p_timed_thread)
+                                                        ERR("Error starting imap thread");
+                                                    timed_thread_register (obj->data.mail->p_timed_thread,
+                                                                           &obj->data.mail->p_timed_thread);
+                                                }
+                                               timed_thread_lock (obj->data.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%lu", obj->data.mail->messages);
-                                               pthread_mutex_unlock(&(obj->data.mail->thread_info.mutex));
+                                               timed_thread_lock (obj->data.mail->p_timed_thread);
                                        } else if (!obj->a) { // something is wrong, warn once then stop
                                                ERR("Theres a problem with your imap_messages settings.  Check that the global IMAP settings are defined properly (line %li).", obj->line);
                                                        obj->a++;
@@ -3768,27 +3717,35 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                }
                                OBJ(pop3_unseen) {
                                        if (obj->global_mode && info.mail) { // this means we use info
-                                               if (info.mail->pos < 0) {
-                                                       info.mail->last_update = current_update_time;
-                                                       if (pthread_create(&(info.mail->thread_info.thread), NULL, (void*)pop3_thread, (void*) info.mail)) {
-                                                               ERR("Error starting thread");
-                                                       }
-                                                       info.mail->pos = register_thread(&(info.mail->thread_info));
+                                               if (!info.mail->p_timed_thread)
+                                               {
+                                                   info.mail->p_timed_thread = 
+                                                   timed_thread_create ((void*)pop3_thread,
+                                                                        (void*)info.mail,
+                                                                        info.mail->interval * 1000000);
+                                                   if (!info.mail->p_timed_thread)
+                                                       ERR("Error starting pop3 thread");
+                                                   timed_thread_register (info.mail->p_timed_thread,
+                                                                          &info.mail->p_timed_thread);
                                                }
-                                               pthread_mutex_lock(&(info.mail->thread_info.mutex));
+                                               timed_thread_lock (info.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%lu", info.mail->unseen);
-                                               pthread_mutex_unlock(&(info.mail->thread_info.mutex));
+                                               timed_thread_unlock (info.mail->p_timed_thread);
                                        } else if (obj->data.mail) { // this means we use obj
-                                               if (obj->data.mail->pos < 0) {
-                                                       obj->data.mail->last_update = current_update_time;
-                                                       if (pthread_create(&(obj->data.mail->thread_info.thread), NULL, (void*)pop3_thread, (void*) obj->data.mail)) {
-                                                               ERR("Error starting thread");
-                                                       }
-                                                       obj->data.mail->pos = register_thread(&(obj->data.mail->thread_info));
+                                               if (!obj->data.mail->p_timed_thread)
+                                               {
+                                                   obj->data.mail->p_timed_thread = 
+                                                   timed_thread_create ((void*)pop3_thread,
+                                                                        (void*)info.mail,
+                                                                        obj->data.mail->interval * 1000000);
+                                                   if (!obj->data.mail->p_timed_thread)
+                                                       ERR("Error starting pop3 thread");
+                                                   timed_thread_register (obj->data.mail->p_timed_thread,
+                                                                          &obj->data.mail->p_timed_thread);
                                                }
-                                               pthread_mutex_lock(&(obj->data.mail->thread_info.mutex));
+                                               timed_thread_lock (obj->data.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%lu", obj->data.mail->unseen);
-                                               pthread_mutex_unlock(&(obj->data.mail->thread_info.mutex));
+                                               timed_thread_unlock (obj->data.mail->p_timed_thread);
                                        } else if (!obj->a) { // something is wrong, warn once then stop
                                                ERR("Theres a problem with your pop3_unseen settings.  Check that the global POP3 settings are defined properly (line %li).", obj->line);
                                                        obj->a++;
@@ -3796,27 +3753,35 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                }
                                OBJ(pop3_used) {
                                        if (obj->global_mode && info.mail) { // this means we use info
-                                               if (info.mail->pos < 0) {
-                                                       info.mail->last_update = current_update_time;
-                                                       if (pthread_create(&(info.mail->thread_info.thread), NULL, (void*)pop3_thread, (void*) info.mail)) {
-                                                               ERR("Error starting thread");
-                                                       }
-                                                       info.mail->pos = register_thread(&(info.mail->thread_info));
+                                               if (!info.mail->p_timed_thread)
+                                               {
+                                                   info.mail->p_timed_thread = 
+                                                   timed_thread_create ((void*)pop3_thread,
+                                                                        (void*)info.mail,
+                                                                        info.mail->interval * 1000000);
+                                                   if (!info.mail->p_timed_thread)
+                                                       ERR("Error starting pop3 thread");
+                                                   timed_thread_register (info.mail->p_timed_thread,
+                                                                          &info.mail->p_timed_thread);
                                                }
-                                               pthread_mutex_lock(&(info.mail->thread_info.mutex));
+                                               timed_thread_lock (info.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%.1f", info.mail->used/1024.0/1024.0);
-                                               pthread_mutex_unlock(&(info.mail->thread_info.mutex));
+                                               timed_thread_unlock (info.mail->p_timed_thread);
                                        } else if (obj->data.mail) { // this means we use obj
-                                               if (obj->data.mail->pos < 0) {
-                                                       obj->data.mail->last_update = current_update_time;
-                                                       if (pthread_create(&(obj->data.mail->thread_info.thread), NULL, (void*)pop3_thread, (void*) obj->data.mail)) {
-                                                               ERR("Error starting thread");
-                                                       }
-                                                       obj->data.mail->pos = register_thread(&(obj->data.mail->thread_info));
+                                               if (!obj->data.mail->p_timed_thread)
+                                               {
+                                                   obj->data.mail->p_timed_thread =
+                                                   timed_thread_create ((void*)pop3_thread,
+                                                                        (void*)obj->data.mail,
+                                                                        obj->data.mail->interval * 1000000);
+                                                   if (!obj->data.mail->p_timed_thread)
+                                                       ERR("Error starting pop3 thread");
+                                                   timed_thread_register (obj->data.mail->p_timed_thread,
+                                                                          &obj->data.mail->p_timed_thread);
                                                }
-                                               pthread_mutex_lock(&(obj->data.mail->thread_info.mutex));
+                                               timed_thread_lock (obj->data.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%.1f", obj->data.mail->used/1024.0/1024.0);
-                                               pthread_mutex_unlock(&(obj->data.mail->thread_info.mutex));
+                                               timed_thread_unlock (obj->data.mail->p_timed_thread);
                                        } else if (!obj->a) { // something is wrong, warn once then stop
                                                ERR("Theres a problem with your pop3_used settings.  Check that the global POP3 settings are defined properly (line %li).", obj->line);
                                                        obj->a++;
@@ -5959,16 +5924,13 @@ static void load_config_file(const char *);
 /* reload the config file */
 void reload_config(void)
 {
-       //lock_all_threads();
-       threads_runnable++;
+       timed_thread_destroy_registered_threads ();
+
        if (info.cpu_usage) {
                free(info.cpu_usage);
                info.cpu_usage = NULL;
        }
-#ifdef AUDACIOUS
-        if ( (info.audacious.thread) && (destroy_audacious_thread()!=0) )
-           ERR("error destroying audacious thread");
-#endif
+
 #ifdef TCP_PORT_MONITOR
        destroy_tcp_port_monitor_collection( info.p_tcp_port_monitor_collection );
 #endif
@@ -5986,21 +5948,21 @@ void reload_config(void)
                info.p_tcp_port_monitor_collection = NULL; 
 #endif
 #ifdef AUDACIOUS
-                if ( (!info.audacious.thread) && (create_audacious_thread() !=0) )
+                if (create_audacious_thread() !=0)
                     CRIT_ERR("unable to create audacious thread!");
+               timed_thread_register (info.audacious.p_timed_thread, &info.audacious.p_timed_thread);
 #endif
                extract_variable_text(text);
                free(text);
                text = NULL;
                update_text();
        }
-       thread_count = 0;
 }
 
 void clean_up(void)
 {
-       //lock_all_threads();
-       threads_runnable++;
+       timed_thread_destroy_registered_threads ();
+
        if (info.cpu_usage) {
                free(info.cpu_usage);
                info.cpu_usage = NULL;
@@ -6046,10 +6008,6 @@ void clean_up(void)
        destroy_tcp_port_monitor_collection( info.p_tcp_port_monitor_collection );
        info.p_tcp_port_monitor_collection = NULL;
 #endif
-#ifdef AUDACIOUS
-        if ( info.audacious.thread && (destroy_audacious_thread()!=0) )
-            ERR("error destroying audacious thread");
-#endif
 }
 
 static int string_to_bool(const char *s)
@@ -6949,19 +6907,13 @@ int main(int argc, char **argv)
        }
 
 #ifdef AUDACIOUS
-       if ( (create_audacious_thread() !=0) )
-       {
+       if (create_audacious_thread() !=0) 
            CRIT_ERR("unable to create audacious thread!");
-       }
+       timed_thread_register (info.audacious.p_timed_thread, &info.audacious.p_timed_thread);
 #endif
 
        main_loop();
 
-#ifdef AUDACIOUS
-       if ( info.audacious.thread && (destroy_audacious_thread()!=0) )
-            ERR("error destroying audacious thread");
-#endif 
-
 #if defined(__FreeBSD__)
        kvm_close(kd);
 #endif
index e19bb3b..63136a4 100644 (file)
@@ -9,7 +9,6 @@
 #ifndef _conky_h_
 #define _conky_h_
 
-#include <pthread.h>
 #if defined(HAS_MCHECK_H)
 #include <mcheck.h>
 #endif /* HAS_MCHECK_H */
@@ -41,6 +40,8 @@
 #include <xmmsclient/xmmsclient.h>
 #endif
 
+#include "timed_thread.h"
+
 #define TOP_CPU 1
 #define TOP_NAME 2
 #define TOP_PID 3
@@ -96,11 +97,6 @@ struct fs_stat {
        long long free;
 };
 
-struct thread_info_s {
-       pthread_t thread;
-       pthread_mutex_t mutex;
-};
-
 struct mail_s {                        // for imap and pop3
        unsigned long unseen;
        unsigned long messages;
@@ -114,9 +110,8 @@ struct mail_s {                     // for imap and pop3
        char pass[128];
        char command[1024];
        char folder[128];
-       int pos;
-       struct thread_info_s thread_info;
        char secure;
+       timed_thread *p_timed_thread;
 } mail;
 
 /*struct cpu_stat {
@@ -172,11 +167,7 @@ struct xmms2_s {
 #ifdef AUDACIOUS
 struct audacious_s {
        audacious_t items;              /* e.g. items[AUDACIOUS_STATUS] */
-       pthread_t thread;               /* worker thread */
-       pthread_attr_t thread_attr;     /* thread attributes */
-       pthread_mutex_t item_mutex;     /* mutex for item array */
-       pthread_mutex_t runnable_mutex; /* mutex for runnable */
-       pthread_cond_t runnable_cond;   /* cond for runnable */
+       timed_thread *p_timed_thread;
 };
 #endif
 
index 66b59e3..32134b6 100644 (file)
@@ -10,6 +10,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <time.h>
 #include "timed_thread.h"
 
@@ -67,6 +68,7 @@ timed_thread_create (void *(*start_routine)(void*), void *arg, unsigned int inte
        return NULL;
     }
 
+    /*fprintf (stderr, "created timed thread 0x%08X\n", (unsigned)p_timed_thread);*/
     return p_timed_thread;
 }
 
@@ -93,6 +95,7 @@ timed_thread_destroy (timed_thread* p_timed_thread, timed_thread** addr_of_p_tim
     pthread_mutex_destroy (&p_timed_thread->runnable_mutex);
     pthread_cond_destroy (&p_timed_thread->runnable_cond);
 
+    fprintf (stderr, "destroying timed thread 0x%08X\n", (unsigned)p_timed_thread);
     free (p_timed_thread);
     if (addr_of_p_timed_thread)
        *addr_of_p_timed_thread = NULL;
index fc2dcf6..0ec4e33 100644 (file)
@@ -6,6 +6,8 @@
  * Abstraction layer for timed threads
  * */
 
+#ifndef _TIMED_THREAD_H_
+#define _TIMED_THREAD_H_
 
 #define MINIMUM_INTERVAL_USECS 50000  /* 50000 microseconds = 50 ms =  0.05 sec */
 
@@ -13,7 +15,7 @@
 typedef struct _timed_thread timed_thread;
 
 /* create a timed thread */
-timed_thread* timed_thread_create (void *(*start_routine)(void*), void *arg, unsigned int interval_ms);
+timed_thread* timed_thread_create (void *(*start_routine)(void*), void *arg, unsigned int interval_usecs);
 
 /* destroy a timed thread */
 void timed_thread_destroy (timed_thread* p_timed_thread, timed_thread** addr_of_p_timed_thread);
@@ -30,8 +32,10 @@ int timed_thread_test (timed_thread* p_timed_thread);
 /* exit a timed thread */
 void timed_thread_exit (timed_thread* p_timed_thread);
 
-/* register a timed thread for future destruction */
+/* register a timed thread for future destruction via timed_thread_destroy_registered_threads() */
 int timed_thread_register (timed_thread* p_timed_thread, timed_thread** addr_of_p_timed_thread);
 
 /* destroy all registered timed threads */
 void timed_thread_destroy_registered_threads (void);
+
+#endif /* #ifdef _TIMED_THREAD_H_ */