Giving up use of function pthread_cancel()

This commit is contained in:
Thomas Schmitt 2017-01-28 21:02:17 +01:00
parent 6f6bf688d9
commit 724d518dbc
5 changed files with 95 additions and 32 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2016.11.18.132335" #define Cdrskin_timestamP "2017.01.28.200155"

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net> Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later. Provided under GPL version 2 or later.
*/ */
@ -123,6 +123,42 @@ struct w_list
static struct w_list *workers = NULL; static struct w_list *workers = NULL;
int burn_async_manage_lock(int mode)
{
int ret;
static pthread_mutex_t access_lock;
static int mutex_initialized = 0;
static int mutex_locked = 0;
if (mode == BURN_ASYNC_LOCK_INIT) {
if (mutex_initialized)
return 2;
ret = pthread_mutex_init(&access_lock, NULL);
if (ret != 0)
return 0;
mutex_initialized = 1;
return 1;
}
if (!mutex_initialized)
return 0;
if (mode == BURN_ASYNC_LOCK_OBTAIN) {
ret = pthread_mutex_lock(&access_lock);
if (ret != 0)
return 0;
mutex_locked = 1;
} else if (mode == BURN_ASYNC_LOCK_RELEASE) {
if (!mutex_locked)
return 2;
ret = pthread_mutex_unlock(&access_lock);
if (ret != 0)
return 0;
mutex_locked = 0;
}
return 1;
}
static struct w_list *find_worker(struct burn_drive *d) static struct w_list *find_worker(struct burn_drive *d)
{ {
struct w_list *a; struct w_list *a;
@ -149,9 +185,8 @@ static void add_worker(int w_type, struct burn_drive *d,
a->drive = d; a->drive = d;
a->u = *data; a->u = *data;
/*
memcpy(&(a->u), data, sizeof(union w_list_data)); burn_async_manage_lock(BURN_ASYNC_LOCK_INIT);
*/
/* insert at front of the list */ /* insert at front of the list */
a->next = workers; a->next = workers;
@ -162,6 +197,7 @@ static void add_worker(int w_type, struct burn_drive *d,
d->busy = BURN_DRIVE_SPAWNING; d->busy = BURN_DRIVE_SPAWNING;
#ifdef Libburn_create_detached_threadS #ifdef Libburn_create_detached_threadS
/* ts A71019 : /* ts A71019 :
Trying to start the threads detached to get rid of the zombies Trying to start the threads detached to get rid of the zombies
which do neither react on pthread_join() nor on pthread_detach(). which do neither react on pthread_join() nor on pthread_detach().
@ -169,12 +205,12 @@ static void add_worker(int w_type, struct burn_drive *d,
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
attr_pt= &attr; attr_pt= &attr;
/*
libdax_msgs_submit(libdax_messenger, -1, 0x00020158, #endif /* Libburn_create_detached_threadS */
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW,
"add_worker(): Creating detached thread.", 0, 0); /* Worker specific locks are to be released early by the worker */
*/ if (f == (WorkerFunc) burn_fifo_source_shoveller)
#endif burn_async_manage_lock(BURN_ASYNC_LOCK_OBTAIN);
if (pthread_create(&a->thread, attr_pt, f, a)) { if (pthread_create(&a->thread, attr_pt, f, a)) {
free(a); free(a);
@ -704,7 +740,6 @@ ex:;
static void *fifo_worker_func(struct w_list *w) static void *fifo_worker_func(struct w_list *w)
{ {
int old;
#define Libburn_protect_fifo_threaD 1 #define Libburn_protect_fifo_threaD 1
@ -718,10 +753,6 @@ static void *fifo_worker_func(struct w_list *w)
pthread_sigmask(SIG_SETMASK, &sigset, &oldset); pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
#endif /* Libburn_protect_fifo_threaD */ #endif /* Libburn_protect_fifo_threaD */
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); burn_fifo_source_shoveller(w->u.fifo.source, w->u.fifo.flag);
remove_worker(pthread_self()); remove_worker(pthread_self());
@ -764,18 +795,19 @@ int burn_fifo_abort(struct burn_source_fifo *fs, int flag)
int ret; int ret;
pthread_t pt; pthread_t pt;
if (fs->thread_is_valid <= 0 || fs->thread_handle == NULL) burn_async_manage_lock(BURN_ASYNC_LOCK_OBTAIN);
return(2);
#ifdef NIX if (fs->thread_is_valid <= 0 || fs->thread_handle == NULL) {
libdax_msgs_submit(libdax_messenger, -1, 0x00000002, burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, return 2;
"Aborting running burn_source_fifo thread", 0, 0); }
#endif /* NIX */ pt = *((pthread_t *) fs->thread_handle);
burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
fs->do_abort = 1;
ret = pthread_join(pt, NULL);
pt= *((pthread_t *) fs->thread_handle);
remove_worker(pt);
ret = pthread_cancel(pt);
return (ret == 0); return (ret == 0);
} }

View File

@ -1,5 +1,10 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
#ifndef BURN__ASYNC_H #ifndef BURN__ASYNC_H
#define BURN__ASYNC_H #define BURN__ASYNC_H
@ -14,5 +19,10 @@ int burn_fifo_start(struct burn_source *source, int flag);
/* To abort a running fifo thread before the fifo object gets deleted */ /* To abort a running fifo thread before the fifo object gets deleted */
int burn_fifo_abort(struct burn_source_fifo *fs, int flag); int burn_fifo_abort(struct burn_source_fifo *fs, int flag);
/* ts B70126 */
#define BURN_ASYNC_LOCK_RELEASE 0
#define BURN_ASYNC_LOCK_OBTAIN 1
#define BURN_ASYNC_LOCK_INIT 2
int burn_async_manage_lock(int mode);
#endif /* BURN__ASYNC_H */ #endif /* BURN__ASYNC_H */

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net> Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later. Provided under GPL version 2 or later.
*/ */
@ -356,13 +356,20 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
fs->thread_pid = getpid(); fs->thread_pid = getpid();
fs->thread_is_valid = 1; fs->thread_is_valid = 1;
/* Lock was obtained by async.c:add_worker() */
burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
bufsize = fs->chunksize * fs->chunks; bufsize = fs->chunksize * fs->chunks;
while (!fs->end_of_consumption) { while (!fs->end_of_consumption) {
if (fs->do_abort)
goto emergency_exit;
/* wait for enough buffer space available */ /* wait for enough buffer space available */
wpos = fs->buf_writepos; wpos = fs->buf_writepos;
counted = 0; counted = 0;
while (1) { while (1) {
if (fs->do_abort)
goto emergency_exit;
rpos = fs->buf_readpos; rpos = fs->buf_readpos;
diff = rpos - wpos; diff = rpos - wpos;
trans_end = 0; trans_end = 0;
@ -405,6 +412,8 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
} }
/* Obtain next chunk */ /* Obtain next chunk */
if (fs->do_abort)
goto emergency_exit;
if (fs->inp->read != NULL) if (fs->inp->read != NULL)
ret = fs->inp->read(fs->inp, ret = fs->inp->read(fs->inp,
(unsigned char *) bufpt, fs->inp_read_size); (unsigned char *) bufpt, fs->inp_read_size);
@ -430,6 +439,8 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
fs->put_counter++; fs->put_counter++;
/* activate read chunk */ /* activate read chunk */
if (fs->do_abort)
goto emergency_exit;
if (ret > fs->inp_read_size) if (ret > fs->inp_read_size)
/* beware of ill custom burn_source */ /* beware of ill custom burn_source */
ret = fs->inp_read_size; ret = fs->inp_read_size;
@ -463,8 +474,11 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
fs->end_of_input = 1; fs->end_of_input = 1;
/* wait for end of reading by consumer */; /* wait for end of reading by consumer */;
while (fs->buf_readpos != fs->buf_writepos && !fs->end_of_consumption) while (fs->buf_readpos != fs->buf_writepos && !fs->end_of_consumption) {
fifo_sleep(0); if (fs->do_abort)
goto emergency_exit;
fifo_sleep(0);
}
/* destroy ring buffer */; /* destroy ring buffer */;
if (!fs->end_of_consumption) if (!fs->end_of_consumption)
@ -481,8 +495,11 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
((size_t) fs->chunksize) * (size_t) fs->chunks, 0); ((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
fs->buf = NULL; fs->buf = NULL;
emergency_exit:;
burn_async_manage_lock(BURN_ASYNC_LOCK_OBTAIN);
fs->thread_handle= NULL; fs->thread_handle= NULL;
fs->thread_is_valid = 0; fs->thread_is_valid = 0;
burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
return (fs->input_error == 0); return (fs->input_error == 0);
} }
@ -524,6 +541,7 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
fs->thread_handle = NULL; fs->thread_handle = NULL;
fs->thread_pid = 0; fs->thread_pid = 0;
fs->thread_is_valid = 0; fs->thread_is_valid = 0;
fs->do_abort = 0;
fs->inp = NULL; /* set later */ fs->inp = NULL; /* set later */
if (flag & 1) if (flag & 1)
fs->inp_read_size = 32 * 1024; fs->inp_read_size = 32 * 1024;

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net> Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later. Provided under GPL version 2 or later.
*/ */
@ -27,8 +27,8 @@ struct burn_source_fifo {
/* The fifo stays inactive and unequipped with eventual resources /* The fifo stays inactive and unequipped with eventual resources
until its read() method is called for the first time. until its read() method is called for the first time.
Only then burn_fifo_start() gets called, allocates the complete Only then burn_fifo_start() gets called, allocates the complete
resources, starts a thread with burn_fifo_source_shuffler() resources, starts a thread with burn_fifo_source_shoveller()
which shuffles data and finally destroys the resources. which shovels data and finally destroys the resources.
This late start is to stay modest in case of multiple tracks This late start is to stay modest in case of multiple tracks
in one disc. in one disc.
*/ */
@ -38,6 +38,9 @@ struct burn_source_fifo {
int thread_pid; int thread_pid;
int thread_is_valid; int thread_is_valid;
/* The shoveller aborts if this is 1. Resource leaks are possible. */
volatile int do_abort;
/* the burn_source for which this fifo is acting as proxy */ /* the burn_source for which this fifo is acting as proxy */
struct burn_source *inp; struct burn_source *inp;
int inp_read_size; int inp_read_size;