#endif
#ifdef INFOPIPE
OBJ(infopipe_protocol) {
- snprintf(p, p_max_size, "%s", cur->infopipe.item[INFOPIPE_PROTOCOL]);
+ snprintf(p, p_max_size, "%s", cur->infopipe.items[INFOPIPE_PROTOCOL]);
}
OBJ(infopipe_version) {
- snprintf(p, p_max_size, "%s", cur->infopipe.item[INFOPIPE_VERSION]);
+ snprintf(p, p_max_size, "%s", cur->infopipe.items[INFOPIPE_VERSION]);
}
OBJ(infopipe_status) {
- snprintf(p, p_max_size, "%s", cur->infopipe.item[INFOPIPE_STATUS]);
+ snprintf(p, p_max_size, "%s", cur->infopipe.items[INFOPIPE_STATUS]);
}
OBJ(infopipe_playlist_tunes) {
- snprintf(p, p_max_size, "%s", cur->infopipe.item[INFOPIPE_PLAYLIST_TUNES]);
+ snprintf(p, p_max_size, "%s", cur->infopipe.items[INFOPIPE_PLAYLIST_TUNES]);
}
OBJ(infopipe_playlist_currtune) {
- snprintf(p, p_max_size, "%s", cur->infopipe.item[INFOPIPE_PLAYLIST_CURRTUNE]);
+ snprintf(p, p_max_size, "%s", cur->infopipe.items[INFOPIPE_PLAYLIST_CURRTUNE]);
}
OBJ(infopipe_usec_position) {
- snprintf(p, p_max_size, "%s", cur->infopipe.item[INFOPIPE_USEC_POSITION]);
+ snprintf(p, p_max_size, "%s", cur->infopipe.items[INFOPIPE_USEC_POSITION]);
}
OBJ(infopipe_position) {
- snprintf(p, p_max_size, "%s", cur->infopipe.item[INFOPIPE_POSITION]);
+ snprintf(p, p_max_size, "%s", cur->infopipe.items[INFOPIPE_POSITION]);
}
OBJ(infopipe_usec_time) {
- snprintf(p, p_max_size, "%s", cur->infopipe.item[INFOPIPE_USEC_TIME]);
+ snprintf(p, p_max_size, "%s", cur->infopipe.items[INFOPIPE_USEC_TIME]);
}
OBJ(infopipe_time) {
- snprintf(p, p_max_size, "%s", cur->infopipe.item[INFOPIPE_TIME]);
+ snprintf(p, p_max_size, "%s", cur->infopipe.items[INFOPIPE_TIME]);
}
OBJ(infopipe_bitrate) {
- snprintf(p, p_max_size, "%s", cur->infopipe.item[INFOPIPE_BITRATE]);
+ snprintf(p, p_max_size, "%s", cur->infopipe.items[INFOPIPE_BITRATE]);
}
OBJ(infopipe_frequency) {
- snprintf(p, p_max_size, "%s", cur->infopipe.item[INFOPIPE_FREQUENCY]);
+ snprintf(p, p_max_size, "%s", cur->infopipe.items[INFOPIPE_FREQUENCY]);
}
OBJ(infopipe_channels) {
- snprintf(p, p_max_size, "%s", cur->infopipe.item[INFOPIPE_CHANNELS]);
+ snprintf(p, p_max_size, "%s", cur->infopipe.items[INFOPIPE_CHANNELS]);
}
OBJ(infopipe_title) {
- snprintf(p, p_max_size, "%s", cur->infopipe.item[INFOPIPE_TITLE]);
+ snprintf(p, p_max_size, "%s", cur->infopipe.items[INFOPIPE_TITLE]);
}
OBJ(infopipe_file) {
- snprintf(p, p_max_size, "%s", cur->infopipe.item[INFOPIPE_FILE]);
+ snprintf(p, p_max_size, "%s", cur->infopipe.items[INFOPIPE_FILE]);
}
#endif
OBJ(top) {
pthread_mutex_lock(&info.infopipe.runnable_mutex);
info.infopipe.runnable=1;
pthread_mutex_unlock(&info.infopipe.runnable_mutex);
- if (pthread_create(&info.infopipe.thread, &info.infopipe.thread_attr, infopipe_service, NULL))
+ if (pthread_create(&info.infopipe.thread, &info.infopipe.thread_attr, infopipe_thread_func, NULL))
{
CRIT_ERR("unable to create infopipe thread!");
}
#ifdef INFOPIPE
#include "infopipe.h"
-enum _infopipe_keys {
- INFOPIPE_PROTOCOL,
- INFOPIPE_VERSION,
- INFOPIPE_STATUS,
- INFOPIPE_PLAYLIST_TUNES,
- INFOPIPE_PLAYLIST_CURRTUNE,
- INFOPIPE_USEC_POSITION,
- INFOPIPE_POSITION,
- INFOPIPE_USEC_TIME,
- INFOPIPE_TIME,
- INFOPIPE_BITRATE,
- INFOPIPE_FREQUENCY,
- INFOPIPE_CHANNELS,
- INFOPIPE_TITLE,
- INFOPIPE_FILE
-};
struct infopipe_s {
- char item[14][256]; /* use enum as first array index, e.g. item[INFOPIPE_STATUS] */
+ infopipe_t items; /* e.g. items[INFOPIPE_STATUS] yields char[] */
int runnable; /* used to signal infopipe thread to stop */
pthread_t thread; /* worker thread for infopipe updating */
pthread_attr_t thread_attr; /* thread attributes */
#include "conky.h"
/* access to this item array is synchronized with mutexes */
-static char g_item[14][256];
+static infopipe_t g_items;
/* ----------------------------------------
* Conky update function for InfoPipe data.
void update_infopipe(void)
{
/*
- The worker thread is updating ihe g_item array asynchronously to the main
- conky thread. We merely copy the g_item array into the main thread's info
+ The worker thread is updating ihe g_items array asynchronously to the main
+ conky thread. We merely copy the g_items array into the main thread's info
structure when the main thread's update cycle fires. Note that using the
mutexes here makes it easier since we won't have to do any sync in conky.c.
*/
pthread_mutex_lock(&info.infopipe.item_mutex);
- memcpy(&info.infopipe.item,g_item,sizeof(g_item));
+ memcpy(&info.infopipe.items,g_items,sizeof(g_items));
pthread_mutex_unlock(&info.infopipe.item_mutex);
}
/* --------------------------------------------------
* Worker thread function for InfoPipe data sampling.
* -------------------------------------------------- */
-void *infopipe_service(void *pvoid)
+void *infopipe_thread_func(void *pvoid)
{
int i,fd,runnable;
fd_set readset;
struct timeval tm;
char buf[2048],*pbuf;
+ infopipe_t items;
pvoid=(void*)pvoid; /* useless cast to avoid unused var warning */
- /* I/O multiplexing timer is set for one second select() */
- tm.tv_sec=1;
+ /* I/O multiplexing timer */
+ tm.tv_sec=10; /* high enough to reduce persistent select() failures */
tm.tv_usec=0;
/* Grab the runnable signal. Should be non-zero here or we do nothing. */
for (;;) { /* convenience loop so we can break below */
memset(buf,0,sizeof(buf));
- memset(g_item,0,sizeof(g_item));
+ memset(items,0,sizeof(items));
- if ((fd=open(INFOPIPE_NAMED_PIPE, O_RDONLY | O_NONBLOCK)) < 0)
+ if ((fd=open(INFOPIPE_NAMED_PIPE, O_RDONLY | O_NONBLOCK)) < 0) {
break;
+ }
FD_ZERO(&readset);
FD_SET(fd,&readset);
ideally suited for a worker thread such as this. We don't want
to slow down ui updates in the main thread as there is already
excess latency there. */
- if (select(fd+1,&readset,NULL,NULL,&tm) == 1) { /* something to read */
+ if ((i=select(fd+1,&readset,NULL,NULL,&tm)) == 1) { /* something to read */
if (read(fd,buf,sizeof(buf)) > 0) { /* buf has data */
pbuf=buf;
- pthread_mutex_lock(&info.infopipe.item_mutex);
for (i=0;i<14;i++) {
/* 14 lines of key: value pairs presented in a known order */
- sscanf(pbuf,"%*[^:]: %[^\n]",g_item[i]);
+ sscanf(pbuf,"%*[^:]: %[^\n]",items[i]);
while(*pbuf++ != '\n');
}
- pthread_mutex_unlock(&info.infopipe.item_mutex);
/* -- debug to console --
for(i=0;i<14;i++)
- printf("%s\n",g_item[i]);
+ printf("%s\n",items[i]);
*/
}
}
+ else {
+ printf("select() says nothing to read: %d, fd %d\n",i,fd);
+ }
- if (close(fd)<0)
+ if (close(fd) < 0) {
break;
+ }
break;
}
- sleep(2); /* need a var here */
+ /* Deliver the refreshed items array to g_items. */
+ pthread_mutex_lock(&info.infopipe.item_mutex);
+ memcpy(&g_items,items,sizeof(items));
+ pthread_mutex_unlock(&info.infopipe.item_mutex);
/* Grab the runnable signal for next loop. */
pthread_mutex_lock(&info.infopipe.runnable_mutex);
runnable=info.infopipe.runnable;
pthread_mutex_unlock(&info.infopipe.runnable_mutex);
+
+ sleep(1);
}
pthread_exit(NULL);
#ifndef INFOPIPE_H
#define INFOPIPE_H
+/* The named pipe created by the infopipe plugin (actually a symlink) */
#define INFOPIPE_NAMED_PIPE "/tmp/xmms-info"
+/* 14 keys comprise the output of the infopipe plugin. */
+enum _infopipe_keys {
+ INFOPIPE_PROTOCOL,
+ INFOPIPE_VERSION,
+ INFOPIPE_STATUS,
+ INFOPIPE_PLAYLIST_TUNES,
+ INFOPIPE_PLAYLIST_CURRTUNE,
+ INFOPIPE_USEC_POSITION,
+ INFOPIPE_POSITION,
+ INFOPIPE_USEC_TIME,
+ INFOPIPE_TIME,
+ INFOPIPE_BITRATE,
+ INFOPIPE_FREQUENCY,
+ INFOPIPE_CHANNELS,
+ INFOPIPE_TITLE,
+ INFOPIPE_FILE
+};
+
+/* 14 slots for the infopipe values */
+typedef char infopipe_t[14][256];
+
+/* Service routine for the conky main thread */
void update_infopipe(void);
-void *infopipe_service(void *);
+
+/* Thread function */
+void *infopipe_thread_func(void *);
#endif