Made burn_drive_scan_and_grab() extend the drive list rather than replacing it

This commit is contained in:
Thomas Schmitt 2007-09-07 19:09:25 +00:00
parent 1935d222ed
commit c62e63a8d9
4 changed files with 68 additions and 30 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2007.09.07.184631" #define Cdrskin_timestamP "2007.09.07.190916"

View File

@ -82,8 +82,10 @@ void burn_drive_free(struct burn_drive *d)
return; return;
/* ts A60822 : close open fds before forgetting them */ /* ts A60822 : close open fds before forgetting them */
if (d->drive_role == 1) if (d->drive_role == 1)
if (burn_drive_is_open(d)) if (burn_drive_is_open(d)) {
d->unlock(d);
d->release(d); d->release(d);
}
burn_drive_free_subs(d); burn_drive_free_subs(d);
d->global_index = -1; d->global_index = -1;
} }
@ -782,7 +784,7 @@ int burn_drive_scan_sync(struct burn_drive_info *drives[],
unsigned int *n_drives, int flag) unsigned int *n_drives, int flag)
{ {
/* ts A70907 : /* ts A70907 :
There seems to be a misunderstanding about the role of There seems to have been a misunderstanding about the role of
burn_drive_scan_sync(). It needs no static state because it burn_drive_scan_sync(). It needs no static state because it
is only started once during an asynchronous scan operation. is only started once during an asynchronous scan operation.
Its starter, burn_drive_scan(), is the one which ends immediately Its starter, burn_drive_scan(), is the one which ends immediately
@ -792,13 +794,22 @@ int burn_drive_scan_sync(struct burn_drive_info *drives[],
burn_drive_scan_sync(). burn_drive_scan_sync().
The scanning itself is not parallel but enumerates sequentially The scanning itself is not parallel but enumerates sequentially
drive by drive (within scsi_enumerate_drives()). drive by drive (within scsi_enumerate_drives()).
I will use "scanned" for marking drives found by previous runs.
Leaving it static for now, but initializing it on each call by
iterating over the list of known drives.
*/ */
/* state vars for the scan process */ /* state vars for the scan process */
/* ts A60904 : did set some default values to feel comfortable */ /* ts A60904 : did set some default values to feel comfortable */
static int scanning = 0, scanned = 0, found = 0; static int scanning = 0;
/* ts A70907 :
These variables are too small anyway. We got up to 255 drives.
static int scanned = 0, found = 0;
Variable "found" was only set but never read.
*/
static unsigned char scanned[32];
static unsigned num_scanned = 0, count = 0; static unsigned num_scanned = 0, count = 0;
unsigned int i; int i;
/* ts A61007 : moved up to burn_drive_scan() */ /* ts A61007 : moved up to burn_drive_scan() */
/* a ssert(burn_running); */ /* a ssert(burn_running); */
@ -815,16 +826,26 @@ int burn_drive_scan_sync(struct burn_drive_info *drives[],
state */ state */
#endif /* 0 */ #endif /* 0 */
/* ts A70907 : moved here from burn_drive_info_free() */ *n_drives = num_scanned = 0;
if (flag & 1)
/* ts A70907 : wether to scan from scratch or to extend */
if (flag & 1) {
burn_drive_free_all(); burn_drive_free_all();
for (i = 0; i < sizeof(scanned); i++)
scanned[i] = 0;
} else {
for (i = 0; i <= drivetop; i++)
if (drive_array[i].global_index >= 0) {
scanned[i / 8] |= (1 << (i % 8));
num_scanned++;
}
}
/* refresh the lib's drives */ /* refresh the lib's drives */
/* ts A61115 : formerly sg_enumerate(); ata_enumerate(); */ /* ts A61115 : formerly sg_enumerate(); ata_enumerate(); */
scsi_enumerate_drives(); scsi_enumerate_drives();
*n_drives = scanned = found = num_scanned = 0;
count = burn_drive_count(); count = burn_drive_count();
if (count) { if (count) {
/* ts A70907 : /* ts A70907 :
@ -840,23 +861,23 @@ int burn_drive_scan_sync(struct burn_drive_info *drives[],
scanning = 0; scanning = 0;
return -1; return -1;
} else } else
(*drives)[count].drive = NULL; /* end mark */ for (i = 0; i <= count; i++) /* invalidate */
(*drives)[i].drive = NULL;
} else } else
*drives = NULL; *drives = NULL;
} }
for (i = 0; i < count; ++i) { for (i = 0; i < count; ++i) {
if (scanned & (1 << i)) if (scanned[i / 8] & (1 << (i % 8)))
continue; /* already scanned the device */ continue; /* device already scanned by previous run */
while (!drive_getcaps(&drive_array[i], while (!drive_getcaps(&drive_array[i],
&(*drives)[num_scanned])) { &(*drives)[*n_drives])) {
sleep(1); sleep(1);
} }
scanned |= 1 << i;
found |= 1 << i;
num_scanned++;
(*n_drives)++; (*n_drives)++;
scanned[i / 8] |= 1 << (i % 8);
num_scanned++;
} }
if (num_scanned == count) { if (num_scanned == count) {
@ -1140,9 +1161,21 @@ int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], char* adr,
int load) int load)
{ {
unsigned int n_drives; unsigned int n_drives;
int ret; int ret, i;
/* >>> check wether drive adress is already registered */ /* check wether drive adress is already registered */
for (i = 0; i <= drivetop; i++)
if (drive_array[i].global_index >= 0)
if (strcmp(drive_array[i].devname, adr) == 0)
break;
if (i <= drivetop) {
libdax_msgs_submit(libdax_messenger, i,
0x0002014b,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Drive is already registered resp. scanned",
0, 0);
return -1;
}
if(strncmp(adr, "stdio:", 6) == 0) { if(strncmp(adr, "stdio:", 6) == 0) {
ret = burn_drive_grab_dummy(drive_infos, adr + 6); ret = burn_drive_grab_dummy(drive_infos, adr + 6);
@ -1156,7 +1189,7 @@ int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], char* adr,
adr); adr);
*/ */
/* ts A70907 : now calling synchronously rather than looping */ /* ts A70907 : now calling synchronously rather than looping */
ret = burn_drive_scan_sync(drive_infos, &n_drives, 0); ret = burn_drive_scan_sync(drive_infos, &n_drives, 0);
if (ret < 0) if (ret < 0)
return -1; return -1;
@ -1164,7 +1197,11 @@ int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], char* adr,
if (n_drives <= 0) if (n_drives <= 0)
return 0; return 0;
/* /*
fprintf(stderr, "libburn: experimental: n_drives == %d\n",n_drives); fprintf(stderr, "libburn: experimental: n_drives %d , drivetop %d\n",
n_drives, drivetop);
if (n_drives > 0)
fprintf(stderr, "libburn: experimental: global_index %d\n",
drive_infos[0]->drive->global_index);
*/ */
ret = burn_drive_grab(drive_infos[0]->drive, load); ret = burn_drive_grab(drive_infos[0]->drive, load);

