Skip to content

Commit

Permalink
When filebrowser is scanning archive and one or more of the files nee…
Browse files Browse the repository at this point in the history
…ds to be probed, keep one of them in an open state until the scan is complete. This avoids the archive closing its io-file handle due reference count falling to zero if the archive directory listing was cached in ADB.
  • Loading branch information
mywave82 committed Dec 4, 2024
1 parent 1eb1ee1 commit 4d334ac
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 26 deletions.
10 changes: 8 additions & 2 deletions filesel/mdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,8 @@ int mdbWriteModuleInfo (uint32_t mdb_ref, struct moduleinfostruct *m)
return !retval;
}

void mdbScan (struct ocpfile_t *file, uint32_t mdb_ref)
/* if retain is non-zero, do not unref filehandle, but pass it to caller when done */
void mdbScan (struct ocpfile_t *file, uint32_t mdb_ref, struct ocpfilehandle_t **retain)
{
DEBUG_PRINT ("mdbScan(file=%p, mdb_ref=0x%08"PRIx32")\n", file, mdb_ref);
assert (mdb_ref > 0);
Expand All @@ -519,7 +520,12 @@ void mdbScan (struct ocpfile_t *file, uint32_t mdb_ref)
}
mdbGetModuleInfo(&mdbEditBuf, mdb_ref);
mdbReadInfo(&mdbEditBuf, f);
f->unref (f);
if (retain)
{
*retain = f;
} else {
f->unref (f);
}
mdbWriteModuleInfo(mdb_ref, &mdbEditBuf);
}
}
Expand Down
2 changes: 1 addition & 1 deletion filesel/mdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ int mdbGetModuleType (uint32_t fileref, struct moduletype *dst);
int mdbInfoIsAvailable (uint32_t fileref); // used to be mdbInfoRead
int mdbReadInfo(struct moduleinfostruct *m, struct ocpfilehandle_t *f);
int mdbWriteModuleInfo(uint32_t fileref, struct moduleinfostruct *m); // returns zero on error
void mdbScan(struct ocpfile_t *file, uint32_t mdb_ref);
void mdbScan(struct ocpfile_t *file, uint32_t mdb_ref, struct ocpfilehandle_t **retain); // if retain is non-zero, do not unref filehandle, but pass it to caller
int mdbInit (const struct configAPI_t *configAPI); // returns zero on error
void mdbUpdate(void);
void mdbClose(void);
Expand Down
4 changes: 2 additions & 2 deletions filesel/modlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ void modlist_append_drive (struct modlist *modlist, struct dmDrive *drive)
modlist_append (modlist, &entry);
}

