1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2024-12-23 19:39:06 +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
* Fix compile error with --disable-x11.
* Add new timed thread abstraction file.
* Convert thread activity to timed threads, including
texeci, imap, pop3, audacious.
2006-11-13
* 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
* --------------------------------------------------------------------------- */
#include <pthread.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <glib.h>
#include <audacious/beepctrl.h>
@ -32,6 +29,7 @@
#include "config.h"
#include "conky.h"
#include "audacious.h"
#include "timed_thread.h"
/* access to this item array is synchronized */
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
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));
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)
{
/* Is a worker is thread already running? */
if (info.audacious.thread)
return(-1);
if (!info.audacious.p_timed_thread)
info.audacious.p_timed_thread = timed_thread_create (audacious_thread_func, NULL, 1000000);
/* Joinable thread for audacious activity */
pthread_attr_init(&info.audacious.thread_attr);
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);
if (!info.audacious.p_timed_thread)
return (-1);
return 0;
}
@ -85,25 +77,11 @@ int create_audacious_thread(void)
int destroy_audacious_thread(void)
{
/* Is a worker is thread running? If not, no error. */
if (!info.audacious.thread)
if (!info.audacious.p_timed_thread)
return(0);
/* Signal audacious thread to terminate */
pthread_mutex_lock (&info.audacious.runnable_mutex);
pthread_cond_signal (&info.audacious.runnable_cond);
pthread_mutex_unlock (&info.audacious.runnable_mutex);
timed_thread_destroy (info.audacious.p_timed_thread, &info.audacious.p_timed_thread);
/* 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;
}
@ -112,20 +90,18 @@ int destroy_audacious_thread(void)
* --------------------------------------------------- */
void *audacious_thread_func(void *pvoid)
{
int runnable=1;
static audacious_t items;
gint session,playpos,frames,length;
gint rate,freq,chans;
gchar *psong,*pfilename;
struct timespec abstime;
pvoid=(void *)pvoid; /* avoid warning */
session=0;
psong=NULL;
pfilename=NULL;
/* Loop until the main thread sets the runnable signal to 0. */
while(runnable) {
/* Loop until the main thread sets the runnable signal to 0i via timed_thread_destroy. */
while (1) {
if (!xmms_remote_is_running (session)) {
memset(&items,0,sizeof(items));
@ -199,24 +175,12 @@ void *audacious_thread_func(void *pvoid)
next_iter:
/* 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));
pthread_mutex_unlock(&info.audacious.item_mutex);
timed_thread_unlock (info.audacious.p_timed_thread);
/* Get absolute time 1 sec in the future. */
clock_gettime (CLOCK_REALTIME, &abstime);
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);
}
if (timed_thread_test (info.audacious.p_timed_thread))
timed_thread_exit (info.audacious.p_timed_thread);
}
pthread_exit(NULL);
}

View File

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

View File

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

View File

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

View File

@ -6,6 +6,8 @@
* 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 */
@ -13,7 +15,7 @@
typedef struct _timed_thread 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 */
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 */
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);
/* destroy all registered timed threads */
void timed_thread_destroy_registered_threads (void);
#endif /* #ifdef _TIMED_THREAD_H_ */