Implemented burn_abort() and made use of it

This commit is contained in:
Thomas Schmitt 2006-10-02 10:35:51 +00:00
parent 5aa2729766
commit b3bea43074
7 changed files with 147 additions and 11 deletions

View File

@ -167,6 +167,7 @@ or
#define Cdrskin_libburn_has_convert_fs_adR 1
#define Cdrskin_libburn_has_convert_scsi_adR 1
#define Cdrskin_libburn_has_burn_msgS 1
#define Cdrskin_libburn_has_burn_aborT 1
#endif
#ifndef Cdrskin_libburn_versioN
@ -2633,10 +2634,20 @@ int Cdrskin_release_drive(struct CdrskiN *skin, int flag)
*/
int Cdrskin_abort_handler(struct CdrskiN *skin, int signum, int flag)
{
#ifdef Cdrskin_libburn_has_burn_aborT
int ret;
#else
int wait_grain= 100000,first_status= 1;
double start_time,last_time,current_time;
#endif /* ! Cdrskin_libburn_has_burn_aborT */
struct burn_progress p;
enum burn_drive_status drive_status= BURN_DRIVE_GRABBING;
double start_time,last_time,current_time;
if(getpid()!=skin->control_pid) {
if(skin->verbosity>=Cdrskin_verbose_debuG)
@ -2660,6 +2671,27 @@ int Cdrskin_abort_handler(struct CdrskiN *skin, int signum, int flag)
Cdrfifo_close_all(skin->fifo,0);
#endif
#ifdef Cdrskin_libburn_has_burn_aborT
/* Only for user info */
if(skin->grabbed_drive!=NULL)
drive_status= burn_drive_get_status(skin->grabbed_drive,&p);
if(drive_status!=BURN_DRIVE_IDLE) {
fprintf(stderr,"cdrskin: ABORT : Abort processing depends on CD speed and buffer size\n");
fprintf(stderr,"cdrskin: ABORT : Usually it is done with 4x speed after about a MINUTE\n");
fprintf(stderr,"cdrskin: URGE : But wait at least the normal burning time before any kill -9\n");
}
ret= burn_abort(skin->abort_max_wait, burn_abort_pacifier, "cdrskin: ");
if(ret<=0) {
fprintf(stderr,
"\ncdrskin: ABORT : Cannot cancel burn session and release drive.\n");
return(0);
}
fprintf(stderr,"\n");
#else /* Cdrskin_libburn_has_burn_aborT */
if(skin->grabbed_drive!=NULL) {
drive_status= burn_drive_get_status(skin->grabbed_drive,&p);
if(drive_status!=BURN_DRIVE_IDLE && !skin->drive_is_grabbed)
@ -2751,6 +2783,9 @@ try_to_finish_lib:;
fprintf(stderr,"cdrskin: ABORT : Trying to finish libburn.\n");
burn_finish();
}
#endif /* ! Cdrskin_libburn_has_burn_aborT */
fprintf(stderr,
"cdrskin: ABORT : Drive is released and library is shut down now.\n");
fprintf(stderr,

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2006.10.01.104140"
#define Cdrskin_timestamP "2006.10.02.103418"

View File

@ -27,9 +27,6 @@ extern struct libdax_msgs *libdax_messenger;
static struct burn_drive drive_array[255];
static int drivetop = -1;
int burn_drive_is_open(struct burn_drive *d);
int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count);
/* ts A60904 : ticket 62, contribution by elmom */
/* splitting former burn_drive_free() (which freed all, into two calls) */
@ -527,13 +524,11 @@ void burn_drive_info_free(struct burn_drive_info drive_infos[])
burn_drive_free_all();
}
/* Experimental API call */
int burn_drive_info_forget(struct burn_drive_info *info, int force)
/* ts A61001 : internal call */
int burn_drive_forget(struct burn_drive *d, int force)
{
int occup;
struct burn_drive *d;
d = info->drive;
occup = burn_drive_is_occupied(d);
/*
fprintf(stderr, "libburn: experimental: occup == %d\n",occup);
@ -556,6 +551,12 @@ int burn_drive_info_forget(struct burn_drive_info *info, int force)
return 1;
}
/* API call */
int burn_drive_info_forget(struct burn_drive_info *info, int force)
{
return burn_drive_forget(info->drive, force);
}
struct burn_disc *burn_drive_get_disc(struct burn_drive *d)
{
d->disc->refcnt++;
@ -954,3 +955,74 @@ int burn_drive_convert_fs_adr(char *path, char adr[])
return ret;
}
/** A pacifier function suitable for burn_abort.
@param handle If not NULL, a pointer to a text suitable for printf("%s")
*/
int burn_abort_pacifier(void *handle, int patience, int elapsed)
{
char *prefix= "libburn : ";
if(handle!=NULL)
prefix= handle;
fprintf(stderr,
"\r%sABORT : Waiting for drive to finish since %d seconds (%d max)",
(char *) prefix, elapsed, patience);
return(1);
}
/** Abort any running drive operation and finis libburn.
@param patience Maximum number of seconds to wait for drives to finish
@param pacifier_func Function to produce appeasing messages. See
burn_abort_pacifier() for an example.
@return 1 ok, all went well
0 had to leave a drive in unclean state
<0 severe error, do no use libburn again
*/
int burn_abort(int patience,
int (*pacifier_func)(void *handle, int patience, int elapsed),
void *handle)
{
int ret, i, occup, still_not_done= 1, pacifier_off= 0, first_round= 1;
unsigned long wait_grain= 100000;
time_t start_time, current_time, pacifier_time, end_time;
current_time = start_time = pacifier_time = time(0);
end_time = start_time + patience;
while(current_time-end_time < patience) {
still_not_done = 0;
for(i = 0; i < drivetop + 1; i++) {
occup = burn_drive_is_occupied(&(drive_array[i]));
if(occup == -2)
continue;
if(occup <= 10) {
burn_drive_forget(&(drive_array[i]), 1);
} else if(occup <= 100) {
if(first_round)
burn_drive_cancel(&(drive_array[i]));
still_not_done++;
} else if(occup <= 1000) {
still_not_done++;
}
}
first_round = 0;
if(still_not_done == 0)
break;
usleep(wait_grain);
current_time = time(0);
if(current_time>pacifier_time) {
if(pacifier_func != NULL && !pacifier_off) {
ret = (*pacifier_func)(handle, patience,
current_time-start_time);
pacifier_off = (ret <= 0);
}
pacifier_time = current_time;
}
}
burn_finish();
return(still_not_done == 0);
}

View File

@ -52,7 +52,9 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast);
int burn_drive_get_block_types(struct burn_drive *d,
enum burn_write_types write_type);
/* ts A60822 */
int burn_drive_is_open(struct burn_drive *d);
int burn_drive_is_occupied(struct burn_drive *d);
int burn_drive_forget(struct burn_drive *d, int force);
int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count);
#endif /* __DRIVE */

