1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2024-12-25 04:06:03 +00:00

convert all thread activity to timed thread abstraction

git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky1@772 7f574dfc-610e-0410-a909-a81674777703
This commit is contained in:
Philip Kovacs 2006-11-15 01:20:49 +00:00
parent 615f0be933
commit 5a91ebca4e
6 changed files with 187 additions and 271 deletions

View File

@ -3,6 +3,8 @@
2006-11-14 2006-11-14
* Fix compile error with --disable-x11. * Fix compile error with --disable-x11.
* Add new timed thread abstraction file. * Add new timed thread abstraction file.
* Convert thread activity to timed threads, including
texeci, imap, pop3, audacious.
2006-11-13 2006-11-13
* Use pthread_cond_timedwait() instead of sleep() in audacious * Use pthread_cond_timedwait() instead of sleep() in audacious

View File

@ -20,11 +20,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* --------------------------------------------------------------------------- */ * --------------------------------------------------------------------------- */
#include <pthread.h>
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <glib.h> #include <glib.h>
#include <audacious/beepctrl.h> #include <audacious/beepctrl.h>
@ -32,6 +29,7 @@
#include "config.h" #include "config.h"
#include "conky.h" #include "conky.h"
#include "audacious.h" #include "audacious.h"
#include "timed_thread.h"
/* access to this item array is synchronized */ /* access to this item array is synchronized */
static audacious_t audacious_items; 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 conky thread. We merely copy the audacious_items array into the main thread's
info structure when the main thread's update cycle fires. 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)); 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) int create_audacious_thread(void)
{ {
/* Is a worker is thread already running? */ if (!info.audacious.p_timed_thread)
if (info.audacious.thread) info.audacious.p_timed_thread = timed_thread_create (audacious_thread_func, NULL, 1000000);
return(-1);
/* Joinable thread for audacious activity */ if (!info.audacious.p_timed_thread)
pthread_attr_init(&info.audacious.thread_attr); return (-1);
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);
return 0; return 0;
} }
@ -85,25 +77,11 @@ int create_audacious_thread(void)
int destroy_audacious_thread(void) int destroy_audacious_thread(void)
{ {
/* Is a worker is thread running? If not, no error. */ /* Is a worker is thread running? If not, no error. */
if (!info.audacious.thread) if (!info.audacious.p_timed_thread)
return(0); return(0);
/* Signal audacious thread to terminate */ timed_thread_destroy (info.audacious.p_timed_thread, &info.audacious.p_timed_thread);
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);
/* 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; return 0;
} }
@ -112,20 +90,18 @@ int destroy_audacious_thread(void)
* --------------------------------------------------- */ * --------------------------------------------------- */
void *audacious_thread_func(void *pvoid) void *audacious_thread_func(void *pvoid)
{ {
int runnable=1;
static audacious_t items; static audacious_t items;
gint session,playpos,frames,length; gint session,playpos,frames,length;
gint rate,freq,chans; gint rate,freq,chans;
gchar *psong,*pfilename; gchar *psong,*pfilename;
struct timespec abstime;
pvoid=(void *)pvoid; /* avoid warning */ pvoid=(void *)pvoid; /* avoid warning */
session=0; session=0;
psong=NULL; psong=NULL;
pfilename=NULL; pfilename=NULL;
/* Loop until the main thread sets the runnable signal to 0. */ /* Loop until the main thread sets the runnable signal to 0i via timed_thread_destroy. */
while(runnable) { while (1) {
if (!xmms_remote_is_running (session)) { if (!xmms_remote_is_running (session)) {
memset(&items,0,sizeof(items)); memset(&items,0,sizeof(items));
@ -199,24 +175,12 @@ void *audacious_thread_func(void *pvoid)
next_iter: next_iter:
/* Deliver the refreshed items array to audacious_items. */ /* 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)); memcpy(&audacious_items,items,sizeof(items));
pthread_mutex_unlock(&info.audacious.item_mutex); timed_thread_unlock (info.audacious.p_timed_thread);
/* Get absolute time 1 sec in the future. */ if (timed_thread_test (info.audacious.p_timed_thread))
clock_gettime (CLOCK_REALTIME, &abstime); timed_thread_exit (info.audacious.p_timed_thread);
abstime.tv_sec += 1;
/* 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);
}
} }
pthread_exit(NULL);
} }

View File

@ -1138,10 +1138,16 @@ struct text_object {
char *cmd; char *cmd;
char *buffer; char *buffer;
double data; double data;
int pos;
struct thread_info_s thread_info;
} execi; /* 5 */ } execi; /* 5 */
struct {
float interval;
char *cmd;
char *buffer;
double data;
timed_thread *p_timed_thread;
} texeci;
struct { struct {
int a, b; int a, b;
} pair; /* 2 */ } pair; /* 2 */
@ -1172,25 +1178,6 @@ static unsigned int text_object_count;
static struct text_object *text_objects; 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); 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 MAXDATASIZE 1000
#define POP3 1 #define POP3 1
#define IMAP 2 #define IMAP 2
@ -1262,15 +1249,12 @@ struct mail_s* parse_mail_args(char type, const char *arg) {
} else { } else {
mail->command[0] = '\0'; mail->command[0] = '\0';
} }
mail->pos = -1; mail->p_timed_thread = NULL;
return mail; return mail;
} }
void *imap_thread(struct mail_s* 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; int sockfd, numbytes;
char recvbuf[MAXDATASIZE]; char recvbuf[MAXDATASIZE];
char sendbuf[MAXDATASIZE]; char sendbuf[MAXDATASIZE];
@ -1284,12 +1268,11 @@ void *imap_thread(struct mail_s* mail)
herror("gethostbyname"); herror("gethostbyname");
exit(1); exit(1);
} }
while (threads_runnable == run_code && fail < 5) { while (fail < 5) {
if (fail > 0) { if (fail > 0) {
ERR("Trying IMAP connection again for %s@%s (try %i/5)", mail->user, mail->host, fail + 1); ERR("Trying IMAP connection again for %s@%s (try %i/5)", mail->user, mail->host, fail + 1);
sleep((int)mail->interval); sleep((int)mail->interval);
} }
update_time = get_time();
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket"); perror("socket");
fail++; fail++;
@ -1406,11 +1389,11 @@ void *imap_thread(struct mail_s* mail)
fail++; fail++;
continue; continue;
} else { } else {
pthread_mutex_lock(&(mail->thread_info.mutex)); timed_thread_lock (mail->p_timed_thread);
sscanf(reply, "MESSAGES %lu UNSEEN %lu", sscanf(reply, "MESSAGES %lu UNSEEN %lu",
&mail->messages, &mail->messages,
&mail->unseen); &mail->unseen);
pthread_mutex_unlock(&(mail->thread_info.mutex)); timed_thread_unlock (mail->p_timed_thread);
} }
strncpy(sendbuf, "a3 logout\n", MAXDATASIZE); strncpy(sendbuf, "a3 logout\n", MAXDATASIZE);
if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
@ -1447,32 +1430,14 @@ void *imap_thread(struct mail_s* mail)
fail = 0; fail = 0;
old_unseen = mail->unseen; old_unseen = mail->unseen;
old_messages = mail->messages; old_messages = mail->messages;
mail->last_update = update_time; if (timed_thread_test (mail->p_timed_thread))
usleep(100); // prevent race condition timed_thread_exit (mail->p_timed_thread);
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);
}
}
ERR("exiting imap thread");
pthread_exit(NULL);
return 0; return 0;
} }
void *pop3_thread(struct mail_s *mail) 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; int sockfd, numbytes;
char recvbuf[MAXDATASIZE]; char recvbuf[MAXDATASIZE];
char sendbuf[MAXDATASIZE]; char sendbuf[MAXDATASIZE];
@ -1485,12 +1450,11 @@ void *pop3_thread(struct mail_s *mail)
herror("gethostbyname"); herror("gethostbyname");
exit(1); exit(1);
} }
while (threads_runnable == run_code && fail < 5) { while (fail < 5) {
if (fail > 0) { if (fail > 0) {
ERR("Trying POP3 connection again for %s@%s (try %i/5)", mail->user, mail->host, fail + 1); ERR("Trying POP3 connection again for %s@%s (try %i/5)", mail->user, mail->host, fail + 1);
sleep((int)mail->interval); sleep((int)mail->interval);
} }
update_time = get_time();
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket"); perror("socket");
fail++; fail++;
@ -1627,11 +1591,10 @@ void *pop3_thread(struct mail_s *mail)
fail++; fail++;
continue; continue;
} else { } else {
pthread_mutex_lock(&(mail->thread_info.mutex)); timed_thread_lock (mail->p_timed_thread);
sscanf(reply, "%lu %lu", &mail->unseen, sscanf(reply, "%lu %lu", &mail->unseen,
&mail->used); &mail->used);
// sleep(60); timed_thread_unlock (mail->p_timed_thread);
pthread_mutex_unlock(&(mail->thread_info.mutex));
} }
strncpy(sendbuf, "QUIT\n", MAXDATASIZE); strncpy(sendbuf, "QUIT\n", MAXDATASIZE);
if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
@ -1667,36 +1630,18 @@ void *pop3_thread(struct mail_s *mail)
} }
fail = 0; fail = 0;
old_unseen = mail->unseen; old_unseen = mail->unseen;
mail->last_update = update_time; if (timed_thread_test (mail->p_timed_thread))
usleep(100); // prevent race condition timed_thread_exit (mail->p_timed_thread);
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);
}
}
ERR("exiting pop3 thread");
pthread_exit(NULL);
return 0; return 0;
} }
void *threaded_exec(struct text_object *obj) { // pthreads are really beginning to piss me off void *threaded_exec(struct text_object *obj) {
double update_time; while (1) {
int run_code = threads_runnable; char *p2 = obj->data.texeci.buffer;
while (threads_runnable == run_code) { FILE *fp = popen(obj->data.texeci.cmd,"r");
update_time = get_time(); timed_thread_lock (obj->data.texeci.p_timed_thread);
char *p2 = obj->data.execi.buffer;
FILE *fp = popen(obj->data.execi.cmd,"r");
pthread_mutex_lock(&(obj->data.execi.thread_info.mutex));
int n2 = fread(p2, 1, TEXT_BUFFER_SIZE, fp); int n2 = fread(p2, 1, TEXT_BUFFER_SIZE, fp);
(void) pclose(fp); (void) pclose(fp);
p2[n2] = '\0'; p2[n2] = '\0';
@ -1709,21 +1654,10 @@ void *threaded_exec(struct text_object *obj) { // pthreads are really beginning
} }
p2++; p2++;
} }
pthread_mutex_unlock(&(obj->data.execi.thread_info.mutex)); timed_thread_unlock (obj->data.texeci.p_timed_thread);
obj->data.execi.last_update = update_time; if (timed_thread_test (obj->data.texeci.p_timed_thread))
usleep(100); // prevent race condition timed_thread_exit (obj->data.texeci.p_timed_thread);
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);
}
}
ERR("exiting thread");
pthread_exit(NULL);
return 0; return 0;
} }
@ -1984,8 +1918,8 @@ static void free_text_objects(unsigned int count, struct text_object *objs)
free(objs[i].data.execi.buffer); free(objs[i].data.execi.buffer);
break; break;
case OBJ_texeci: case OBJ_texeci:
free(objs[i].data.execi.cmd); free(objs[i].data.texeci.cmd);
free(objs[i].data.execi.buffer); free(objs[i].data.texeci.buffer);
break; break;
case OBJ_top: case OBJ_top:
if (info.first_process) { 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); obj->data.execi.cmd = strdup(arg + n);
} }
END OBJ(execi, 0) unsigned int 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]; char buf[256];
ERR("${execi <interval> command}"); ERR("${execi <interval> command}");
obj->type = OBJ_text; 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); (char *) calloc(1, TEXT_BUFFER_SIZE);
} }
END OBJ(texeci, 0) unsigned int n; END OBJ(texeci, 0) unsigned int n;
if (!arg || sscanf(arg, "%f %n", &obj->data.texeci.interval, &n) <= 0) {
if (!arg || sscanf(arg, "%f %n", &obj->data.execi.interval, &n) <= 0) {
char buf[256]; char buf[256];
ERR("${texeci <interval> command}"); ERR("${texeci <interval> command}");
obj->type = OBJ_text; obj->type = OBJ_text;
snprintf(buf, 256, "${%s}", s); snprintf(buf, 256, "${%s}", s);
obj->data.s = strdup(buf); obj->data.s = strdup(buf);
} else { } else {
obj->data.execi.cmd = strdup(arg + n); obj->data.texeci.cmd = strdup(arg + n);
obj->data.execi.buffer = obj->data.texeci.buffer =
(char *) calloc(1, TEXT_BUFFER_SIZE); (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; END OBJ(pre_exec, 0) obj->type = OBJ_text;
if (arg) { if (arg) {
FILE *fp = popen(arg, "r"); 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); //parse_conky_vars(output, p, cur);
} }
OBJ(texeci) { OBJ(texeci) {
if (obj->data.execi.pos < 0) { if (!obj->data.texeci.p_timed_thread)
obj->data.execi.last_update = current_update_time; {
if (pthread_create(&(obj->data.execi.thread_info.thread), NULL, (void*)threaded_exec, (void*) obj)) { obj->data.texeci.p_timed_thread=
ERR("Error starting 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);
} }
obj->data.execi.pos = register_thread(&(obj->data.execi.thread_info)); timed_thread_lock (obj->data.texeci.p_timed_thread);
} snprintf(p, p_max_size, "%s", obj->data.texeci.buffer);
pthread_mutex_lock(&(obj->data.execi.thread_info.mutex)); timed_thread_unlock (obj->data.texeci.p_timed_thread);
snprintf(p, p_max_size, "%s", obj->data.execi.buffer);
pthread_mutex_unlock(&(obj->data.execi.thread_info.mutex));
} }
#endif /* HAVE_POPEN */ #endif /* HAVE_POPEN */
OBJ(imap_unseen) { OBJ(imap_unseen) {
if (obj->global_mode && info.mail) { // this means we use info if (obj->global_mode && info.mail) { // this means we use info
if (info.mail->pos < 0) { if (!info.mail->p_timed_thread)
info.mail->last_update = current_update_time; {
if (pthread_create(&(info.mail->thread_info.thread), NULL, (void*)imap_thread, (void*) info.mail)) { info.mail->p_timed_thread =
ERR("Error starting 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);
} }
info.mail->pos = register_thread(&(info.mail->thread_info)); timed_thread_lock (info.mail->p_timed_thread);
}
// get a lock before reading
pthread_mutex_lock(&(info.mail->thread_info.mutex));
snprintf(p, p_max_size, "%lu", info.mail->unseen); 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 } else if (obj->data.mail) { // this means we use obj
if (obj->data.mail->pos < 0) { if (!obj->data.mail->p_timed_thread)
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)) { obj->data.mail->p_timed_thread =
ERR("Error starting 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->pos = register_thread(&(obj->data.mail->thread_info)); timed_thread_lock (obj->data.mail->p_timed_thread);
}
pthread_mutex_lock(&(obj->data.mail->thread_info.mutex));
snprintf(p, p_max_size, "%lu", obj->data.mail->unseen); 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 } 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); ERR("Theres a problem with your imap_unseen settings. Check that the global IMAP settings are defined properly (line %li).", obj->line);
obj->a++; obj->a++;
@ -3740,27 +3681,35 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
} }
OBJ(imap_messages) { OBJ(imap_messages) {
if (obj->global_mode && info.mail) { // this means we use info if (obj->global_mode && info.mail) { // this means we use info
if (info.mail->pos < 0) { if (!info.mail->p_timed_thread)
info.mail->last_update = current_update_time; {
if (pthread_create(&(info.mail->thread_info.thread), NULL, (void*)imap_thread, (void*) info.mail)) { info.mail->p_timed_thread =
ERR("Error starting 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);
} }
info.mail->pos = register_thread(&(info.mail->thread_info)); timed_thread_lock (info.mail->p_timed_thread);
}
pthread_mutex_lock(&(info.mail->thread_info.mutex));
snprintf(p, p_max_size, "%lu", info.mail->messages); 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 } else if (obj->data.mail) { // this means we use obj
if (obj->data.mail->pos < 0) { if (!obj->data.mail->p_timed_thread)
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)) { obj->data.mail->p_timed_thread =
ERR("Error starting 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->pos = register_thread(&(obj->data.mail->thread_info)); timed_thread_lock (obj->data.mail->p_timed_thread);
}
pthread_mutex_lock(&(obj->data.mail->thread_info.mutex));
snprintf(p, p_max_size, "%lu", obj->data.mail->messages); 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 } 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); ERR("Theres a problem with your imap_messages settings. Check that the global IMAP settings are defined properly (line %li).", obj->line);
obj->a++; obj->a++;
@ -3768,27 +3717,35 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
} }
OBJ(pop3_unseen) { OBJ(pop3_unseen) {
if (obj->global_mode && info.mail) { // this means we use info if (obj->global_mode && info.mail) { // this means we use info
if (info.mail->pos < 0) { if (!info.mail->p_timed_thread)
info.mail->last_update = current_update_time; {
if (pthread_create(&(info.mail->thread_info.thread), NULL, (void*)pop3_thread, (void*) info.mail)) { info.mail->p_timed_thread =
ERR("Error starting 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);
} }
info.mail->pos = register_thread(&(info.mail->thread_info)); timed_thread_lock (info.mail->p_timed_thread);
}
pthread_mutex_lock(&(info.mail->thread_info.mutex));
snprintf(p, p_max_size, "%lu", info.mail->unseen); 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 } else if (obj->data.mail) { // this means we use obj
if (obj->data.mail->pos < 0) { if (!obj->data.mail->p_timed_thread)
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)) { obj->data.mail->p_timed_thread =
ERR("Error starting 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);
} }
obj->data.mail->pos = register_thread(&(obj->data.mail->thread_info)); timed_thread_lock (obj->data.mail->p_timed_thread);
}
pthread_mutex_lock(&(obj->data.mail->thread_info.mutex));
snprintf(p, p_max_size, "%lu", obj->data.mail->unseen); 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 } 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); ERR("Theres a problem with your pop3_unseen settings. Check that the global POP3 settings are defined properly (line %li).", obj->line);
obj->a++; obj->a++;
@ -3796,27 +3753,35 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
} }
OBJ(pop3_used) { OBJ(pop3_used) {
if (obj->global_mode && info.mail) { // this means we use info if (obj->global_mode && info.mail) { // this means we use info
if (info.mail->pos < 0) { if (!info.mail->p_timed_thread)
info.mail->last_update = current_update_time; {
if (pthread_create(&(info.mail->thread_info.thread), NULL, (void*)pop3_thread, (void*) info.mail)) { info.mail->p_timed_thread =
ERR("Error starting 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);
} }
info.mail->pos = register_thread(&(info.mail->thread_info)); timed_thread_lock (info.mail->p_timed_thread);
}
pthread_mutex_lock(&(info.mail->thread_info.mutex));
snprintf(p, p_max_size, "%.1f", info.mail->used/1024.0/1024.0); 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 } else if (obj->data.mail) { // this means we use obj
if (obj->data.mail->pos < 0) { if (!obj->data.mail->p_timed_thread)
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)) { obj->data.mail->p_timed_thread =
ERR("Error starting 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);
} }
obj->data.mail->pos = register_thread(&(obj->data.mail->thread_info)); timed_thread_lock (obj->data.mail->p_timed_thread);
}
pthread_mutex_lock(&(obj->data.mail->thread_info.mutex));
snprintf(p, p_max_size, "%.1f", obj->data.mail->used/1024.0/1024.0); 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 } 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); ERR("Theres a problem with your pop3_used settings. Check that the global POP3 settings are defined properly (line %li).", obj->line);
obj->a++; obj->a++;
@ -5959,16 +5924,13 @@ static void load_config_file(const char *);
/* reload the config file */ /* reload the config file */
void reload_config(void) void reload_config(void)
{ {
//lock_all_threads(); timed_thread_destroy_registered_threads ();
threads_runnable++;
if (info.cpu_usage) { if (info.cpu_usage) {
free(info.cpu_usage); free(info.cpu_usage);
info.cpu_usage = NULL; info.cpu_usage = NULL;
} }
#ifdef AUDACIOUS
if ( (info.audacious.thread) && (destroy_audacious_thread()!=0) )
ERR("error destroying audacious thread");
#endif
#ifdef TCP_PORT_MONITOR #ifdef TCP_PORT_MONITOR
destroy_tcp_port_monitor_collection( info.p_tcp_port_monitor_collection ); destroy_tcp_port_monitor_collection( info.p_tcp_port_monitor_collection );
#endif #endif
@ -5986,21 +5948,21 @@ void reload_config(void)
info.p_tcp_port_monitor_collection = NULL; info.p_tcp_port_monitor_collection = NULL;
#endif #endif
#ifdef AUDACIOUS #ifdef AUDACIOUS
if ( (!info.audacious.thread) && (create_audacious_thread() !=0) ) if (create_audacious_thread() !=0)
CRIT_ERR("unable to create audacious thread!"); CRIT_ERR("unable to create audacious thread!");
timed_thread_register (info.audacious.p_timed_thread, &info.audacious.p_timed_thread);
#endif #endif
extract_variable_text(text); extract_variable_text(text);
free(text); free(text);
text = NULL; text = NULL;
update_text(); update_text();
} }
thread_count = 0;
} }
void clean_up(void) void clean_up(void)
{ {
//lock_all_threads(); timed_thread_destroy_registered_threads ();
threads_runnable++;
if (info.cpu_usage) { if (info.cpu_usage) {
free(info.cpu_usage); free(info.cpu_usage);
info.cpu_usage = NULL; info.cpu_usage = NULL;
@ -6046,10 +6008,6 @@ void clean_up(void)
destroy_tcp_port_monitor_collection( info.p_tcp_port_monitor_collection ); destroy_tcp_port_monitor_collection( info.p_tcp_port_monitor_collection );
info.p_tcp_port_monitor_collection = NULL; info.p_tcp_port_monitor_collection = NULL;
#endif #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) static int string_to_bool(const char *s)
@ -6949,19 +6907,13 @@ int main(int argc, char **argv)
} }
#ifdef AUDACIOUS #ifdef AUDACIOUS
if ( (create_audacious_thread() !=0) ) if (create_audacious_thread() !=0)
{
CRIT_ERR("unable to create audacious thread!"); CRIT_ERR("unable to create audacious thread!");
} timed_thread_register (info.audacious.p_timed_thread, &info.audacious.p_timed_thread);
#endif #endif
main_loop(); main_loop();
#ifdef AUDACIOUS
if ( info.audacious.thread && (destroy_audacious_thread()!=0) )
ERR("error destroying audacious thread");
#endif
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
kvm_close(kd); kvm_close(kd);
#endif #endif

View File

@ -9,7 +9,6 @@
#ifndef _conky_h_ #ifndef _conky_h_
#define _conky_h_ #define _conky_h_
#include <pthread.h>
#if defined(HAS_MCHECK_H) #if defined(HAS_MCHECK_H)
#include <mcheck.h> #include <mcheck.h>
#endif /* HAS_MCHECK_H */ #endif /* HAS_MCHECK_H */
@ -41,6 +40,8 @@
#include <xmmsclient/xmmsclient.h> #include <xmmsclient/xmmsclient.h>
#endif #endif
#include "timed_thread.h"
#define TOP_CPU 1 #define TOP_CPU 1
#define TOP_NAME 2 #define TOP_NAME 2
#define TOP_PID 3 #define TOP_PID 3
@ -96,11 +97,6 @@ struct fs_stat {
long long free; long long free;
}; };
struct thread_info_s {
pthread_t thread;
pthread_mutex_t mutex;
};
struct mail_s { // for imap and pop3 struct mail_s { // for imap and pop3
unsigned long unseen; unsigned long unseen;
unsigned long messages; unsigned long messages;
@ -114,9 +110,8 @@ struct mail_s { // for imap and pop3
char pass[128]; char pass[128];
char command[1024]; char command[1024];
char folder[128]; char folder[128];
int pos;
struct thread_info_s thread_info;
char secure; char secure;
timed_thread *p_timed_thread;
} mail; } mail;
/*struct cpu_stat { /*struct cpu_stat {
@ -172,11 +167,7 @@ struct xmms2_s {
#ifdef AUDACIOUS #ifdef AUDACIOUS
struct audacious_s { struct audacious_s {
audacious_t items; /* e.g. items[AUDACIOUS_STATUS] */ audacious_t items; /* e.g. items[AUDACIOUS_STATUS] */
pthread_t thread; /* worker thread */ timed_thread *p_timed_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 */
}; };
#endif #endif

