Fix timed thread race condition, seen esp. on new kernel scheduler (cfs).
[monky] / src / conky.c
index c5e02e4..036aa20 100644 (file)
@@ -1002,6 +1002,8 @@ enum text_object_type {
        OBJ_alignr,
        OBJ_alignc,
        OBJ_i2c,
+       OBJ_platform,
+       OBJ_hwmon,
 #if defined(__linux__)
        OBJ_i8k_version,
        OBJ_i8k_bios,
@@ -1056,7 +1058,6 @@ enum text_object_type {
        OBJ_mixerrbar,
        OBJ_new_mails,
        OBJ_nodename,
-  OBJ_platform,
        OBJ_pre_exec,
        OBJ_processes,
        OBJ_running_processes,
@@ -1226,7 +1227,7 @@ struct text_object {
                        int arg;
                        char devtype[256];
                        char type[64];
-               } i2c, platform;                /* 2 */
+               } sysfs;                /* 2 */
 
                struct {
                        int pos;
@@ -1811,10 +1812,13 @@ static void free_text_objects(unsigned int count, struct text_object *objs)
                                close(objs[i].data.i);
                                break;
                        case OBJ_i2c:
-                               close(objs[i].data.i2c.fd);
+                               close(objs[i].data.sysfs.fd);
                                break;
       case OBJ_platform:
-        close(objs[i].data.platform.fd);
+        close(objs[i].data.sysfs.fd);
+        break;
+      case OBJ_hwmon:
+        close(objs[i].data.sysfs.fd);
         break;
 #endif /* !__OpenBSD__ */
                        case OBJ_time:
@@ -2596,7 +2600,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
        obj->data.pair.b = b;
 
 #ifndef __OpenBSD__
-       END OBJ(i2c, INFO_I2C)
+       END OBJ(i2c, INFO_SYSFS)
   char buf1[64], buf2[64];
        int n;
 
@@ -2610,16 +2614,16 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
        if (sscanf(arg, "%63s %63s %d", buf1, buf2, &n) != 3) {
                /* if scanf couldn't read three values, read type and num and use default device */
                sscanf(arg, "%63s %d", buf2, &n);
-               obj->data.i2c.fd =
-                       open_i2c_sensor(0, buf2, n, &obj->data.i2c.arg, obj->data.i2c.devtype);
-               strncpy(obj->data.i2c.type, buf2, 63);
+               obj->data.sysfs.fd =
+                       open_i2c_sensor(0, buf2, n, &obj->data.sysfs.arg, obj->data.sysfs.devtype);
+               strncpy(obj->data.sysfs.type, buf2, 63);
        } else {
-               obj->data.i2c.fd =
-                       open_i2c_sensor(buf1, buf2, n, &obj->data.i2c.arg, obj->data.i2c.devtype);
-               strncpy(obj->data.i2c.type, buf2, 63);
+               obj->data.sysfs.fd =
+                       open_i2c_sensor(buf1, buf2, n, &obj->data.sysfs.arg, obj->data.sysfs.devtype);
+               strncpy(obj->data.sysfs.type, buf2, 63);
        }
 
-  END OBJ(platform, INFO_PLATFORM)
+  END OBJ(platform, INFO_SYSFS)
   char buf1[64], buf2[64];
   int n;
 
@@ -2632,13 +2636,35 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
   if (sscanf(arg, "%63s %63s %d", buf1, buf2, &n) != 3) {
     /* if scanf couldn't read three values, read type and num and use default device */
     sscanf(arg, "%63s %d", buf2, &n);
-    obj->data.platform.fd =
-      open_platform_sensor(0, buf2, n, &obj->data.platform.arg, obj->data.platform.devtype);
-    strncpy(obj->data.platform.type, buf2, 63);
+    obj->data.sysfs.fd =
+      open_platform_sensor(0, buf2, n, &obj->data.sysfs.arg, obj->data.sysfs.devtype);
+    strncpy(obj->data.sysfs.type, buf2, 63);
+  } else {
+    obj->data.sysfs.fd =
+      open_platform_sensor(buf1, buf2, n, &obj->data.sysfs.arg, obj->data.sysfs.devtype);
+    strncpy(obj->data.sysfs.type, buf2, 63);
+  }
+
+  END OBJ(hwmon, INFO_SYSFS)
+  char buf1[64], buf2[64];
+  int n;
+
+  if (!arg) {
+    ERR("hwmon needs argumanets");
+    obj->type = OBJ_text;
+    return NULL;
+  }
+
+  if (sscanf(arg, "%63s %63s %d", buf1, buf2, &n) != 3) {
+    /* if scanf couldn't read three values, read type and num and use default device */
+    sscanf(arg, "%63s %d", buf2, &n);
+    obj->data.sysfs.fd =
+      open_hwmon_sensor(0, buf2, n, &obj->data.sysfs.arg, obj->data.sysfs.devtype);
+    strncpy(obj->data.sysfs.type, buf2, 63);
   } else {
-    obj->data.platform.fd =
-      open_platform_sensor(buf1, buf2, n, &obj->data.platform.arg, obj->data.platform.devtype);
-    strncpy(obj->data.platform.type, buf2, 63);
+    obj->data.sysfs.fd =
+      open_hwmon_sensor(buf1, buf2, n, &obj->data.sysfs.arg, obj->data.sysfs.devtype);
+    strncpy(obj->data.sysfs.type, buf2, 63);
   }
 #endif /* !__OpenBSD__ */
 
@@ -2969,14 +2995,14 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                (void) scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
        END OBJ(sysname, 0)
 #ifndef __OpenBSD__
-       END OBJ(temp1, INFO_I2C) obj->type = OBJ_i2c;
-       obj->data.i2c.fd =
-               open_i2c_sensor(0, "temp", 1, &obj->data.i2c.arg,
-                               obj->data.i2c.devtype);
-       END OBJ(temp2, INFO_I2C) obj->type = OBJ_i2c;
-       obj->data.i2c.fd =
-               open_i2c_sensor(0, "temp", 2, &obj->data.i2c.arg,
-                               obj->data.i2c.devtype);
+       END OBJ(temp1, INFO_SYSFS) obj->type = OBJ_i2c;
+       obj->data.sysfs.fd =
+               open_i2c_sensor(0, "temp", 1, &obj->data.sysfs.arg,
+                               obj->data.sysfs.devtype);
+       END OBJ(temp2, INFO_SYSFS) obj->type = OBJ_i2c;
+       obj->data.sysfs.fd =
+               open_i2c_sensor(0, "temp", 2, &obj->data.sysfs.arg,
+                               obj->data.sysfs.devtype);
 #endif
        END OBJ(time, 0) obj->data.s = strdup(arg ? arg : "%F %T");
        END OBJ(utime, 0) obj->data.s = strdup(arg ? arg : "%F %T");
@@ -3114,13 +3140,15 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                OBJ(mpd_artist, INFO_MPD) END
                OBJ(mpd_title, INFO_MPD)
                {
-                       if (arg)
-                       {
-                           sscanf (arg, "%d", &info.mpd.max_title_len);
-                           if (info.mpd.max_title_len > 0)
-                               info.mpd.max_title_len++;
-                           else
-                               CRIT_ERR ("mpd_title: invalid length argument");
+                       if (arg) {
+                               sscanf (arg, "%d", &info.mpd.max_title_len);
+                               if (info.mpd.max_title_len > 0) {
+                                       info.mpd.max_title_len++;
+                               } else {
+                                       CRIT_ERR ("mpd_title: invalid length argument");
+                               }
+                       } else {
+                               info.mpd.max_title_len = 0;
                        }
                }
                END OBJ(mpd_random, INFO_MPD)
@@ -3166,13 +3194,13 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                OBJ(audacious_status, INFO_AUDACIOUS) END
                OBJ(audacious_title, INFO_AUDACIOUS) 
                {
-                       if (arg)
-                       {
-                           sscanf (arg, "%d", &info.audacious.max_title_len);
-                           if (info.audacious.max_title_len > 0)
-                               info.audacious.max_title_len++;
-                           else
-                               CRIT_ERR ("audacious_title: invalid length argument");
+                       if (arg) {
+                               sscanf (arg, "%d", &info.audacious.max_title_len);
+                               if (info.audacious.max_title_len > 0) {
+                                       info.audacious.max_title_len++;
+                               }                   else {
+                                       CRIT_ERR ("audacious_title: invalid length argument");
+                               }
                        }
                }
                END
@@ -4142,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);
@@ -4159,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);
@@ -4174,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);
@@ -4195,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);
@@ -4231,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);
@@ -4246,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);
@@ -4267,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);
@@ -4282,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);
@@ -4491,10 +4515,10 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                        OBJ(i2c) {
                                double r;
 
-                               r = get_sysbus_info(&obj->data.i2c.fd,
-                                                obj->data.i2c.arg,
-                                                obj->data.i2c.devtype,
-                                                obj->data.i2c.type);
+                               r = get_sysfs_info(&obj->data.sysfs.fd,
+                                                            obj->data.sysfs.arg,
+                                                            obj->data.sysfs.devtype,
+                                                            obj->data.sysfs.type);
 
                                if (r >= 100.0 || r == 0)
                                        snprintf(p, p_max_size, "%d", (int) r);
@@ -4504,16 +4528,29 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
       OBJ(platform) {
         double r;
 
-        r = get_sysbus_info(&obj->data.platform.fd,
-            obj->data.platform.arg,
-            obj->data.platform.devtype,
-            obj->data.platform.type);
+        r = get_sysfs_info(&obj->data.sysfs.fd,
+                         obj->data.sysfs.arg,
+                         obj->data.sysfs.devtype,
+                         obj->data.sysfs.type);
 
         if (r >= 100.0 || r == 0)
           snprintf(p, p_max_size, "%d", (int) r);
         else
           snprintf(p, p_max_size, "%.1f", r);
       }
+      OBJ(hwmon) {
+        double r;
+
+        r = get_sysfs_info(&obj->data.sysfs.fd,
+                         obj->data.sysfs.arg,
+                         obj->data.sysfs.devtype,
+                         obj->data.sysfs.type);
+
+        if (r >= 100.0 || r == 0)
+           snprintf(p, p_max_size, "%d", (int) r);
+        else
+          snprintf(p, p_max_size, "%.1f", r);
+      }
 #endif /* !__OpenBSD__ */
                        OBJ(alignr) {
                                new_alignr(p, obj->data.i);
@@ -4928,7 +4965,7 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                               255.0f));
                        }
                        OBJ(mpd_smart) {
-                               if (strlen(cur->mpd.title) < 2 && strlen(cur->mpd.title) < 2) {
+                               if (strlen(cur->mpd.title) < 2 && strlen(cur->mpd.artist) < 2) {
                                        snprintf(p, p_max_size, "%s", cur->mpd.file);
                                } else {
                                        snprintf(p, p_max_size, "%s - %s", cur->mpd.artist, cur->mpd.title);
@@ -7389,7 +7426,7 @@ int main(int argc, char **argv)
        struct sigaction act, oact;
 
        g_signal_pending=0;
-       memset(&info, 0, sizeof(info) );
+       memset(&info, 0, sizeof(info));
 
 #ifdef TCP_PORT_MONITOR
        tcp_port_monitor_args.max_port_monitor_connections = MAX_PORT_MONITOR_CONNECTIONS_DEFAULT;