More safety checks to dircache to block updates until cache is ready.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9339 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Miika Pekkarinen 2006-03-29 09:38:45 +00:00
parent 029ff80235
commit 6ce466ea2c
2 changed files with 51 additions and 6 deletions

View file

@ -52,6 +52,7 @@ static struct dircache_entry *fd_bindings[MAX_OPEN_FILES];
static struct dircache_entry *dircache_root;
static bool dircache_initialized = false;
static bool dircache_initializing = false;
static bool thread_enabled = false;
static unsigned long allocated_size = DIRCACHE_LIMIT;
static unsigned long dircache_size = 0;
@ -64,6 +65,9 @@ static struct event_queue dircache_queue;
static long dircache_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)];
static const char dircache_thread_name[] = "dircache";
static struct fdbind_queue fdbind_cache[MAX_PENDING_BINDINGS];
static int fdbind_idx = 0;
/* --- Internal cache structure control functions --- */
/**
@ -446,12 +450,15 @@ static int dircache_do_rebuild(void)
{
struct fat_dir dir;
unsigned int start_tick;
int i;
/* Measure how long it takes build the cache. */
start_tick = current_tick;
dircache_initializing = true;
if ( fat_opendir(IF_MV2(volume,) &dir, 0, NULL) < 0 ) {
logf("Failed opening root dir");
dircache_initializing = false;
return -3;
}
@ -472,14 +479,22 @@ static int dircache_do_rebuild(void)
logf("dircache_travel failed");
cpu_boost(false);
dircache_size = 0;
dircache_initializing = false;
return -2;
}
cpu_boost(false);
logf("Done, %d KiB used", dircache_size / 1024);
dircache_initialized = true;
dircache_initializing = false;
cache_build_ticks = current_tick - start_tick;
/* Initialized fd bindings. */
memset(fd_bindings, 0, sizeof(fd_bindings));
for (i = 0; i < fdbind_idx; i++)
dircache_bind(fdbind_cache[i].fd, fdbind_cache[i].path);
if (thread_enabled)
{
if (allocated_size - dircache_size < DIRCACHE_RESERVE)
@ -710,6 +725,18 @@ void dircache_copy_path(const struct dircache_entry *entry, char *buf, int size)
}
/* --- Directory cache live updating functions --- */
static int block_until_ready(void)
{
/* Block until dircache has been built. */
while (!dircache_initialized && dircache_initializing)
sleep(1);
if (!dircache_initialized)
return -1;
return 0;
}
static struct dircache_entry* dircache_new_entry(const char *path, int attribute)
{
struct dircache_entry *entry;
@ -783,6 +810,18 @@ void dircache_bind(int fd, const char *path)
{
struct dircache_entry *entry;
/* Queue requests until dircache has been built. */
if (!dircache_initialized && dircache_initializing)
{
if (fdbind_idx >= MAX_PENDING_BINDINGS)
return ;
strncpy(fdbind_cache[fdbind_idx].path, path,
sizeof(fdbind_cache[fdbind_idx].path)-1);
fdbind_cache[fdbind_idx].fd = fd;
fdbind_idx++;
return ;
}
if (!dircache_initialized)
return ;
@ -816,7 +855,7 @@ void dircache_update_filesize(int fd, long newsize, long startcluster)
void dircache_mkdir(const char *path)
{ /* Test ok. */
if (!dircache_initialized)
if (block_until_ready())
return ;
logf("mkdir: %s", path);
@ -827,7 +866,7 @@ void dircache_rmdir(const char *path)
{ /* Test ok. */
struct dircache_entry *entry;
if (!dircache_initialized)
if (block_until_ready())
return ;
logf("rmdir: %s", path);
@ -848,7 +887,7 @@ void dircache_remove(const char *name)
{ /* Test ok. */
struct dircache_entry *entry;
if (!dircache_initialized)
if (block_until_ready())
return ;
logf("remove: %s", name);
@ -872,7 +911,7 @@ void dircache_rename(const char *oldpath, const char *newpath)
char absolute_path[MAX_PATH];
char *p;
if (!dircache_initialized)
if (block_until_ready())
return ;
logf("rename: %s->%s", oldpath, newpath);
@ -927,9 +966,9 @@ void dircache_add_file(const char *path, long startcluster)
{
struct dircache_entry *entry;
if (!dircache_initialized)
if (block_until_ready())
return ;
logf("add file: %s", path);
entry = dircache_new_entry(path, 0);
if (entry == NULL)

View file

@ -46,6 +46,12 @@ struct dircache_maindata {
struct dircache_entry *root_entry;
};
#define MAX_PENDING_BINDINGS 2
struct fdbind_queue {
char path[MAX_PATH];
int fd;
};
/* Exported structures. */
struct dircache_entry {
struct dircache_entry *next;