Fix timed thread race condition, seen esp. on new kernel scheduler (cfs).
authorPhilip Kovacs <pkovacs@users.sourceforge.net>
Fri, 31 Aug 2007 21:35:30 +0000 (21:35 +0000)
committerPhilip Kovacs <pkovacs@users.sourceforge.net>
Fri, 31 Aug 2007 21:35:30 +0000 (21:35 +0000)
Fix $audacious_title not being displayed when no length argument indicated.

git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky1@943 7f574dfc-610e-0410-a909-a81674777703

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

index 52293c9..be76169 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,8 @@
 
 2007-08-31
        * _Really_ fix mpd SIGPIPE issues
+       * Fix timed thread race condition, seen esp. on new kernel scheduler (cfs).
+       * Fix $audacious_title not being displayed when no length argument indicated.
 
 2007-08-30
        * Conky 1.4.7 released
index 1f56985..330365d 100644 (file)
@@ -65,7 +65,7 @@ int create_audacious_thread(void)
   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)
+  if (!info.audacious.p_timed_thread || timed_thread_run (info.audacious.p_timed_thread))
     return (-1);
 
   return 0;
index c2c9522..ab78697 100644 (file)
@@ -236,9 +236,11 @@ void update_stuff()
                        clear_mpd_stats(&info); 
                        mpd_timed_thread = timed_thread_create((void*)update_mpd, (void*) NULL, update_interval * 1000000);
                        if (!mpd_timed_thread) {
-                               ERR("Failed to create MPD thread");
+                               ERR("Failed to create MPD timed thread");
                        }
                        timed_thread_register(mpd_timed_thread, &mpd_timed_thread);
+      if (timed_thread_run (mpd_timed_thread))
+        ERR("Failed to run MPD timed thread");
                }
        }
 #endif
index 959e7fd..036aa20 100644 (file)
@@ -3201,8 +3201,6 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                                }                   else {
                                        CRIT_ERR ("audacious_title: invalid length argument");
                                }
-                       } else {
-                               info.audacious.max_title_len++;
                        }
                }
                END
@@ -4172,12 +4170,12 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                        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);
+                                             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);
+                                                   ERR("Error creating texeci timed thread");
+                                           timed_thread_register (obj->data.texeci.p_timed_thread, &obj->data.texeci.p_timed_thread);
+              if (timed_thread_run (obj->data.texeci.p_timed_thread))
+                ERR("Error running texeci timed thread");
                                        }
                                        timed_thread_lock (obj->data.texeci.p_timed_thread);
                                        snprintf(p, p_max_size, "%s", obj->data.texeci.buffer);
@@ -4189,13 +4187,12 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                                if (!info.mail->p_timed_thread)
                                                {
                                                    info.mail->p_timed_thread = 
-                                                   timed_thread_create ((void*)imap_thread, 
-                                                                        (void*)info.mail,
-                                                                        info.mail->interval * 1000000);
+                                                     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);
+                                                           ERR("Error creating imap timed thread");
+                                                   timed_thread_register (info.mail->p_timed_thread, &info.mail->p_timed_thread);
+                if (timed_thread_run (info.mail->p_timed_thread))
+                  ERR("Error running imap timed thread");
                                                }
                                                timed_thread_lock (info.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%lu", info.mail->unseen);
@@ -4204,13 +4201,13 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                                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);
+                                                     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);
+                                                           ERR("Error creating imap timed thread");
+                                                   timed_thread_register (obj->data.mail->p_timed_thread, &obj->data.mail->p_timed_thread);
+                if (timed_thread_run (obj->data.mail->p_timed_thread))
+                  ERR("Error running imap timed thread");
                                                }
                                                timed_thread_lock (obj->data.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%lu", obj->data.mail->unseen);
@@ -4225,29 +4222,28 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                                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);
+                  timed_thread_create ((void*)imap_thread, (void*)info.mail, info.mail->interval * 1000000);
+                if (!info.mail->p_timed_thread)
+                  ERR("Error creating imap timed thread");
+                timed_thread_register (info.mail->p_timed_thread, &info.mail->p_timed_thread);
+                if (timed_thread_run (info.mail->p_timed_thread))
+                  ERR("Error running imap timed thread");
                                                }
                                                timed_thread_lock (info.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%lu", info.mail->messages);
                                                timed_thread_unlock (info.mail->p_timed_thread);
                                        } else if (obj->data.mail) { // this means we use obj
                                                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);