View File

@ -391,6 +391,25 @@ int burn_initialize(void);
*/
void burn_finish(void);
/** Abort any running drive operation and finally call burn_finish().
@param patience Maximum number of seconds to wait for drives to finish
@param pacifier_func If not NULL: a function to produce appeasing messages.
See burn_abort_pacifier() for an example.
@return 1 ok, all went well
0 had to leave a drive in unclean state
<0 severe error, do no use libburn again
*/
int burn_abort(int patience,
int (*pacifier_func)(void *handle, int patience, int elapsed),
void *handle);
/** A pacifier function suitable for burn_abort.
@param handle If not NULL, a pointer to a text suitable for printf("%s")
*/
int burn_abort_pacifier(void *handle, int patience, int elapsed);
/** Set the verbosity level of the library. The default value is 0, which means
that nothing is output on stderr. The more you increase this, the more
debug output should be displayed on stderr for you.

View File

@ -224,6 +224,8 @@ int libdax_msgs__text_to_sev(char *severity_name, int *severity,
{
if(strncmp(severity_name,"NEVER",5)==0)
*severity= LIBDAX_MSGS_SEV_NEVER;
else if(strncmp(severity_name,"ABORT",5)==0)
*severity= LIBDAX_MSGS_SEV_ABORT;
else if(strncmp(severity_name,"FATAL",5)==0)
*severity= LIBDAX_MSGS_SEV_FATAL;
else if(strncmp(severity_name,"SORRY",5)==0)
@ -253,12 +255,14 @@ int libdax_msgs__sev_to_text(int severity, char **severity_name,
{
if(flag&1) {
*severity_name=
"NEVER\nFATAL\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nALL";
"NEVER\nABORT\nFATAL\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nALL";
return(1);
}
*severity_name= "";
if(severity>=LIBDAX_MSGS_SEV_NEVER)
*severity_name= "NEVER";
else if(severity>=LIBDAX_MSGS_SEV_ABORT)
*severity_name= "ABORT";
else if(severity>=LIBDAX_MSGS_SEV_FATAL)
*severity_name= "FATAL";
else if(severity>=LIBDAX_MSGS_SEV_SORRY)

View File

@ -121,6 +121,10 @@ struct libdax_msgs_item;
*/
#define LIBDAX_MSGS_SEV_FATAL 0x70000000
/** A message from an abort handler which will finally finish libburn
*/
#define LIBDAX_MSGS_SEV_ABORT 0x71000000
/** A severity to exclude resp. discard any possible message.
Do not use this severity for submitting.
*/