diff --git a/src/conky.c b/src/conky.c index 66bc1edb..c8d3c390 100644 --- a/src/conky.c +++ b/src/conky.c @@ -3116,46 +3116,46 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object * #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) { @@ -5480,7 +5480,7 @@ int main(int argc, char **argv) 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!"); } diff --git a/src/conky.h b/src/conky.h index 91d6ccfc..9de5c553 100644 --- a/src/conky.h +++ b/src/conky.h @@ -141,24 +141,8 @@ struct bmpx_s { #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 */ diff --git a/src/infopipe.c b/src/infopipe.c index f4e821b0..6a01f0bd 100644 --- a/src/infopipe.c +++ b/src/infopipe.c @@ -36,7 +36,7 @@ #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. @@ -44,13 +44,13 @@ static char g_item[14][256]; 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); } @@ -58,17 +58,18 @@ void update_infopipe(void) /* -------------------------------------------------- * 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. */ @@ -82,10 +83,11 @@ void *infopipe_service(void *pvoid) 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); @@ -94,38 +96,45 @@ void *infopipe_service(void *pvoid) 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); diff --git a/src/infopipe.h b/src/infopipe.h index 87c6728a..7425af53 100644 --- a/src/infopipe.h +++ b/src/infopipe.h @@ -28,9 +28,34 @@ #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