[stat-cache] Provide blocking cached stat
This commit is contained in:
parent
38ec6b3c2d
commit
48aac3ab07
|
@ -93,6 +93,9 @@ LI_API void li_stat_cache_free(liStatCache *sc);
|
|||
*/
|
||||
LI_API liHandlerResult li_stat_cache_get(liVRequest *vr, GString *path, struct stat *st, int *err, int *fd);
|
||||
|
||||
/* doesn't return HANDLER_WAIT_FOR_EVENT, blocks instead of async lookup */
|
||||
LI_API liHandlerResult li_stat_cache_get_sync(liVRequest *vr, GString *path, struct stat *st, int *err, int *fd);
|
||||
|
||||
/*
|
||||
sce->dirlist will contain a list of stat_cache_entry_data upon success
|
||||
returns HANDLER_WAIT_FOR_EVENT in case of a cache MISS, HANDLER_GO_ON in case of a hit and HANDLER_ERROR in case of an error
|
||||
|
|
|
@ -291,7 +291,7 @@ liHandlerResult li_stat_cache_get_dirlist(liVRequest *vr, GString *path, liStatC
|
|||
}
|
||||
}
|
||||
|
||||
liHandlerResult li_stat_cache_get(liVRequest *vr, GString *path, struct stat *st, int *err, int *fd) {
|
||||
static liHandlerResult stat_cache_get(liVRequest *vr, GString *path, struct stat *st, int *err, int *fd, gboolean async) {
|
||||
liStatCache *sc;
|
||||
liStatCacheEntry *sce;
|
||||
guint i;
|
||||
|
@ -302,17 +302,23 @@ liHandlerResult li_stat_cache_get(liVRequest *vr, GString *path, struct stat *st
|
|||
if (sce) {
|
||||
/* cache hit, check state */
|
||||
if (g_atomic_int_get(&sce->state) == STAT_CACHE_ENTRY_WAITING) {
|
||||
if (async) {
|
||||
sce = NULL;
|
||||
goto callstat;
|
||||
}
|
||||
|
||||
/* already waiting for it? */
|
||||
for (i = 0; i < vr->stat_cache_entries->len; i++) {
|
||||
if (g_ptr_array_index(vr->stat_cache_entries, i) == sce)
|
||||
if (g_ptr_array_index(vr->stat_cache_entries, i) == sce) {
|
||||
return LI_HANDLER_WAIT_FOR_EVENT;
|
||||
}
|
||||
}
|
||||
li_stat_cache_entry_acquire(vr, sce);
|
||||
return LI_HANDLER_WAIT_FOR_EVENT;
|
||||
}
|
||||
|
||||
sc->hits++;
|
||||
} else {
|
||||
} else if (async) {
|
||||
/* cache miss, allocate new entry */
|
||||
sce = stat_cache_entry_new(path);
|
||||
sce->type = STAT_CACHE_ENTRY_SINGLE;
|
||||
|
@ -324,6 +330,7 @@ liHandlerResult li_stat_cache_get(liVRequest *vr, GString *path, struct stat *st
|
|||
return LI_HANDLER_WAIT_FOR_EVENT;
|
||||
}
|
||||
|
||||
callstat:
|
||||
if (fd) {
|
||||
/* open + fstat */
|
||||
while (-1 == (*fd = open(path->str, O_RDONLY))) {
|
||||
|
@ -350,6 +357,16 @@ liHandlerResult li_stat_cache_get(liVRequest *vr, GString *path, struct stat *st
|
|||
return LI_HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
liHandlerResult li_stat_cache_get(liVRequest *vr, GString *path, struct stat *st, int *err, int *fd) {
|
||||
return stat_cache_get(vr, path, &st, &err, &fd, TRUE);
|
||||
}
|
||||
|
||||
/* doesn't return HANDLER_WAIT_FOR_EVENT, blocks instead of async lookup */
|
||||
liHandlerResult li_stat_cache_get_sync(liVRequest *vr, GString *path, struct stat *st, int *err, int *fd) {
|
||||
return stat_cache_get(vr, path, &st, &err, &fd, FALSE);
|
||||
}
|
||||
|
||||
|
||||
void li_stat_cache_entry_acquire(liVRequest *vr, liStatCacheEntry *sce) {
|
||||
sce->refcount++;
|
||||
g_ptr_array_add(vr->stat_cache_entries, sce);
|
||||
|
|
Loading…
Reference in New Issue