-                                                }
+            {
+              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 creating imap timed thread");
+              timed_thread_register (obj->data.mail->p_timed_thread, &obj->data.mail->p_timed_thread);
+              if (timed_thread_run (obj->data.mail->p_timed_thread))
+                ERR("Error runninging imap timed thread");
+            }
                                                timed_thread_lock (obj->data.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%lu", obj->data.mail->messages);
                                                timed_thread_lock (obj->data.mail->p_timed_thread);
@@ -4261,13 +4257,12 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                                if (!info.mail->p_timed_thread)
                                                {
                                                    info.mail->p_timed_thread = 
-                                                   timed_thread_create ((void*)pop3_thread,
-                                                                        (void*)info.mail,
-                                                                        info.mail->interval * 1000000);
+                                                   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);
+                                                           ERR("Error creating pop3 timed thread");
+                                                   timed_thread_register (info.mail->p_timed_thread, &info.mail->p_timed_thread);
+                if (timed_thread_run (info.mail->p_timed_thread))
+                  ERR("Error running pop3 timed thread");
                                                }
                                                timed_thread_lock (info.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%lu", info.mail->unseen);
@@ -4276,13 +4271,13 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                                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);
+                                                   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);
+                                                           ERR("Error creating pop3 timed thread");
+                                                   timed_thread_register (obj->data.mail->p_timed_thread, &obj->data.mail->p_timed_thread);
+                if (timed_thread_run (obj->data.mail->p_timed_thread))
+                  ERR("Error running pop3 timed thread");
                                                }
                                                timed_thread_lock (obj->data.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%lu", obj->data.mail->unseen);
@@ -4297,13 +4292,12 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                                if (!info.mail->p_timed_thread)
                                                {
                                                    info.mail->p_timed_thread = 
-                                                   timed_thread_create ((void*)pop3_thread,
-                                                                        (void*)info.mail,
-                                                                        info.mail->interval * 1000000);
+                                                     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);
+                                                           ERR("Error creating pop3 timed thread");
+                                                   timed_thread_register (info.mail->p_timed_thread, &info.mail->p_timed_thread);
+                if (timed_thread_run (info.mail->p_timed_thread))
+                  ERR("Error running pop3 timed thread");
                                                }
                                                timed_thread_lock (info.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%.1f", info.mail->used/1024.0/1024.0);
@@ -4312,13 +4306,13 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                                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);
+                                                     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);
+                                                           ERR("Error creating pop3 timed thread");
+                                                   timed_thread_register (obj->data.mail->p_timed_thread, &obj->data.mail->p_timed_thread);
+                if (timed_thread_run (obj->data.mail->p_timed_thread))
+                  ERR("Error running pop3 timed thread");
                                                }
                                                timed_thread_lock (obj->data.mail->p_timed_thread);
                                                snprintf(p, p_max_size, "%.1f", obj->data.mail->used/1024.0/1024.0);
index 0a4be39..2f51044 100644 (file)
@@ -44,6 +44,8 @@ struct _timed_thread
   pthread_mutex_t runnable_mutex; /* only for the runnable_cond */
   pthread_cond_t runnable_cond;   /* signalled to stop the thread */
   unsigned int interval_usecs;    /* timed_thread_test() wait interval in microseconds */
+  void *(*start_routine)(void*);  /* thread function to run */
+  void *arg;                      /* thread function argument */
 };
 
 /* linked list of created threads */
@@ -58,7 +60,7 @@ static timed_thread_list *p_timed_thread_list_head = NULL;
 static timed_thread_list *p_timed_thread_list_tail = NULL;
 
 
-/* create a timed thread */
+/* create a timed thread (object creation only) */
 timed_thread* 
 timed_thread_create (void *(*start_routine)(void*), void *arg, unsigned int interval_usecs)
 {
@@ -79,18 +81,19 @@ timed_thread_create (void *(*start_routine)(void*), void *arg, unsigned int inte
   pthread_cond_init (&p_timed_thread->runnable_cond, NULL);
 
   p_timed_thread->interval_usecs = interval_usecs;
+  p_timed_thread->start_routine = start_routine;
+  p_timed_thread->arg = arg;
 
-  /* create thread */
-  if (pthread_create (&p_timed_thread->thread, &p_timed_thread->thread_attr, start_routine, arg))
-  {
-    timed_thread_destroy (p_timed_thread, NULL);
-    return NULL;
-  }
-
-  /*fprintf (stderr, "created timed thread 0x%08X\n", (unsigned)p_timed_thread);*/
   return p_timed_thread;
 }
 
+/* run a timed thread (drop the thread and run it) */
+int 
+timed_thread_run (timed_thread* p_timed_thread)
+{
+  return pthread_create (&p_timed_thread->thread, &p_timed_thread->thread_attr,
+                         p_timed_thread->start_routine, p_timed_thread->arg);
+}
 
 /* destroy a timed thread.
  * optional addr_of_p_timed_thread to set callers pointer to NULL as a convenience. */
@@ -114,7 +117,6 @@ 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, "Conky: destroying 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 e9abb5c..ca51b6b 100644 (file)
 /* opaque structure for clients */
 typedef struct _timed_thread timed_thread;
 
-/* create a timed thread */
+/* create a timed thread (object creation only) */
 timed_thread* timed_thread_create (void *(*start_routine)(void*), void *arg, unsigned int interval_usecs);
 
+/* run a timed thread (drop the thread and run it) */
+int timed_thread_run (timed_thread* p_timed_thread);
+
 /* destroy a timed thread */
 void timed_thread_destroy (timed_thread* p_timed_thread, timed_thread** addr_of_p_timed_thread);