Added dircache support to playlist. Now playlist filename pointers are

automatically accuired from dircache. WPS UI response with dircache
enabled should be instant.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7931 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Miika Pekkarinen 2005-11-17 19:31:29 +00:00
parent bc8a4e4b8c
commit 735f453730
8 changed files with 336 additions and 75 deletions

View file

@ -340,6 +340,7 @@ int ft_enter(struct tree_context* c)
int start_index=0;
lcd_stop_scroll();
gui_syncsplash(0, true, str(LANG_WAIT));
switch ( file->attr & TREE_ATTR_MASK ) {
case TREE_ATTR_M3U:
if (bookmark_autoload(buf))

View file

@ -3431,3 +3431,9 @@ eng: "Clear current presets?"
voice: "Clear current presets?"
new:
id: LANG_WAIT
desc: general please wait splash
eng: "=== Please Wait ==="
voice: "Please wait"
new:

View file

@ -165,9 +165,6 @@ static volatile int buf_widx;
/* Step count to the next unbuffered track. */
static int last_peek_offset;
/* Index of the last buffered track. */
static int last_index;
/* Track information (count in file buffer, read/write indexes for
track ring structure. */
int track_count;
@ -589,7 +586,7 @@ static bool rebuffer_and_seek(int newpos)
while (cur_ti->available == 0 && cur_ti->filerem > 0) {
yield();
if (ci.stop_codec || ci.reload_codec)
if (ci.stop_codec || ci.reload_codec || !queue_empty(&audio_queue))
return false;
}
@ -1048,8 +1045,6 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
if (tracks[track_widx].filesize != 0)
return false;
last_index = playlist_get_display_index();
peek_again:
/* Get track name from current playlist read position. */
logf("Buffering track:%d/%d", track_widx, track_ridx);
@ -1456,7 +1451,6 @@ void audio_update_trackinfo(void)
} else {
pcmbuf_add_event(codec_track_changed);
}
last_index = playlist_get_display_index();
}
static void audio_stop_playback(void)
@ -1519,8 +1513,8 @@ bool codec_request_next_track_callback(void)
{
if (current_codec == CODEC_IDX_VOICE) {
voice_remaining = 0;
/* Terminate the codec if they are messages waiting on the queue or
core has been requested the codec to be terminated. */
/* Terminate the codec if there are messages waiting on the queue or
the core has been requested the codec to be terminated. */
return !ci_voice.stop_codec && queue_empty(&voice_codec_queue);
}
@ -1531,12 +1525,7 @@ bool codec_request_next_track_callback(void)
/* Advance to next track. */
if (ci.reload_codec && new_track > 0) {
if (!playlist_check(new_track)) {
ci.reload_codec = false;
return false;
}
last_peek_offset--;
playlist_next(new_track);
if (++track_ridx == MAX_TRACK)
track_ridx = 0;
@ -1549,7 +1538,6 @@ bool codec_request_next_track_callback(void)
if (tracks[track_ridx].filesize == 0) {
logf("Loading from disk...");
new_track = 0;
last_index = -1;
queue_post(&audio_queue, AUDIO_PLAY, 0);
return false;
}
@ -1557,12 +1545,7 @@ bool codec_request_next_track_callback(void)
/* Advance to previous track. */
else if (ci.reload_codec && new_track < 0) {
if (!playlist_check(new_track)) {
ci.reload_codec = false;
return false;
}
last_peek_offset++;
playlist_next(new_track);
if (--track_ridx < 0)
track_ridx = MAX_TRACK-1;
if (tracks[track_ridx].filesize == 0 ||
@ -1570,7 +1553,6 @@ bool codec_request_next_track_callback(void)
/*+ (off_t)tracks[track_ridx].codecsize*/ > filebuflen) {
logf("Loading from disk...");
new_track = 0;
last_index = -1;
queue_post(&audio_queue, AUDIO_PLAY, 0);
return false;
}
@ -1597,7 +1579,6 @@ bool codec_request_next_track_callback(void)
logf("No more tracks [2]");
ci.stop_codec = true;
new_track = 0;
last_index = -1;
queue_post(&audio_queue, AUDIO_PLAY, 0);
return false;
}
@ -1652,7 +1633,6 @@ static void initiate_track_change(int peek_index)
/* Detect if disk is spinning.. */
if (filling) {
playlist_next(peek_index);
queue_post(&audio_queue, AUDIO_PLAY, 0);
} else {
new_track = peek_index;
@ -1677,35 +1657,49 @@ static void initiate_dir_change(int direction)
void audio_thread(void)
{
struct event ev;
int last_tick = 0;
bool play_pending = false;
while (1) {
yield_codecs();
audio_check_buffer();
if (!play_pending)
{
yield_codecs();
audio_check_buffer();
}
else
{
// ata_spin();
sleep(1);
}
queue_wait_w_tmo(&audio_queue, &ev, 0);
if (ev.id == SYS_TIMEOUT && play_pending)
{
ev.id = AUDIO_PLAY;
ev.data = 0;
}
switch (ev.id) {
case AUDIO_PLAY:
/* Refuse to start playback if we are already playing
the requested track. This is needed because when skipping
tracks fast, AUDIO_PLAY commands will get queued with the
the same track and playback will stutter. */
if (last_index == playlist_get_display_index() && playing
&& pcm_is_playing()) {
logf("already playing req. track");
/* Don't start playing immediately if user is skipping tracks
* fast to prevent UI lag. */
track_count = 0;
last_peek_offset = 0;
if (current_tick - last_tick < HZ/2)
{
play_pending = true;
break ;
}
play_pending = false;
/* Do not start crossfading if audio is paused. */
if (paused) {
audio_stop_playback();
paused = false;
}
if (paused)
pcmbuf_play_stop();
#ifdef CONFIG_TUNER
/* check if radio is playing */
if(radio_get_status() != FMRADIO_OFF){
radio_stop();
if (radio_get_status() != FMRADIO_OFF) {
radio_stop();
}
#endif
@ -1751,15 +1745,13 @@ void audio_thread(void)
case AUDIO_NEXT:
logf("audio_next");
if (global_settings.beep)
pcmbuf_beep(5000, 100, 2500*global_settings.beep);
last_tick = current_tick;
initiate_track_change(1);
break ;
case AUDIO_PREV:
logf("audio_prev");
if (global_settings.beep)
pcmbuf_beep(5000, 100, 2500*global_settings.beep);
last_tick = current_tick;
initiate_track_change(-1);
break;
@ -1793,7 +1785,7 @@ void audio_thread(void)
// audio_change_track();
break ;
#ifndef SIMULATOR
#ifndef SIMULATOR
case SYS_USB_CONNECTED:
logf("USB: Audio core");
audio_stop_playback();
@ -1973,12 +1965,28 @@ void voice_init(void)
struct mp3entry* audio_current_track(void)
{
// logf("audio_current_track");
const char *filename;
const char *p;
static struct mp3entry temp_id3;
if (track_count > 0 && cur_ti->taginfo_ready)
return (struct mp3entry *)&cur_ti->id3;
else
return NULL;
else {
filename = playlist_peek(0);
if (!filename)
filename = "No file!";
p = strrchr(filename, '/');
if (!p)
p = filename;
else
p++;
memset(&temp_id3, 0, sizeof(struct mp3entry));
strncpy(temp_id3.path, p, sizeof(temp_id3.path)-1);
temp_id3.title = &temp_id3.path[0];
return &temp_id3;
}
}
struct mp3entry* audio_next_track(void)
@ -1994,16 +2002,12 @@ struct mp3entry* audio_next_track(void)
if (!tracks[next_idx].taginfo_ready)
return NULL;
//logf("audio_next_track");
return &tracks[next_idx].id3;
}
bool audio_has_changed_track(void)
{
if (track_changed && track_count > 0 && playing) {
if (!cur_ti->taginfo_ready)
return false;
if (track_changed) {
track_changed = false;
return true;
}
@ -2014,7 +2018,6 @@ bool audio_has_changed_track(void)
void audio_play(int offset)
{
logf("audio_play");
last_index = -1;
queue_post(&audio_queue, AUDIO_PLAY, (void *)offset);
}
@ -2043,11 +2046,37 @@ void audio_resume(void)
void audio_next(void)
{
/* Prevent UI lag and update the WPS immediately. */
if (global_settings.beep)
pcmbuf_beep(5000, 100, 2500*global_settings.beep);
if (!playlist_check(1))
return ;
playlist_next(1);
track_changed = true;
/* Force WPS to update even if audio thread is blocked spinning. */
if (mutex_bufferfill.locked)
cur_ti->taginfo_ready = false;
queue_post(&audio_queue, AUDIO_NEXT, 0);
}
void audio_prev(void)
{
/* Prevent UI lag and update the WPS immediately. */
if (global_settings.beep)
pcmbuf_beep(5000, 100, 2500*global_settings.beep);
if (!playlist_check(-1))
return ;
playlist_next(-1);
track_changed = true;
/* Force WPS to update even if audio thread is blocked spinning. */
if (mutex_bufferfill.locked)
cur_ti->taginfo_ready = false;
queue_post(&audio_queue, AUDIO_PREV, 0);
}

View file

@ -86,6 +86,9 @@
#include "button.h"
#include "filetree.h"
#include "abrepeat.h"
#include "dircache.h"
#include "thread.h"
#include "usb.h"
#ifdef HAVE_LCD_BITMAP
#include "icons.h"
#include "widgets.h"
@ -162,7 +165,7 @@ static int get_next_index(const struct playlist_info* playlist, int steps,
static void find_and_set_playlist_index(struct playlist_info* playlist,
unsigned int seek);
static int compare(const void* p1, const void* p2);
static int get_filename(struct playlist_info* playlist, int seek,
static int get_filename(struct playlist_info* playlist, int index, int seek,
bool control_file, char *buf, int buf_length);
static int get_next_directory(char *dir);
static int get_next_dir(char *dir, bool is_forward, bool recursion);
@ -175,6 +178,14 @@ static void display_buffer_full(void);
static int flush_pending_control(struct playlist_info* playlist);
static int rotate_index(const struct playlist_info* playlist, int index);
#ifdef HAVE_DIRCACHE
#define PLAYLIST_LOAD_POINTERS 1
static struct event_queue playlist_queue;
static long playlist_stack[(DEFAULT_STACK_SIZE + 0x400)/sizeof(long)];
static const char playlist_thread_name[] = "playlist cachectrl";
#endif
/*
* remove any files and indices associated with the playlist
*/
@ -394,11 +405,15 @@ static int add_indices_to_playlist(struct playlist_info* playlist,
{
/* Store a new entry */
playlist->indices[ playlist->amount ] = i+count;
playlist->amount++;
#ifdef HAVE_DIRCACHE
if (playlist->filenames)
playlist->filenames[ playlist->amount ] = NULL;
#endif
if ( playlist->amount >= playlist->max_playlist_size ) {
display_buffer_full();
return -1;
}
playlist->amount++;
}
}
}
@ -406,6 +421,10 @@ static int add_indices_to_playlist(struct playlist_info* playlist,
i+= count;
}
#ifdef HAVE_DIRCACHE
queue_post(&playlist_queue, PLAYLIST_LOAD_POINTERS, 0);
#endif
return 0;
}
@ -499,8 +518,14 @@ static int add_track_to_playlist(struct playlist_info* playlist,
/* shift indices so that track can be added */
for (i=playlist->amount; i>insert_position; i--)
{
playlist->indices[i] = playlist->indices[i-1];
#ifdef HAVE_DIRCACHE
if (playlist->filenames)
playlist->filenames[i] = playlist->filenames[i-1];
#endif
}
/* update stored indices if needed */
if (playlist->amount > 0 && insert_position <= playlist->index)
playlist->index++;
@ -554,6 +579,12 @@ static int add_track_to_playlist(struct playlist_info* playlist,
playlist->indices[insert_position] = flags | seek_pos;
#ifdef HAVE_DIRCACHE
if (playlist->filenames)
playlist->filenames[insert_position] = NULL;
queue_post(&playlist_queue, PLAYLIST_LOAD_POINTERS, 0);
#endif
playlist->amount++;
playlist->num_inserted_tracks++;
@ -693,7 +724,13 @@ static int remove_track_from_playlist(struct playlist_info* playlist,
/* shift indices now that track has been removed */
for (i=position; i<playlist->amount; i++)
{
playlist->indices[i] = playlist->indices[i+1];
#ifdef HAVE_DIRCACHE
if (playlist->filenames)
playlist->filenames[i] = playlist->filenames[i+1];
#endif
}
playlist->amount--;
@ -780,6 +817,14 @@ static int randomise_playlist(struct playlist_info* playlist,
store = playlist->indices[candidate];
playlist->indices[candidate] = playlist->indices[count];
playlist->indices[count] = store;
#ifdef HAVE_DIRCACHE
if (playlist->filenames)
{
store = (int)playlist->filenames[candidate];
playlist->filenames[candidate] = playlist->filenames[count];
playlist->filenames[count] = (struct dircache_entry *)store;
}
#endif
}
if (start_current)
@ -817,6 +862,13 @@ static int sort_playlist(struct playlist_info* playlist, bool start_current,
qsort(playlist->indices, playlist->amount,
sizeof(playlist->indices[0]), compare);
#ifdef HAVE_DIRCACHE
/** We need to re-check the song names from disk because qsort can't
* sort two arrays at once :/
* FIXME: Please implement a better way to do this. */
queue_post(&playlist_queue, PLAYLIST_LOAD_POINTERS, 0);
#endif
if (start_current)
find_and_set_playlist_index(playlist, current);
@ -1040,10 +1092,88 @@ static int compare(const void* p1, const void* p2)
return *e1 - *e2;
}
#ifdef HAVE_DIRCACHE
/**
* Thread to update filename pointers to dircache on background
* without affecting playlist load up performance.
*/
static void playlist_thread(void)
{
struct event ev;
bool dirty_pointers = false;
static char tmp[MAX_PATH+1];
struct playlist_info *playlist;
int index;
int seek;
bool control_file;
while (1)
{
queue_wait_w_tmo(&playlist_queue, &ev, HZ*5);
switch (ev.id)
{
case PLAYLIST_LOAD_POINTERS:
dirty_pointers = true;
break ;
/* Start the background scanning after 5s. */
case SYS_TIMEOUT:
if (!dirty_pointers)
break ;
playlist = &current_playlist;
if (!dircache_is_enabled() || !playlist->filenames
|| playlist->amount <= 0)
break ;
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
cpu_boost(true);
#endif
for (index = 0; index < playlist->amount
&& queue_empty(&playlist_queue); index++)
{
/* Process only pointers that are not already loaded. */
if (playlist->filenames[index])
continue ;
control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK;
seek = playlist->indices[index] & PLAYLIST_SEEK_MASK;
/* Load the filename from playlist file. */
if (get_filename(playlist, index, seek, control_file, tmp,
sizeof(tmp)) < 0)
break ;
/* Set the dircache entry pointer. */
playlist->filenames[index] = dircache_get_entry_ptr(tmp);
/* And be on background so user doesn't notice any delays. */
yield();
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
cpu_boost(false);
#endif
dirty_pointers = false;
break ;
#ifndef SIMULATOR
case SYS_USB_CONNECTED:
usb_acknowledge(SYS_USB_CONNECTED_ACK);
usb_wait_for_disconnect(&playlist_queue);
break ;
#endif
}
}
}
#endif
/*
* gets pathname for track at seek index
*/
static int get_filename(struct playlist_info* playlist, int seek,
static int get_filename(struct playlist_info* playlist, int index, int seek,
bool control_file, char *buf, int buf_length)
{
int fd;
@ -1054,13 +1184,26 @@ static int get_filename(struct playlist_info* playlist, int seek,
if (buf_length > MAX_PATH+1)
buf_length = MAX_PATH+1;
if (playlist->in_ram && !control_file)
#ifdef HAVE_DIRCACHE
if (dircache_is_enabled() && playlist->filenames)
{
if (playlist->filenames[index] != NULL)
{
dircache_copy_path(playlist->filenames[index], tmp_buf, sizeof(tmp_buf)-1);
max = strlen(tmp_buf) + 1;
}
}
#else
(void)index;
#endif
if (playlist->in_ram && !control_file && max < 0)
{
strncpy(tmp_buf, &playlist->buffer[seek], sizeof(tmp_buf));
tmp_buf[MAX_PATH] = '\0';
max = strlen(tmp_buf) + 1;
}
else
else if (max < 0)
{
if (control_file)
fd = playlist->control_fd;
@ -1482,6 +1625,16 @@ void playlist_init(void)
playlist->buffer = buffer_alloc(playlist->buffer_size);
mutex_init(&playlist->control_mutex);
empty_playlist(playlist, true);
#ifdef HAVE_DIRCACHE
playlist->filenames = buffer_alloc(
playlist->max_playlist_size * sizeof(int));
memset(playlist->filenames, 0,
playlist->max_playlist_size * sizeof(int));
create_thread(playlist_thread, playlist_stack, sizeof(playlist_stack),
playlist_thread_name);
queue_init(&playlist_queue);
#endif
}
/*
@ -1906,8 +2059,9 @@ int playlist_add(const char *filename)
return -1;
}
playlist->indices[playlist->amount++] = playlist->buffer_end_pos;
playlist->indices[playlist->amount] = playlist->buffer_end_pos;
playlist->amount++;
strcpy(&playlist->buffer[playlist->buffer_end_pos], filename);
playlist->buffer_end_pos += len;
playlist->buffer[playlist->buffer_end_pos++] = '\0';
@ -1991,7 +2145,7 @@ char* playlist_peek(int steps)
control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK;
seek = playlist->indices[index] & PLAYLIST_SEEK_MASK;
if (get_filename(playlist, seek, control_file, now_playing,
if (get_filename(playlist, index, seek, control_file, now_playing,
MAX_PATH+1) < 0)
return NULL;
@ -2003,11 +2157,21 @@ char* playlist_peek(int steps)
(workaround for buggy playlist creation tools) */
while (temp_ptr)
{
fd = open(temp_ptr, O_RDONLY);
if (fd >= 0)
#ifdef HAVE_DIRCACHE
if (dircache_is_enabled())
{
close(fd);
break;
if (dircache_get_entry_ptr(temp_ptr))
break;
}
else
#endif
{
fd = open(temp_ptr, O_RDONLY);
if (fd >= 0)
{
close(fd);
break;
}
}
temp_ptr = strchr(temp_ptr+1, '/');
@ -2278,16 +2442,26 @@ int playlist_create_ex(struct playlist_info* playlist,
{
int num_indices = index_buffer_size / sizeof(int);
#ifdef HAVE_DIRCACHE
num_indices /= 2;
#endif
if (num_indices > global_settings.max_files_in_playlist)
num_indices = global_settings.max_files_in_playlist;
playlist->max_playlist_size = num_indices;
playlist->indices = index_buffer;
#ifdef HAVE_DIRCACHE
playlist->filenames = (const struct dircache_entry **)
&playlist->indices[num_indices];
#endif
}
else
{
playlist->max_playlist_size = current_playlist.max_playlist_size;
playlist->indices = current_playlist.indices;
#ifdef HAVE_DIRCACHE
playlist->filenames = current_playlist.filenames;
#endif
}
playlist->buffer_size = 0;
@ -2336,9 +2510,15 @@ int playlist_set_current(struct playlist_info* playlist)
current_playlist.dirlen = playlist->dirlen;
if (playlist->indices && playlist->indices != current_playlist.indices)
{
memcpy(current_playlist.indices, playlist->indices,
playlist->max_playlist_size*sizeof(int));
playlist->max_playlist_size*sizeof(int));
#ifdef HAVE_DIRCACHE
memcpy(current_playlist.filenames, playlist->filenames,
playlist->max_playlist_size*sizeof(int));
#endif
}
current_playlist.first_index = playlist->first_index;
current_playlist.amount = playlist->amount;
current_playlist.last_insert_pos = playlist->last_insert_pos;
@ -2620,7 +2800,7 @@ int playlist_move(struct playlist_info* playlist, int index, int new_index)
queue = playlist->indices[index] & PLAYLIST_QUEUE_MASK;
seek = playlist->indices[index] & PLAYLIST_SEEK_MASK;
if (get_filename(playlist, seek, control_file, filename,
if (get_filename(playlist, index, seek, control_file, filename,
sizeof(filename)) < 0)
return -1;
@ -2812,7 +2992,7 @@ int playlist_get_track_info(struct playlist_info* playlist, int index,
control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK;
seek = playlist->indices[index] & PLAYLIST_SEEK_MASK;
if (get_filename(playlist, seek, control_file, info->filename,
if (get_filename(playlist, index, seek, control_file, info->filename,
sizeof(info->filename)) < 0)
return -1;
@ -2883,7 +3063,7 @@ int playlist_save(struct playlist_info* playlist, char *filename)
/* Don't save queued files */
if (!queue)
{
if (get_filename(playlist, seek, control_file, tmp_buf,
if (get_filename(playlist, index, seek, control_file, tmp_buf,
MAX_PATH+1) < 0)
{
result = -1;

View file

@ -36,7 +36,8 @@ struct playlist_info
int control_fd; /* descriptor of the open control file */
bool control_created; /* has control file been created? */
int dirlen; /* Length of the path to the playlist file */
unsigned long *indices; /* array of indices */
unsigned long *indices; /* array of indices */
const struct dircache_entry **filenames; /* Entries from dircache */
int max_playlist_size; /* Max number of files in playlist. Mirror of
global_settings.max_files_in_playlist */
bool in_ram; /* playlist stored in ram (dirplay) */

View file

@ -597,6 +597,7 @@ long wps_show(void)
#endif
#endif
left_lastclick = current_tick;
update_track = true;
#ifdef AB_REPEAT_ENABLE
/* if we're in A/B repeat mode and the current position
@ -604,7 +605,6 @@ long wps_show(void)
if ( ab_repeat_mode_enabled() && ab_after_A_marker(id3->elapsed) )
{
ab_jump_to_A_marker();
update_track = true;
break;
}
/* ...otherwise, do it normally */
@ -655,6 +655,7 @@ long wps_show(void)
#endif
#endif
right_lastclick = current_tick;
update_track = true;
#ifdef AB_REPEAT_ENABLE
/* if we're in A/B repeat mode and the current position is
@ -662,7 +663,6 @@ long wps_show(void)
if ( ab_repeat_mode_enabled() && ab_before_A_marker(id3->elapsed) )
{
ab_jump_to_A_marker();
update_track = true;
break;
}
/* ...otherwise, do it normally */

View file

@ -77,6 +77,7 @@ static struct dircache_entry* allocate_entry(void)
dircache_size += sizeof(struct dircache_entry);
next_entry->name_len = 0;
next_entry->d_name = NULL;
next_entry->up = NULL;
next_entry->down = NULL;
next_entry->next = NULL;
@ -88,6 +89,7 @@ static struct dircache_entry* dircache_gen_next(struct dircache_entry *ce)
struct dircache_entry *next_entry;
next_entry = allocate_entry();
next_entry->up = ce->up;
ce->next = next_entry;
return next_entry;
@ -98,6 +100,7 @@ static struct dircache_entry* dircache_gen_down(struct dircache_entry *ce)
struct dircache_entry *next_entry;
next_entry = allocate_entry();
next_entry->up = ce;
ce->down = next_entry;
return next_entry;
@ -176,6 +179,7 @@ static int dircache_travel(struct fat_dir *dir, struct dircache_entry *ce)
int depth = 0;
int result;
memset(ce, 0, sizeof(struct dircache_entry));
dir_recursion[0].dir = dir;
dir_recursion[0].ce = ce;
@ -517,6 +521,43 @@ void dircache_disable(void)
logf("Cache released");
}
const struct dircache_entry *dircache_get_entry_ptr(const char *filename)
{
if (!dircache_initialized || filename == NULL)
return NULL;
return dircache_get_entry(filename, false, false);
}
void dircache_copy_path(const struct dircache_entry *entry, char *buf, int size)
{
const struct dircache_entry *down[MAX_SCAN_DEPTH];
int depth = 0;
if (size <= 0)
return ;
buf[0] = '\0';
if (entry == NULL)
return ;
do {
down[depth] = entry;
entry = entry->up;
depth++;
} while (entry != NULL && depth < MAX_SCAN_DEPTH);
while (--depth >= 0)
{
snprintf(buf, size, "/%s", down[depth]->d_name);
buf += down[depth]->name_len; /* '/' + d_name */
size -= down[depth]->name_len;
if (size <= 0)
break ;
}
}
/* --- Directory cache live updating functions --- */
static struct dircache_entry* dircache_new_entry(const char *path, int attribute)
{

View file

@ -47,6 +47,7 @@ struct dircache_maindata {
/* Exported structures. */
struct dircache_entry {
struct dircache_entry *next;
struct dircache_entry *up;
struct dircache_entry *down;
int attribute;
long size;
@ -71,6 +72,8 @@ int dircache_build(int last_size);
bool dircache_is_enabled(void);
int dircache_get_cache_size(void);
void dircache_disable(void);
const struct dircache_entry *dircache_get_entry_ptr(const char *filename);
void dircache_copy_path(const struct dircache_entry *entry, char *buf, int size);
void dircache_bind(int fd, const char *path);
void dircache_update_filesize(int fd, long newsize);