View File

@ -10,6 +10,7 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include <time.h> #include <time.h>
#include "timed_thread.h" #include "timed_thread.h"
@ -67,6 +68,7 @@ timed_thread_create (void *(*start_routine)(void*), void *arg, unsigned int inte
return NULL; return NULL;
} }
/*fprintf (stderr, "created timed thread 0x%08X\n", (unsigned)p_timed_thread);*/
return 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_mutex_destroy (&p_timed_thread->runnable_mutex);
pthread_cond_destroy (&p_timed_thread->runnable_cond); pthread_cond_destroy (&p_timed_thread->runnable_cond);
fprintf (stderr, "destroying timed thread 0x%08X\n", (unsigned)p_timed_thread);
free (p_timed_thread); free (p_timed_thread);
if (addr_of_p_timed_thread) if (addr_of_p_timed_thread)
*addr_of_p_timed_thread = NULL; *addr_of_p_timed_thread = NULL;

View File

@ -6,6 +6,8 @@
* Abstraction layer for timed threads * 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 */ #define MINIMUM_INTERVAL_USECS 50000 /* 50000 microseconds = 50 ms = 0.05 sec */
@ -13,7 +15,7 @@
typedef struct _timed_thread timed_thread; typedef struct _timed_thread timed_thread;
/* create a 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 */ /* destroy a timed thread */
void timed_thread_destroy (timed_thread* p_timed_thread, timed_thread** addr_of_p_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 */ /* exit a timed thread */
void timed_thread_exit (timed_thread* p_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); int timed_thread_register (timed_thread* p_timed_thread, timed_thread** addr_of_p_timed_thread);
/* destroy all registered timed threads */ /* destroy all registered timed threads */
void timed_thread_destroy_registered_threads (void); void timed_thread_destroy_registered_threads (void);
#endif /* #ifdef _TIMED_THREAD_H_ */