From 6fe53827da5d582a7ef4123495f7c0f4f6351b6e Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sat, 8 Nov 2008 14:18:14 +0000 Subject: [PATCH] Cancelling libburn fifo thread before freeing the fifo object --- cdrskin/cdrskin_timestamp.h | 2 +- libburn/async.c | 26 +++++++++++++++++++++++++- libburn/file.c | 13 +++++++++++-- libburn/file.h | 3 ++- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index 6e9c406..b4fb4f6 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2008.11.08.134828" +#define Cdrskin_timestamP "2008.11.08.141734" diff --git a/libburn/async.c b/libburn/async.c index e133cfe..ef6450c 100644 --- a/libburn/async.c +++ b/libburn/async.c @@ -25,9 +25,9 @@ #include "drive.h" #include "write.h" #include "options.h" +#include "file.h" #include "async.h" #include "init.h" -#include "file.h" #include "back_hacks.h" #include @@ -518,6 +518,12 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc) static void *fifo_worker_func(struct w_list *w) { + int old; + + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old); + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old); + /* Note: Only burn_fifo_abort() shall cancel the fifo thread */ + burn_fifo_source_shoveller(w->u.fifo.source, w->u.fifo.flag); remove_worker(pthread_self()); return NULL; @@ -547,6 +553,24 @@ int burn_fifo_start(struct burn_source *source, int flag) } +int burn_fifo_abort(struct burn_source_fifo *fs, int flag) +{ + int ret; + pthread_t pt; + + if (fs->thread_is_valid <= 0 || fs->thread_handle == NULL) + return(2); + + libdax_msgs_submit(libdax_messenger, -1, 0x00000002, + LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, + "Aborting running burn_source_fifo thread", 0, 0); + pt= *((pthread_t *) fs->thread_handle); + remove_worker(pt); + ret = pthread_cancel(pt); + return (ret == 0); +} + + #ifdef Libburn_has_burn_async_join_alL /* ts A71019 : never used */ diff --git a/libburn/file.c b/libburn/file.c index e4929a3..0f49ce1 100644 --- a/libburn/file.c +++ b/libburn/file.c @@ -9,6 +9,8 @@ #include #include #include +#include + #include "source.h" #include "libburn.h" #include "file.h" @@ -307,6 +309,7 @@ static void fifo_free(struct burn_source *source) { struct burn_source_fifo *fs = source->data; + burn_fifo_abort(fs, 0); if (fs->inp != NULL) burn_source_free(fs->inp); if (fs->buf != NULL) @@ -320,9 +323,12 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag) struct burn_source_fifo *fs = source->data; int ret, bufsize, diff, wpos, rpos, trans_end, free_bytes; char *bufpt; + pthread_t thread_handle_storage; + fs->thread_handle= &thread_handle_storage; + *((pthread_t *) fs->thread_handle)= pthread_self(); fs->thread_pid = getpid(); - fs->thread_pid_valid = 1; + fs->thread_is_valid = 1; bufsize = fs->chunksize * fs->chunks; while (!fs->end_of_consumption) { @@ -430,6 +436,8 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag) free(fs->buf); /* Give up fifo buffer. Next fifo might start soon. */ fs->buf = NULL; + fs->thread_handle= NULL; + fs->thread_is_valid = 0; return (fs->input_error == 0); } @@ -465,8 +473,9 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp, if (fs == NULL) return NULL; fs->is_started = 0; + fs->thread_handle = NULL; fs->thread_pid = 0; - fs->thread_pid_valid = 0; + fs->thread_is_valid = 0; fs->inp = NULL; /* set later */ fs->chunksize = chunksize; fs->chunks = chunks; diff --git a/libburn/file.h b/libburn/file.h index 7d99c64..1cee375 100644 --- a/libburn/file.h +++ b/libburn/file.h @@ -29,8 +29,9 @@ struct burn_source_fifo { */ int is_started; + void *thread_handle; /* actually a pointer to a thread_t */ int thread_pid; - int thread_pid_valid; + int thread_is_valid; /* the burn_source for which this fifo is acting as proxy */ struct burn_source *inp;