View File

@ -626,12 +626,6 @@ void burn_allow_untested_profiles(int yes);
way to open one drive and to leave all others untouched. It bundles way to open one drive and to leave all others untouched. It bundles
the following API calls to form a non-obtrusive way to use libburn: the following API calls to form a non-obtrusive way to use libburn:
burn_drive_add_whitelist() , burn_drive_scan() , burn_drive_grab() burn_drive_add_whitelist() , burn_drive_scan() , burn_drive_grab()
<<< Restriction in progress of being removed:
To avoid memory leaks or dangling pointers one MUST shutdown all
burn_drive_info arrays by burn_drive_info_free() before calling
burn_drive_scan() a second time.
You are *strongly urged* to use this call whenever you know the drive You are *strongly urged* to use this call whenever you know the drive
address in advance. address in advance.
If not, then you have to use directly above calls. In that case, you are If not, then you have to use directly above calls. In that case, you are
@ -642,6 +636,11 @@ void burn_allow_untested_profiles(int yes);
use the function described here with an address obtained after use the function described here with an address obtained after
burn_drive_scan() via burn_drive_get_adr(&(drive_infos[driveno]), adr) . burn_drive_scan() via burn_drive_get_adr(&(drive_infos[driveno]), adr) .
Another way is to drop the unwanted drives by burn_drive_info_forget(). Another way is to drop the unwanted drives by burn_drive_info_forget().
Other than with burn_drive_scan() it is allowed to call
burn_drive_scan_and_grab() without giving up any other scanned drives.
So this call can be used to hold aquired more than one drive at a time.
@param drive_infos On success returns a one element array with the drive @param drive_infos On success returns a one element array with the drive
(cdrom/burner). Thus use with driveno 0 only. On failure (cdrom/burner). Thus use with driveno 0 only. On failure
the array has no valid elements at all. the array has no valid elements at all.
@ -675,13 +674,14 @@ void burn_drive_clear_whitelist(void);
/** Scan for drives. This function MUST be called until it returns nonzero. /** Scan for drives. This function MUST be called until it returns nonzero.
No drives may be in use when this is called. In case of re-scanning:
All pointers to struct burn_drive and all struct burn_drive_info arrays All pointers to struct burn_drive and all struct burn_drive_info arrays
are invalidated by using this function. Do NOT store drive pointers across are invalidated by using this function. Do NOT store drive pointers across
calls to this function ! calls to this function !
To avoid memory leaks or dangling pointers one MUST shutdown all To avoid invalid pointers one MUST free all burn_drive_info arrays
burn_drive_info arrays by burn_drive_info_free() before calling by burn_drive_info_free() before calling burn_drive_scan() a second time.
bunr_drive_scan() a second time. If there are drives left, then burn_drive_scan() will refuse to work.
After this call all drives depicted by the returned array are subject After this call all drives depicted by the returned array are subject
to eventual (O_EXCL) locking. See burn_preset_device_open(). This state to eventual (O_EXCL) locking. See burn_preset_device_open(). This state
ends either with burn_drive_info_forget() or with burn_drive_release(). ends either with burn_drive_info_forget() or with burn_drive_release().

View File

@ -383,6 +383,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x00020148 (SORRY,HIGH) = Cannot write desired amount of data 0x00020148 (SORRY,HIGH) = Cannot write desired amount of data
0x00020149 (SORRY,HIGH) = Unsuitable filetype for pseudo-drive 0x00020149 (SORRY,HIGH) = Unsuitable filetype for pseudo-drive
0x0002014a (SORRY,HIGH) = Cannot read desired amount of data 0x0002014a (SORRY,HIGH) = Cannot read desired amount of data
0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned
libdax_audioxtr: libdax_audioxtr: