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)
|
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);
|
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
|
/* the options are refcounted, free out ref count which we added below
|
||||||
*/
|
*/
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
|
#include "init.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
@ -163,8 +164,18 @@ int burn_drive_is_occupied(struct burn_drive *d)
|
|||||||
if(d->busy == BURN_DRIVE_READING_SYNC ||
|
if(d->busy == BURN_DRIVE_READING_SYNC ||
|
||||||
d->busy == BURN_DRIVE_WRITING_SYNC)
|
d->busy == BURN_DRIVE_WRITING_SYNC)
|
||||||
return 2;
|
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 50;
|
||||||
|
}
|
||||||
return 1000;
|
return 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,6 +328,8 @@ struct burn_drive *burn_drive_register(struct burn_drive *d)
|
|||||||
d->rlba = 0;
|
d->rlba = 0;
|
||||||
d->cancel = 0;
|
d->cancel = 0;
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
|
d->thread_pid = 0;
|
||||||
|
d->thread_pid_valid = 0;
|
||||||
d->toc_entries = 0;
|
d->toc_entries = 0;
|
||||||
d->toc_entry = NULL;
|
d->toc_entry = NULL;
|
||||||
d->disc = 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,
|
enum burn_drive_status burn_drive_get_status(struct burn_drive *d,
|
||||||
struct burn_progress *p)
|
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) {
|
if (p != NULL) {
|
||||||
memcpy(p, &(d->progress), sizeof(struct burn_progress));
|
memcpy(p, &(d->progress), sizeof(struct burn_progress));
|
||||||
/* TODO: add mutex */
|
/* 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);
|
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 */
|
#endif /* __DRIVE */
|
||||||
|
@ -10,8 +10,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* ts A70928 : init.h is for others, not for init .c
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "sg.h"
|
#include "sg.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
@ -56,7 +59,6 @@ int burn_sg_open_o_nonblock = 1;
|
|||||||
to unconditional abort of the process */
|
to unconditional abort of the process */
|
||||||
int burn_sg_open_abort_busy = 0;
|
int burn_sg_open_abort_busy = 0;
|
||||||
|
|
||||||
|
|
||||||
/* ts A61002 */
|
/* ts A61002 */
|
||||||
|
|
||||||
#include "cleanup.h"
|
#include "cleanup.h"
|
||||||
@ -64,6 +66,10 @@ int burn_sg_open_abort_busy = 0;
|
|||||||
/* Parameters for builtin abort handler */
|
/* Parameters for builtin abort handler */
|
||||||
static char abort_message_prefix[81] = {"libburn : "};
|
static char abort_message_prefix[81] = {"libburn : "};
|
||||||
static pid_t abort_control_pid= 0;
|
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 */
|
/* 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)
|
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) {
|
if(getpid() != abort_control_pid) {
|
||||||
|
|
||||||
#ifdef Not_yeT
|
#ifdef Libburn_new_thread_signal_handleR
|
||||||
pthread_t thread_id;
|
|
||||||
|
|
||||||
/* >>> need better handling of self-induced SIGs
|
ret = burn_drive_find_by_thread_pid(&d, getpid());
|
||||||
like SIGSEGV or SIGFPE.
|
if (ret > 0 && d->busy == BURN_DRIVE_WRITING) {
|
||||||
Like bonking the control thread if it did not show up
|
/* This is an active writer thread */
|
||||||
after a short while.
|
/*
|
||||||
*/
|
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();
|
/* >>> perform a more qualified end of burn process */;
|
||||||
/* >>> find thread_id in worker list of async.c */
|
|
||||||
/* >>> if owning a drive : mark idle and canceled
|
|
||||||
(can't do anything more) */
|
|
||||||
|
|
||||||
usleep(1000000); /* calm down */
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
|
|
||||||
/* forward signal to control thread */
|
if (burn_global_abort_level > 0) {
|
||||||
if (abort_control_pid>1)
|
/* control process did not show up yet */
|
||||||
kill(abort_control_pid, signum);
|
/*
|
||||||
|
fprintf(stderr, "libburn_ABORT: pid %d sending signum %d to pid %d\n", (int) getpid(), (int) signum, (int) abort_control_pid);
|
||||||
/* >>> ??? end thread */;
|
*/
|
||||||
|
kill(abort_control_pid, signum);
|
||||||
|
}
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
usleep(1000000); /* calm down */
|
usleep(1000000); /* calm down */
|
||||||
return -2;
|
return -2;
|
||||||
#endif /* ! Not_yeT */
|
#endif /* ! Libburn_new_thread_signal_handleR */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
burn_global_abort_level = -1;
|
||||||
Cleanup_set_handlers(NULL, NULL, 2);
|
Cleanup_set_handlers(NULL, NULL, 2);
|
||||||
fprintf(stderr,"%sABORT : Trying to shut down drive and library\n",
|
fprintf(stderr,"%sABORT : Trying to shut down drive and library\n",
|
||||||
abort_message_prefix);
|
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",
|
"%sABORT : Wait the normal burning time before any kill -9\n",
|
||||||
abort_message_prefix);
|
abort_message_prefix);
|
||||||
close(0); /* somehow stdin as input blocks abort until EOF */
|
close(0); /* somehow stdin as input blocks abort until EOF */
|
||||||
|
|
||||||
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
|
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n",
|
"\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n",
|
||||||
abort_message_prefix);
|
abort_message_prefix);
|
||||||
|
burn_global_abort_level = -2;
|
||||||
return(1);
|
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_message_prefix[sizeof(abort_message_prefix)-1] = 0;
|
||||||
abort_control_pid = getpid();
|
abort_control_pid = getpid();
|
||||||
Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler, mode|4);
|
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;
|
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 */
|
#endif /* BURN__INIT_H */
|
||||||
|
@ -251,6 +251,12 @@ struct burn_drive
|
|||||||
|
|
||||||
volatile int cancel;
|
volatile int cancel;
|
||||||
volatile enum burn_drive_status busy;
|
volatile enum burn_drive_status busy;
|
||||||
|
|
||||||
|
/* ts A70929 */
|
||||||
|
pid_t thread_pid;
|
||||||
|
int thread_pid_valid;
|
||||||
|
|
||||||
|
|
||||||
/* transport functions */
|
/* transport functions */
|
||||||
int (*grab) (struct burn_drive *);
|
int (*grab) (struct burn_drive *);
|
||||||
int (*release) (struct burn_drive *);
|
int (*release) (struct burn_drive *);
|
||||||
|
Loading…
Reference in New Issue
Block a user