diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index 9159e9b..c294d7f 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2007.10.18.200336" +#define Cdrskin_timestamP "2007.10.19.115326" diff --git a/libburn/async.c b/libburn/async.c index 79a5d04..b73fecb 100644 --- a/libburn/async.c +++ b/libburn/async.c @@ -1,5 +1,40 @@ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ + +/* ts A71019 : burry dead puppies before forgetting them */ + +/* Standard measure : Threads are created detached. + According to the man pages they should then care for disposing themselves. + Does not help on my SuSE 9.3 + +*/ +#define Libburn_create_detached_threadS 1 + +/* Addon with certain impact on application: + Call wait3() more often than pthread_create() + Does not help on my SuSE 9.3 + +#define Libburn_use_wait3 1 +*/ + +/* Alternative 1 : Threads are created joinable. + Workers get transferred to the done_workers list and then joined with + the next thread going to that list. + Does not help on my SuSE 9.3 + +#define Libburn_remove_done_workerS 1 +*/ + +/* Alternative 2 : Threads are created joinable. + Threads get detached in remove_worker() and thus should dispose themselves. + Does not help on my SuSE 9.3 + + Note: this works only if Libburn_remove_done_workerS is not defined. + +#define Libburn_detach_done_workeR 1 +*/ + + #include "libburn.h" #include "transport.h" #include "drive.h" @@ -16,6 +51,9 @@ #include #include #include +#include +#include +#include /* #include @@ -80,7 +118,12 @@ struct w_list } u; }; -static struct w_list *workers; +static struct w_list *workers = NULL; + +#ifdef Libburn_remove_done_workerS +static struct w_list *done_workers = NULL; +#endif + static struct w_list *find_worker(struct burn_drive *d) { @@ -96,6 +139,16 @@ static void add_worker(struct burn_drive *d, WorkerFunc f, void *data) { struct w_list *a; struct w_list *tmp; + pthread_attr_t *attr_pt = NULL; + +#ifdef Libburn_create_detached_threadS + pthread_attr_t attr; +#endif + +#ifdef Libburn_use_wait3 + wait3(NULL,WNOHANG,NULL); + wait3(NULL,WNOHANG,NULL); +#endif a = malloc(sizeof(struct w_list)); a->drive = d; @@ -109,24 +162,101 @@ static void add_worker(struct burn_drive *d, WorkerFunc f, void *data) if (d != NULL) d->busy = BURN_DRIVE_SPAWNING; - if (pthread_create(&a->thread, NULL, f, a)) { +#ifdef Libburn_create_detached_threadS + /* ts A71019 : + Trying to start the threads detached to get rid of the zombies + which do neither react on pthread_join() nor on pthread_detach(). + */ + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + attr_pt= &attr; + libdax_msgs_submit(libdax_messenger, -1, 0x00020158, + LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW, + "add_worker(): Creating detached thread.", 0, 0); +#endif + + if (pthread_create(&a->thread, attr_pt, f, a)) { free(a); workers = tmp; return; } } + +#ifdef Libburn_remove_done_workerS + +/* ts A71019 : burry dead puppies before forgetting them */ +/* Alternative 1 : Threads are created joinable. + Workers get transferred to the done_workers list and then joined with + the next thread going to that list. + Does not work on my SuSE 9.3 +*/ +int burn_remove_done_workers(int flag) +{ + int ret; + char msg[80]; + struct w_list *next; + + while (done_workers != NULL) { + ret = pthread_join(done_workers->thread, NULL); + sprintf(msg, + "burn_remove_done_workers(): pthread_join(%lu) = %d", + (unsigned long) done_workers->thread, ret); + libdax_msgs_submit(libdax_messenger, -1, 0x00020158, + LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW, + msg, 0, 0); + next = done_workers->next; + free(done_workers); + done_workers = next; + } + return 1; +} + +#endif /* Libburn_remove_done_workerS */ + + static void remove_worker(pthread_t th) { struct w_list *a, *l = NULL; +#ifdef Libburn_remove_done_workerS + burn_remove_done_workers(0); +#else +#ifdef Libburn_detach_done_workeR + int ret; + char msg[80]; +#endif +#endif /* ! Libburn_remove_done_workerS && ! Libburn_detach_done_workeR */ + for (a = workers; a; l = a, a = a->next) if (a->thread == th) { if (l) l->next = a->next; else workers = a->next; + +#ifdef Libburn_remove_done_workerS + a->next= done_workers; + done_workers= a; +#else +#ifdef Libburn_detach_done_workeR + /* ts A71019 : burry dead puppy before forgetting it */ + /* Alternative 2 : threads get detached and thus should + dispose themselves. + Does not work on my SuSE 9.3 + */ + ret = pthread_detach(th); + sprintf(msg, + "remove_workers(): pid= %lu pthread_detach(%lu)= %d", + (unsigned long) getpid(), (unsigned long) th, ret); + libdax_msgs_submit(libdax_messenger, -1, 0x00020158, + LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW, + msg, 0, 0); + +#endif /* Libburn_detach_done_workeR */ + free(a); +#endif break; } diff --git a/libburn/libdax_msgs.h b/libburn/libdax_msgs.h index 6c3aec5..4b44209 100644 --- a/libburn/libdax_msgs.h +++ b/libburn/libdax_msgs.h @@ -440,6 +440,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff 0x00020155 (SORRY,HIGH) = Desired fifo buffer too large 0x00020156 (SORRY,HIGH) = Desired fifo buffer too small 0x00020157 (FATAL,HIGH) = burn_source is not a fifo object + 0x00020158 (DEBUG,LOW) = Reporting thread disposal precautions libdax_audioxtr: