Trying to catch signals from within the writer thread
This commit is contained in:
parent
3dda4b92b9
commit
5d93e04b28
@ -1 +1 @@
|
||||
#define Cdrskin_timestamP "2007.09.27.093129"
|
||||
#define Cdrskin_timestamP "2007.09.29.185007"
|
||||
|
@ -338,7 +338,13 @@ void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
||||
|
||||
static void *write_disc_worker_func(struct w_list *w)
|
||||
{
|
||||
struct burn_drive *d = w->u.write.drive;
|
||||
|
||||
d->thread_pid = getpid();
|
||||
d->thread_pid_valid= 1;
|
||||
burn_disc_write_sync(w->u.write.opts, w->u.write.disc);
|
||||
d->thread_pid_valid= 0;
|
||||
d->thread_pid = 0;
|
||||
|
||||
/* the options are refcounted, free out ref count which we added below
|
||||
*/
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include "libburn.h"
|
||||
#include "init.h"
|
||||
#include "drive.h"
|
||||
#include "transport.h"
|
||||
#include "debug.h"
|
||||
@ -163,8 +164,18 @@ int burn_drive_is_occupied(struct burn_drive *d)
|
||||
if(d->busy == BURN_DRIVE_READING_SYNC ||
|
||||
d->busy == BURN_DRIVE_WRITING_SYNC)
|
||||
return 2;
|
||||
if(d->busy == BURN_DRIVE_READING || d->busy == BURN_DRIVE_WRITING)
|
||||
if(d->busy == BURN_DRIVE_WRITING) {
|
||||
|
||||
/* ts A70928 */
|
||||
/* >>> how do i learn whether the writer thread is still
|
||||
alive ? */;
|
||||
/* >>> what to do if writer is dead ?
|
||||
At least sync disc ?*/;
|
||||
|
||||
}
|
||||
if(d->busy == BURN_DRIVE_READING) {
|
||||
return 50;
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@ -317,6 +328,8 @@ struct burn_drive *burn_drive_register(struct burn_drive *d)
|
||||
d->rlba = 0;
|
||||
d->cancel = 0;
|
||||
d->busy = BURN_DRIVE_IDLE;
|
||||
d->thread_pid = 0;
|
||||
d->thread_pid_valid = 0;
|
||||
d->toc_entries = 0;
|
||||
d->toc_entry = NULL;
|
||||
d->disc = NULL;
|
||||
@ -717,6 +730,19 @@ int burn_disc_erasable(struct burn_drive *d)
|
||||
enum burn_drive_status burn_drive_get_status(struct burn_drive *d,
|
||||
struct burn_progress *p)
|
||||
{
|
||||
/* ts A70928 : inform control thread of signal in sub-threads */
|
||||
if (burn_global_abort_level > 0)
|
||||
burn_global_abort_level++;
|
||||
if (burn_global_abort_level > 5) {
|
||||
if (burn_global_signal_handler == NULL)
|
||||
kill(getpid(), burn_global_abort_signum);
|
||||
else
|
||||
(*burn_global_signal_handler)
|
||||
(burn_global_signal_handle,
|
||||
burn_global_abort_signum, 0);
|
||||
burn_global_abort_level = -1;
|
||||
}
|
||||
|
||||
if (p != NULL) {
|
||||
memcpy(p, &(d->progress), sizeof(struct burn_progress));
|
||||
/* TODO: add mutex */
|
||||
@ -2376,3 +2402,17 @@ int burn_drive_equals_adr(struct burn_drive *d1, char *adr2_in, int role2)
|
||||
}
|
||||
|
||||
|
||||
int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < drivetop + 1; i++)
|
||||
if (drive_array[i].thread_pid_valid &&
|
||||
drive_array[i].thread_pid == pid) {
|
||||
*d = &(drive_array[i]);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -121,4 +121,8 @@ int burn_disc_get_write_mode_demands(struct burn_disc *disc,
|
||||
int burn_drive__fd_from_special_adr(char *adr);
|
||||
|
||||
|
||||
/* ts A70929 : Find the drive which is being worked on by pid */
|
||||
int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid);
|
||||
|
||||
|
||||
#endif /* __DRIVE */
|
||||
|
@ -10,8 +10,11 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/* ts A70928 : init.h is for others, not for init .c
|
||||
#include "init.h"
|
||||
*/
|
||||
|
||||
|
||||
#include "sg.h"
|
||||
#include "error.h"
|
||||
#include "libburn.h"
|
||||
@ -56,7 +59,6 @@ int burn_sg_open_o_nonblock = 1;
|
||||
to unconditional abort of the process */
|
||||
int burn_sg_open_abort_busy = 0;
|
||||
|
||||
|
||||
/* ts A61002 */
|
||||
|
||||
#include "cleanup.h"
|
||||
@ -64,6 +66,10 @@ int burn_sg_open_abort_busy = 0;
|
||||
/* Parameters for builtin abort handler */
|
||||
static char abort_message_prefix[81] = {"libburn : "};
|
||||
static pid_t abort_control_pid= 0;
|
||||
volatile int burn_global_abort_level= 0;
|
||||
int burn_global_abort_signum= 0;
|
||||
void *burn_global_signal_handle = NULL;
|
||||
burn_abort_handler_t burn_global_signal_handler = NULL;
|
||||
|
||||
|
||||
/* ts A70223 : wether implemented untested profiles are supported */
|
||||
@ -263,38 +269,57 @@ int burn_msgs_submit(int error_code, char msg_text[], int os_errno,
|
||||
|
||||
int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
||||
{
|
||||
#define Libburn_new_thread_signal_handleR 1
|
||||
int ret;
|
||||
struct burn_drive *d;
|
||||
|
||||
/*
|
||||
fprintf(stderr, "libburn_ABORT: pid = %d , abort_control_pid = %d\n",
|
||||
getpid(), abort_control_pid);
|
||||
*/
|
||||
|
||||
/* ts A70928:
|
||||
Must be quick. Allowed to coincide with other thread and to share
|
||||
the increment with that one. It must not decrease, though, and
|
||||
yield at least 1 if any thread calls this function.
|
||||
*/
|
||||
burn_global_abort_level++;
|
||||
burn_global_abort_signum= signum;
|
||||
|
||||
if(getpid() != abort_control_pid) {
|
||||
|
||||
#ifdef Not_yeT
|
||||
pthread_t thread_id;
|
||||
#ifdef Libburn_new_thread_signal_handleR
|
||||
|
||||
/* >>> need better handling of self-induced SIGs
|
||||
like SIGSEGV or SIGFPE.
|
||||
Like bonking the control thread if it did not show up
|
||||
after a short while.
|
||||
*/
|
||||
ret = burn_drive_find_by_thread_pid(&d, getpid());
|
||||
if (ret > 0 && d->busy == BURN_DRIVE_WRITING) {
|
||||
/* This is an active writer thread */
|
||||
/*
|
||||
fprintf(stderr, "libburn_ABORT: pid %d found drive busy with writing, (level= %d)\n", (int) getpid(), burn_global_abort_level);
|
||||
*/
|
||||
|
||||
/* >>> if this is a non-fatal signal : return -2 */
|
||||
d->sync_cache(d);
|
||||
|
||||
thread_id = pthread_self();
|
||||
/* >>> find thread_id in worker list of async.c */
|
||||
/* >>> if owning a drive : mark idle and canceled
|
||||
(can't do anything more) */
|
||||
/* >>> perform a more qualified end of burn process */;
|
||||
|
||||
usleep(1000000); /* calm down */
|
||||
d->busy = BURN_DRIVE_IDLE;
|
||||
|
||||
/* forward signal to control thread */
|
||||
if (abort_control_pid>1)
|
||||
kill(abort_control_pid, signum);
|
||||
|
||||
/* >>> ??? end thread */;
|
||||
if (burn_global_abort_level > 0) {
|
||||
/* control process did not show up yet */
|
||||
/*
|
||||
fprintf(stderr, "libburn_ABORT: pid %d sending signum %d to pid %d\n", (int) getpid(), (int) signum, (int) abort_control_pid);
|
||||
*/
|
||||
kill(abort_control_pid, signum);
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
#else
|
||||
usleep(1000000); /* calm down */
|
||||
return -2;
|
||||
#endif /* ! Not_yeT */
|
||||
#endif /* ! Libburn_new_thread_signal_handleR */
|
||||
|
||||
}
|
||||
burn_global_abort_level = -1;
|
||||
Cleanup_set_handlers(NULL, NULL, 2);
|
||||
fprintf(stderr,"%sABORT : Trying to shut down drive and library\n",
|
||||
abort_message_prefix);
|
||||
@ -302,10 +327,13 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
||||
"%sABORT : Wait the normal burning time before any kill -9\n",
|
||||
abort_message_prefix);
|
||||
close(0); /* somehow stdin as input blocks abort until EOF */
|
||||
|
||||
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
|
||||
|
||||
fprintf(stderr,
|
||||
"\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n",
|
||||
abort_message_prefix);
|
||||
burn_global_abort_level = -2;
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -326,6 +354,8 @@ void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
|
||||
abort_message_prefix[sizeof(abort_message_prefix)-1] = 0;
|
||||
abort_control_pid = getpid();
|
||||
Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler, mode|4);
|
||||
burn_global_signal_handle = handle;
|
||||
burn_global_signal_handler = handler;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,4 +5,17 @@
|
||||
|
||||
extern int burn_running;
|
||||
|
||||
/** Indicator for burn_drive_get_status() wether a signal hit parts of the
|
||||
thread team.
|
||||
0= all works well ,
|
||||
1 to 5 = waiting for eventual signal on control thread
|
||||
> 5 = do abort now
|
||||
-1 = control thread has been informed
|
||||
*/
|
||||
extern volatile int burn_global_abort_level;
|
||||
extern int burn_global_abort_signum;
|
||||
extern void *burn_global_signal_handle;
|
||||
extern burn_abort_handler_t burn_global_signal_handler;
|
||||
|
||||
|
||||
#endif /* BURN__INIT_H */
|
||||
|
@ -251,6 +251,12 @@ struct burn_drive
|
||||
|
||||
volatile int cancel;
|
||||
volatile enum burn_drive_status busy;
|
||||
|
||||
/* ts A70929 */
|
||||
pid_t thread_pid;
|
||||
int thread_pid_valid;
|
||||
|
||||
|
||||
/* transport functions */
|
||||
int (*grab) (struct burn_drive *);
|
||||
int (*release) (struct burn_drive *);
|
||||
|
Loading…
Reference in New Issue
Block a user