void modlist_append_file (struct modlist *modlist, struct ocpfile_t *file, int ismod, int prescanhint)
void modlist_append_file (struct modlist *modlist, struct ocpfile_t *file, int ismod, int prescanhint, struct ocpfilehandle_t **retain)
{
struct modlistentry entry = {{0}};
const char *childpath = 0;
Expand Down Expand Up @@ -216,7 +216,7 @@ void modlist_append_file (struct modlist *modlist, struct ocpfile_t *file, int i
{
if (prescanhint && (!mdbInfoIsAvailable(entry.mdb_ref)))
{
mdbScan (file, entry.mdb_ref);
mdbScan (file, entry.mdb_ref, retain);
entry.flags |= MODLIST_FLAG_SCANNED;
}
}
Expand Down
2 changes: 1 addition & 1 deletion filesel/modlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void modlist_append(struct modlist *modlist, struct modlistentry *entry);
void modlist_append_dir (struct modlist *modlist, struct ocpdir_t *dir);
void modlist_append_dotdot (struct modlist *modlist, struct ocpdir_t *dir);
void modlist_append_drive (struct modlist *modlist, struct dmDrive *drive);
void modlist_append_file (struct modlist *modlist, struct ocpfile_t *file, int ismod, int prescanhint); /* if file is stored SOLID, trigger a mdb scan if needed */
void modlist_append_file (struct modlist *modlist, struct ocpfile_t *file, int ismod, int prescanhint, struct ocpfilehandle_t **retain); /* if file is stored SOLID, trigger a mdb scan if needed */

void modlist_swap(struct modlist *modlist, unsigned int index1, unsigned int index2);
void modlist_clear(struct modlist *modlist);
Expand Down
57 changes: 38 additions & 19 deletions filesel/pfilesel.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ struct fsReadDir_token_t

int cancel_recursive;
char *parent_displaydir;

struct ocpfilehandle_t *fileretain; /* hack to keep one file open in archives, to ensure they remain open while scanning their content */
};

static void fsReadDir_file (void *_token, struct ocpfile_t *file)
Expand Down Expand Up @@ -172,11 +174,6 @@ static void fsReadDir_file (void *_token, struct ocpfile_t *file)
{
unsigned int mlTop=plScrHeight/2-2;
unsigned int i;
char *oldparent_displaydir;

/* store the callers directory - we might be running recursive */
oldparent_displaydir = token->parent_displaydir;
token->parent_displaydir = 0;

/* draw a box and information to the display... resize of the display will not be gracefull during a directory scan */
displayvoid(mlTop+1, 5, plScrWidth-10);
Expand All @@ -202,13 +199,17 @@ static void fsReadDir_file (void *_token, struct ocpfile_t *file)
displaystr(mlTop+4, plScrWidth-5, 0x04, "\xd9", 1);
}
displaystr (mlTop + 1, 5, 0x09, "Scanning content of the given file. Press space to cancel", plScrWidth - 10);
dirdbGetFullname_malloc (dir->dirdb_ref, &token->parent_displaydir, DIRDB_FULLNAME_ENDSLASH);
displaystr_utf8_overflowleft (mlTop + 3, 5, 0x0a, token->parent_displaydir, plScrWidth - 10);
{ /* do the actual scan */
struct fsReadDir_token_t innertoken = *token;

innertoken.parent_displaydir = 0;
innertoken.fileretain = 0;

{ /* do the actual scan */
ocpdirhandle_pt dh = dir->readflatdir_start (dir, fsReadDir_file, token); /* recycle the same token... */
while (dir->readdir_iterate (dh) && (!token->cancel_recursive))
dirdbGetFullname_malloc (dir->dirdb_ref, &innertoken.parent_displaydir, DIRDB_FULLNAME_ENDSLASH);
displaystr_utf8_overflowleft (mlTop + 3, 5, 0x0a, innertoken.parent_displaydir, plScrWidth - 10);

ocpdirhandle_pt dh = dir->readflatdir_start (dir, fsReadDir_file, &innertoken);
while (dir->readdir_iterate (dh) && (!innertoken.cancel_recursive))
{
if (poll_framelock())
{
Expand All @@ -217,7 +218,7 @@ static void fsReadDir_file (void *_token, struct ocpfile_t *file)
int key = Console.KeyboardGetChar();
if ((key == ' ') || (key == KEY_EXIT))
{
token->cancel_recursive = 1;
innertoken.cancel_recursive = 1;
}
if (key == VIRT_KEY_RESIZE)
{
Expand All @@ -227,11 +228,18 @@ static void fsReadDir_file (void *_token, struct ocpfile_t *file)
}
}
}

free (innertoken.parent_displaydir);
if (innertoken.fileretain)
{
innertoken.fileretain->unref (innertoken.fileretain);
innertoken.fileretain = 0;
}
token->cancel_recursive |= innertoken.cancel_recursive;
dir->readdir_cancel (dh);
}

/* undo the filename displayed */
free (token->parent_displaydir); token->parent_displaydir = oldparent_displaydir;
if (token->parent_displaydir)
{
displaystr_utf8_overflowleft (mlTop + 3, 5, 0x0a, token->parent_displaydir, plScrWidth - 10);
Expand Down Expand Up @@ -284,7 +292,7 @@ static void fsReadDir_file (void *_token, struct ocpfile_t *file)
if (ismod || // always include if file is an actual module
(fsShowAllFiles && (!(token->opt & RD_ISMODONLY)))) // force include if fsShowAllFiles is true, except if RD_ISMODONLY
{
modlist_append_file (token->ml, file, ismod, file->compression >= COMPRESSION_SOLID && (file->compression < COMPRESSION_REMOTE)); /* modlist_append() will do refcount on the file */
modlist_append_file (token->ml, file, ismod, file->compression >= COMPRESSION_SOLID && (file->compression < COMPRESSION_REMOTE), token->fileretain ? 0 : &token->fileretain); /* modlist_append() will do refcount on the file */
}
out:
free (curext);
Expand Down Expand Up @@ -342,6 +350,7 @@ int fsReadDir (struct modlist *ml, struct ocpdir_t *dir, const char *mask, unsig
token.mask = (char *)mask;
#endif
token.opt = opt & ~(RD_SUBSORT);
token.fileretain = 0;

if ((opt & RD_PUTRSUBS) && dir->readflatdir_start)
{
Expand All @@ -355,6 +364,11 @@ int fsReadDir (struct modlist *ml, struct ocpdir_t *dir, const char *mask, unsig
#ifndef FNM_CASEFOLD
free (token.mask);
#endif
if (token.fileretain)
{
token.fileretain->unref (token.fileretain);
token.fileretain = 0;
}
return 0;
}
while (dir->readdir_iterate (dh))
Expand All @@ -377,6 +391,11 @@ int fsReadDir (struct modlist *ml, struct ocpdir_t *dir, const char *mask, unsig
#ifndef FNM_CASEFOLD
free (token.mask);
#endif
if (token.fileretain)
{
token.fileretain->unref (token.fileretain);
token.fileretain = 0;
}

if (opt & RD_SUBSORT)
{
Expand Down Expand Up @@ -520,7 +539,7 @@ static void addfiles_file (void *token, struct ocpfile_t *file)
}
if (fsIsModule(curext))
{
modlist_append_file (playlist, file, 1, 0); /* modlist_append calls file->ref (file); for us */
modlist_append_file (playlist, file, 1, 0, 0); /* modlist_append calls file->ref (file); for us */
}
free (curext);
}
Expand Down Expand Up @@ -3299,7 +3318,7 @@ signed int fsFileSelect(void)
int poll = 1;
if ((m->file && (m->file->compression < COMPRESSION_REMOTE) && (m->flags & MODLIST_FLAG_ISMOD)) && (!mdbInfoIsAvailable(m->mdb_ref)) && (!(m->flags&MODLIST_FLAG_SCANNED)))
{
mdbScan(m->file, m->mdb_ref);
mdbScan(m->file, m->mdb_ref, 0);
m->flags |= MODLIST_FLAG_SCANNED;
}

Expand All @@ -3312,7 +3331,7 @@ signed int fsFileSelect(void)
{
if (!mdbInfoIsAvailable(scanm->mdb_ref))
{
mdbScan(scanm->file, scanm->mdb_ref);
mdbScan(scanm->file, scanm->mdb_ref, 0);
scanm->flags |= MODLIST_FLAG_SCANNED;

if (poll_framelock())
Expand All @@ -3333,7 +3352,7 @@ signed int fsFileSelect(void)
{
if (!mdbInfoIsAvailable(scanm->mdb_ref))
{
mdbScan(scanm->file, scanm->mdb_ref);
mdbScan(scanm->file, scanm->mdb_ref, 0);
scanm->flags |= MODLIST_FLAG_SCANNED;

if (poll_framelock())
Expand Down Expand Up @@ -3470,7 +3489,7 @@ signed int fsFileSelect(void)
mdbEditBuf.modtype.integer.i = mtUnRead;
if (!mdbWriteModuleInfo(m->mdb_ref, &mdbEditBuf))
return -1;
mdbScan(m->file, m->mdb_ref);
mdbScan(m->file, m->mdb_ref, 0);
m->flags |= MODLIST_FLAG_SCANNED;
}
break;
Expand Down Expand Up @@ -3539,7 +3558,7 @@ signed int fsFileSelect(void)
/* We delay mdbScan for remote files until this stage */
if (m && m->file && (m->file->compression >= COMPRESSION_REMOTE) && !(m->flags & MODLIST_FLAG_SCANNED))
{
mdbScan (m->file, m->mdb_ref);
mdbScan (m->file, m->mdb_ref, 0);
m->flags |= MODLIST_FLAG_SCANNED;
}
if (win)
Expand Down
15 changes: 14 additions & 1 deletion medialib/medialib-scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct scanlist_t
int entries;
int size;
int abort;
struct ocpfilehandle_t *retain; /* hack to keep one file open in archives, to ensure they remain open while scanning their content */
};

static void mlScanDraw(const char *title, struct scanlist_t *token)
Expand Down Expand Up @@ -193,7 +194,7 @@ static void mlScan_file (void *_token, struct ocpfile_t *file)
mdbref = mdbGetModuleReference2 (file->dirdb_ref, file->filesize(file));
if (!mdbInfoIsAvailable (mdbref))
{
mdbScan(file, mdbref);
mdbScan(file, mdbref, token->retain ? 0 : &token->retain);
}
dirdbMakeMdbRef(file->dirdb_ref, mdbref);

Expand Down Expand Up @@ -231,6 +232,11 @@ static int mlScan(struct ocpdir_t *dir)
if (!handle)
{
free (token.path);
if (token.retain)
{
token.retain->unref (token.retain);
token.retain = 0;
}
return 0;
}
while (dir->readdir_iterate (handle) && (!token.abort))
Expand All @@ -249,5 +255,12 @@ static int mlScan(struct ocpdir_t *dir)
free (token.files);

free (token.path);

if (token.retain)
{
token.retain->unref (token.retain);
token.retain = 0;
}

return token.abort;
}

0 comments on commit 4d334ac

Please sign in to comment.