1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2024-12-26 12:27:52 +00:00

Fix timed thread race condition, seen esp. on new kernel scheduler (cfs).

Fix $audacious_title not being displayed when no length argument indicated.



git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky1@943 7f574dfc-610e-0410-a909-a81674777703
This commit is contained in:
Philip Kovacs 2007-08-31 21:35:30 +00:00
parent ef272217d9
commit 6c052dae9b
6 changed files with 76 additions and 73 deletions

View File

@ -2,6 +2,8 @@
2007-08-31 2007-08-31
* _Really_ fix mpd SIGPIPE issues * _Really_ fix mpd SIGPIPE issues
* Fix timed thread race condition, seen esp. on new kernel scheduler (cfs).
* Fix $audacious_title not being displayed when no length argument indicated.
2007-08-30 2007-08-30
* Conky 1.4.7 released * Conky 1.4.7 released

View File

@ -65,7 +65,7 @@ int create_audacious_thread(void)
if (!info.audacious.p_timed_thread) if (!info.audacious.p_timed_thread)
info.audacious.p_timed_thread = timed_thread_create (audacious_thread_func, NULL, 1000000); info.audacious.p_timed_thread = timed_thread_create (audacious_thread_func, NULL, 1000000);
if (!info.audacious.p_timed_thread) if (!info.audacious.p_timed_thread || timed_thread_run (info.audacious.p_timed_thread))
return (-1); return (-1);
return 0; return 0;

View File

@ -236,9 +236,11 @@ void update_stuff()
clear_mpd_stats(&info); clear_mpd_stats(&info);
mpd_timed_thread = timed_thread_create((void*)update_mpd, (void*) NULL, update_interval * 1000000); mpd_timed_thread = timed_thread_create((void*)update_mpd, (void*) NULL, update_interval * 1000000);
if (!mpd_timed_thread) { if (!mpd_timed_thread) {
ERR("Failed to create MPD thread"); ERR("Failed to create MPD timed thread");
} }
timed_thread_register(mpd_timed_thread, &mpd_timed_thread); timed_thread_register(mpd_timed_thread, &mpd_timed_thread);
if (timed_thread_run (mpd_timed_thread))
ERR("Failed to run MPD timed thread");
} }
} }
#endif #endif

View File

