From d941c4a02c301ebfb93a622907034fc6b20f17f5 Mon Sep 17 00:00:00 2001 From: dborth Date: Tue, 7 Jul 2009 06:37:22 +0000 Subject: [PATCH] faster smb browsing - added thread to parse entries --- source/ngc/fileop.cpp | 188 ++++++++++++++++++----------- source/ngc/gui/gui.h | 1 + source/ngc/gui/gui_filebrowser.cpp | 3 +- 3 files changed, 120 insertions(+), 72 deletions(-) diff --git a/source/ngc/fileop.cpp b/source/ngc/fileop.cpp index 2c5e067..f6af592 100644 --- a/source/ngc/fileop.cpp +++ b/source/ngc/fileop.cpp @@ -33,6 +33,8 @@ #include "filebrowser.h" #include "preferences.h" +#define THREAD_SLEEP 100 + unsigned char savebuffer[SAVEBUFFERSIZE] ATTRIBUTE_ALIGN(32); static mutex_t bufferLock = LWP_MUTEX_NULL; FILE * file; // file pointer - the only one we should ever use! @@ -47,9 +49,13 @@ bool isMounted[9] = { false, false, false, false, false, false, false, false, fa const DISC_INTERFACE* cardb = &__io_gcsdb; #endif -/**************************************************************************** - * deviceThreading - ***************************************************************************/ +// folder parsing thread +static lwp_t parsethread = LWP_THREAD_NULL; +static DIR_ITER * dirIter = NULL; +static bool parseHalt = true; +bool ParseDirEntries(); + +// device thread static lwp_t devicethread = LWP_THREAD_NULL; static bool deviceHalt = true; @@ -82,7 +88,7 @@ HaltDeviceThread() // wait for thread to finish while(!LWP_ThreadIsSuspended(devicethread)) - usleep(100); + usleep(THREAD_SLEEP); } /**************************************************************************** @@ -100,8 +106,8 @@ devicecallback (void *arg) { if(deviceHalt) LWP_SuspendThread(devicethread); - usleep(100); - devsleep -= 100; + usleep(THREAD_SLEEP); + devsleep -= THREAD_SLEEP; } while (1) @@ -151,13 +157,25 @@ devicecallback (void *arg) { if(deviceHalt) LWP_SuspendThread(devicethread); - usleep(100); - devsleep -= 100; + usleep(THREAD_SLEEP); + devsleep -= THREAD_SLEEP; } } return NULL; } +static void * +parsecallback (void *arg) +{ + while(1) + { + while(ParseDirEntries()) + usleep(THREAD_SLEEP); + LWP_SuspendThread(parsethread); + } + return NULL; +} + /**************************************************************************** * InitDeviceThread * @@ -168,6 +186,7 @@ void InitDeviceThread() { LWP_CreateThread (&devicethread, devicecallback, NULL, NULL, 0, 40); + LWP_CreateThread (&parsethread, parsecallback, NULL, NULL, 0, 80); } /**************************************************************************** @@ -314,32 +333,107 @@ bool ChangeInterface(int method, bool silent) return mounted; } + +bool ParseDirEntries() +{ + if(!dirIter) + return false; + + char filename[MAXPATHLEN]; + struct stat filestat; + + int i, res; + + for(i=0; i < 20; i++) + { + res = dirnext(dirIter,filename,&filestat); + + if(res != 0) + break; + + if(strcmp(filename,".") == 0) + { + i--; + continue; + } + + BROWSERENTRY * newBrowserList = (BROWSERENTRY *)realloc(browserList, (browser.numEntries+i+1) * sizeof(BROWSERENTRY)); + + if(!newBrowserList) // failed to allocate required memory + { + ResetBrowser(); + ErrorPrompt("Out of memory: too many files!"); + break; + } + else + { + browserList = newBrowserList; + } + + memset(&(browserList[browser.numEntries+i]), 0, sizeof(BROWSERENTRY)); // clear the new entry + + strncpy(browserList[browser.numEntries+i].filename, filename, MAXJOLIET); + browserList[browser.numEntries+i].length = filestat.st_size; + browserList[browser.numEntries+i].mtime = filestat.st_mtime; + browserList[browser.numEntries+i].isdir = (filestat.st_mode & _IFDIR) == 0 ? 0 : 1; // flag this as a dir + + if(browserList[browser.numEntries+i].isdir) + { + if(strcmp(filename, "..") == 0) + sprintf(browserList[browser.numEntries+i].displayname, "Up One Level"); + else + strncpy(browserList[browser.numEntries+i].displayname, browserList[browser.numEntries+i].filename, MAXJOLIET); + } + else + { + StripExt(browserList[browser.numEntries+i].displayname, browserList[browser.numEntries+i].filename); // hide file extension + } + } + + // Sort the file list + if(i >= 0) + { + browser.numEntries += i; + qsort(browserList, browser.numEntries, sizeof(BROWSERENTRY), FileSortCallback); + } + + if(res != 0 || parseHalt) + { + dirclose(dirIter); // close directory + dirIter = NULL; + return false; // no more entries + } + return true; // more entries +} + /*************************************************************************** * Browse subdirectories **************************************************************************/ int ParseDirectory(int method) { - DIR_ITER *dir = NULL; char fulldir[MAXPATHLEN]; - char filename[MAXPATHLEN]; - struct stat filestat; char msg[128]; int retry = 1; bool mounted = false; + // halt parsing + parseHalt = true; + + while(!LWP_ThreadIsSuspended(parsethread)) + usleep(THREAD_SLEEP); + // reset browser + dirIter = NULL; ResetBrowser(); - ShowAction("Loading..."); - // open the directory - while(dir == NULL && retry == 1) + while(dirIter == NULL && retry == 1) { mounted = ChangeInterface(method, NOTSILENT); sprintf(fulldir, "%s%s", rootdir, browser.dir); // add device to path - if(mounted) dir = diropen(fulldir); - if(dir == NULL) + if(mounted) dirIter = diropen(fulldir); + if(dirIter == NULL) { unmountRequired[method] = true; sprintf(msg, "Error opening %s", fulldir); @@ -348,14 +442,14 @@ ParseDirectory(int method) } // if we can't open the dir, try opening the root dir - if (dir == NULL) + if (dirIter == NULL) { if(ChangeInterface(method, SILENT)) { sprintf(browser.dir,"/"); sprintf(fulldir, "%s%s", rootdir, browser.dir); - dir = diropen(fulldir); - if (dir == NULL) + dirIter = diropen(fulldir); + if (dirIter == NULL) { sprintf(msg, "Error opening %s", rootdir); ErrorPrompt(msg); @@ -364,59 +458,11 @@ ParseDirectory(int method) } } - // index files/folders - int entryNum = 0; + parseHalt = false; + ParseDirEntries(); // index first 50 entries + LWP_ResumeThread(parsethread); // index remaining entries - while(dirnext(dir,filename,&filestat) == 0) - { - if(strcmp(filename,".") != 0) - { - BROWSERENTRY * newBrowserList = (BROWSERENTRY *)realloc(browserList, (entryNum+1) * sizeof(BROWSERENTRY)); - - if(!newBrowserList) // failed to allocate required memory - { - ResetBrowser(); - ErrorPrompt("Out of memory: too many files!"); - entryNum = -1; - break; - } - else - { - browserList = newBrowserList; - } - - memset(&(browserList[entryNum]), 0, sizeof(BROWSERENTRY)); // clear the new entry - - strncpy(browserList[entryNum].filename, filename, MAXJOLIET); - browserList[entryNum].length = filestat.st_size; - browserList[entryNum].mtime = filestat.st_mtime; - browserList[entryNum].isdir = (filestat.st_mode & _IFDIR) == 0 ? 0 : 1; // flag this as a dir - - if(browserList[entryNum].isdir) - { - if(strcmp(filename, "..") == 0) - sprintf(browserList[entryNum].displayname, "Up One Level"); - else - strncpy(browserList[entryNum].displayname, browserList[entryNum].filename, MAXJOLIET); - } - else - { - StripExt(browserList[entryNum].displayname, browserList[entryNum].filename); // hide file extension - } - entryNum++; - } - } - - // close directory - dirclose(dir); - - // Sort the file list - qsort(browserList, entryNum, sizeof(BROWSERENTRY), FileSortCallback); - - CancelAction(); - - browser.numEntries = entryNum; - return entryNum; + return browser.numEntries; } /**************************************************************************** diff --git a/source/ngc/gui/gui.h b/source/ngc/gui/gui.h index 89d5ca1..46439e3 100644 --- a/source/ngc/gui/gui.h +++ b/source/ngc/gui/gui.h @@ -908,6 +908,7 @@ class GuiFileBrowser : public GuiElement GuiButton * fileList[FILE_PAGESIZE]; protected: int selectedItem; + int numEntries; bool listChanged; GuiText * fileListText[FILE_PAGESIZE]; diff --git a/source/ngc/gui/gui_filebrowser.cpp b/source/ngc/gui/gui_filebrowser.cpp index 44c08c9..1af4aa2 100644 --- a/source/ngc/gui/gui_filebrowser.cpp +++ b/source/ngc/gui/gui_filebrowser.cpp @@ -18,6 +18,7 @@ GuiFileBrowser::GuiFileBrowser(int w, int h) { width = w; height = h; + numEntries = 0; selectedItem = 0; selectable = true; listChanged = true; // trigger an initial list update @@ -329,7 +330,7 @@ void GuiFileBrowser::Update(GuiTrigger * t) for(int i=0; i