@ -3201,8 +3201,6 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
} else { } else {
CRIT_ERR ("audacious_title: invalid length argument"); CRIT_ERR ("audacious_title: invalid length argument");
} }
} else {
info.audacious.max_title_len++;
} }
} }
END END
@ -4172,12 +4170,12 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
if (!obj->data.texeci.p_timed_thread) if (!obj->data.texeci.p_timed_thread)
{ {
obj->data.texeci.p_timed_thread= obj->data.texeci.p_timed_thread=
timed_thread_create ((void*)threaded_exec, (void*) obj, timed_thread_create ((void*)threaded_exec, (void*) obj, obj->data.texeci.interval * 1000000);
obj->data.texeci.interval * 1000000);
if (!obj->data.texeci.p_timed_thread) if (!obj->data.texeci.p_timed_thread)
ERR("Error starting texeci thread"); ERR("Error creating texeci timed thread");
timed_thread_register (obj->data.texeci.p_timed_thread, timed_thread_register (obj->data.texeci.p_timed_thread, &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); timed_thread_lock (obj->data.texeci.p_timed_thread);
snprintf(p, p_max_size, "%s", obj->data.texeci.buffer); snprintf(p, p_max_size, "%s", obj->data.texeci.buffer);
@ -4189,13 +4187,12 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
if (!info.mail->p_timed_thread) if (!info.mail->p_timed_thread)
{ {
info.mail->p_timed_thread = info.mail->p_timed_thread =
timed_thread_create ((void*)imap_thread, timed_thread_create ((void*)imap_thread, (void*)info.mail, info.mail->interval * 1000000);
(void*)info.mail,
info.mail->interval * 1000000);
if (!info.mail->p_timed_thread) if (!info.mail->p_timed_thread)
ERR("Error starting imap thread"); ERR("Error creating imap timed thread");
timed_thread_register (info.mail->p_timed_thread, timed_thread_register (info.mail->p_timed_thread, &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); timed_thread_lock (info.mail->p_timed_thread);
snprintf(p, p_max_size, "%lu", info.mail->unseen); snprintf(p, p_max_size, "%lu", info.mail->unseen);
@ -4204,13 +4201,13 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
if (!obj->data.mail->p_timed_thread) if (!obj->data.mail->p_timed_thread)
{ {
obj->data.mail->p_timed_thread = obj->data.mail->p_timed_thread =
timed_thread_create ((void*)imap_thread, timed_thread_create ((void*)imap_thread, (void*)obj->data.mail,
(void*)obj->data.mail,
obj->data.mail->interval * 1000000); obj->data.mail->interval * 1000000);
if (!obj->data.mail->p_timed_thread) if (!obj->data.mail->p_timed_thread)
ERR("Error starting imap thread"); ERR("Error creating imap timed thread");
timed_thread_register (obj->data.mail->p_timed_thread, timed_thread_register (obj->data.mail->p_timed_thread, &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); timed_thread_lock (obj->data.mail->p_timed_thread);
snprintf(p, p_max_size, "%lu", obj->data.mail->unseen); snprintf(p, p_max_size, "%lu", obj->data.mail->unseen);
@ -4225,13 +4222,12 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
if (!info.mail->p_timed_thread) if (!info.mail->p_timed_thread)
{ {
info.mail->p_timed_thread = info.mail->p_timed_thread =
timed_thread_create ((void*)imap_thread, timed_thread_create ((void*)imap_thread, (void*)info.mail, info.mail->interval * 1000000);
(void*)info.mail,
info.mail->interval * 1000000);
if (!info.mail->p_timed_thread) if (!info.mail->p_timed_thread)
ERR("Error starting imap thread"); ERR("Error creating imap timed thread");
timed_thread_register (info.mail->p_timed_thread, timed_thread_register (info.mail->p_timed_thread, &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); timed_thread_lock (info.mail->p_timed_thread);
snprintf(p, p_max_size, "%lu", info.mail->messages); snprintf(p, p_max_size, "%lu", info.mail->messages);
@ -4240,13 +4236,13 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
if (!obj->data.mail->p_timed_thread) if (!obj->data.mail->p_timed_thread)
{ {
obj->data.mail->p_timed_thread = obj->data.mail->p_timed_thread =
timed_thread_create ((void*)imap_thread, timed_thread_create ((void*)imap_thread, (void*)obj->data.mail,
(void*)obj->data.mail,
obj->data.mail->interval * 1000000); obj->data.mail->interval * 1000000);
if (!obj->data.mail->p_timed_thread) if (!obj->data.mail->p_timed_thread)
ERR("Error starting imap thread"); ERR("Error creating imap timed thread");
timed_thread_register (obj->data.mail->p_timed_thread, timed_thread_register (obj->data.mail->p_timed_thread, &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); timed_thread_lock (obj->data.mail->p_timed_thread);
snprintf(p, p_max_size, "%lu", obj->data.mail->messages); snprintf(p, p_max_size, "%lu", obj->data.mail->messages);
@ -4261,13 +4257,12 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
if (!info.mail->p_timed_thread) if (!info.mail->p_timed_thread)
{ {
info.mail->p_timed_thread = info.mail->p_timed_thread =
timed_thread_create ((void*)pop3_thread, timed_thread_create ((void*)pop3_thread, (void*)info.mail, info.mail->interval * 1000000);
(void*)info.mail,
info.mail->interval * 1000000);
if (!info.mail->p_timed_thread) if (!info.mail->p_timed_thread)
ERR("Error starting pop3 thread"); ERR("Error creating pop3 timed thread");
timed_thread_register (info.mail->p_timed_thread, timed_thread_register (info.mail->p_timed_thread, &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); timed_thread_lock (info.mail->p_timed_thread);
snprintf(p, p_max_size, "%lu", info.mail->unseen); snprintf(p, p_max_size, "%lu", info.mail->unseen);
@ -4276,13 +4271,13 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
if (!obj->data.mail->p_timed_thread) if (!obj->data.mail->p_timed_thread)
{ {
obj->data.mail->p_timed_thread = obj->data.mail->p_timed_thread =
timed_thread_create ((void*)pop3_thread, timed_thread_create ((void*)pop3_thread, (void*)obj->data.mail,
(void*)obj->data.mail,
obj->data.mail->interval * 1000000); obj->data.mail->interval * 1000000);
if (!obj->data.mail->p_timed_thread) if (!obj->data.mail->p_timed_thread)
ERR("Error starting pop3 thread"); ERR("Error creating pop3 timed thread");
timed_thread_register (obj->data.mail->p_timed_thread, timed_thread_register (obj->data.mail->p_timed_thread, &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); timed_thread_lock (obj->data.mail->p_timed_thread);
snprintf(p, p_max_size, "%lu", obj->data.mail->unseen); snprintf(p, p_max_size, "%lu", obj->data.mail->unseen);
@ -4297,13 +4292,12 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
if (!info.mail->p_timed_thread) if (!info.mail->p_timed_thread)
{ {
info.mail->p_timed_thread = info.mail->p_timed_thread =
timed_thread_create ((void*)pop3_thread, timed_thread_create ((void*)pop3_thread, (void*)info.mail, info.mail->interval * 1000000);
(void*)info.mail,
info.mail->interval * 1000000);
if (!info.mail->p_timed_thread) if (!info.mail->p_timed_thread)
ERR("Error starting pop3 thread"); ERR("Error creating pop3 timed thread");
timed_thread_register (info.mail->p_timed_thread, timed_thread_register (info.mail->p_timed_thread, &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); timed_thread_lock (info.mail->p_timed_thread);
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);
@ -4312,13 +4306,13 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
if (!obj->data.mail->p_timed_thread) if (!obj->data.mail->p_timed_thread)
{ {
obj->data.mail->p_timed_thread = obj->data.mail->p_timed_thread =
timed_thread_create ((void*)pop3_thread, timed_thread_create ((void*)pop3_thread, (void*)obj->data.mail,
(void*)obj->data.mail,
obj->data.mail->interval * 1000000); obj->data.mail->interval * 1000000);
if (!obj->data.mail->p_timed_thread) if (!obj->data.mail->p_timed_thread)
ERR("Error starting pop3 thread"); ERR("Error creating pop3 timed thread");
timed_thread_register (obj->data.mail->p_timed_thread, timed_thread_register (obj->data.mail->p_timed_thread, &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); timed_thread_lock (obj->data.mail->p_timed_thread);
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);

View File

@ -44,6 +44,8 @@ struct _timed_thread
pthread_mutex_t runnable_mutex; /* only for the runnable_cond */ pthread_mutex_t runnable_mutex; /* only for the runnable_cond */
pthread_cond_t runnable_cond; /* signalled to stop the thread */ pthread_cond_t runnable_cond; /* signalled to stop the thread */
unsigned int interval_usecs; /* timed_thread_test() wait interval in microseconds */ unsigned int interval_usecs; /* timed_thread_test() wait interval in microseconds */
void *(*start_routine)(void*); /* thread function to run */
void *arg; /* thread function argument */
}; };
/* linked list of created threads */ /* linked list of created threads */
@ -58,7 +60,7 @@ static timed_thread_list *p_timed_thread_list_head = NULL;
static timed_thread_list *p_timed_thread_list_tail = NULL; static timed_thread_list *p_timed_thread_list_tail = NULL;
/* create a timed thread */ /* create a timed thread (object creation only) */
timed_thread* timed_thread*
timed_thread_create (void *(*start_routine)(void*), void *arg, unsigned int interval_usecs) timed_thread_create (void *(*start_routine)(void*), void *arg, unsigned int interval_usecs)
{ {
@ -79,18 +81,19 @@ timed_thread_create (void *(*start_routine)(void*), void *arg, unsigned int inte
pthread_cond_init (&p_timed_thread->runnable_cond, NULL); pthread_cond_init (&p_timed_thread->runnable_cond, NULL);
p_timed_thread->interval_usecs = interval_usecs; p_timed_thread->interval_usecs = interval_usecs;
p_timed_thread->start_routine = start_routine;
p_timed_thread->arg = arg;
/* create thread */
if (pthread_create (&p_timed_thread->thread, &p_timed_thread->thread_attr, start_routine, arg))
{
timed_thread_destroy (p_timed_thread, NULL);
return NULL;
}
/*fprintf (stderr, "created timed thread 0x%08X\n", (unsigned)p_timed_thread);*/
return p_timed_thread; return p_timed_thread;
} }
/* run a timed thread (drop the thread and run it) */
int
timed_thread_run (timed_thread* p_timed_thread)
{
return pthread_create (&p_timed_thread->thread, &p_timed_thread->thread_attr,
p_timed_thread->start_routine, p_timed_thread->arg);
}
/* destroy a timed thread. /* destroy a timed thread.
* optional addr_of_p_timed_thread to set callers pointer to NULL as a convenience. */ * optional addr_of_p_timed_thread to set callers pointer to NULL as a convenience. */
@ -114,7 +117,6 @@ 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, "Conky: destroying 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

@ -30,9 +30,12 @@
/* opaque structure for clients */ /* opaque structure for clients */
typedef struct _timed_thread timed_thread; typedef struct _timed_thread timed_thread;
/* create a timed thread */ /* create a timed thread (object creation only) */
timed_thread* timed_thread_create (void *(*start_routine)(void*), void *arg, unsigned int interval_usecs); timed_thread* timed_thread_create (void *(*start_routine)(void*), void *arg, unsigned int interval_usecs);
/* run a timed thread (drop the thread and run it) */
int timed_thread_run (timed_thread* p_timed_thread);
/* 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);