[core] stat_cache_entry reference counting

future: should probably create fd cache separate from stat_cache,
        perhaps along w/ http-specific fields like etag and content_type
        and maybe even mmap
This commit is contained in:
Glenn Strauss 2020-10-19 21:36:46 -04:00
parent e057c5413b
commit 7f8ab9dd29
2 changed files with 34 additions and 5 deletions

View File

@ -533,6 +533,7 @@ static stat_cache_entry * stat_cache_entry_init(void) {
stat_cache_entry *sce = calloc(1, sizeof(*sce));
force_assert(NULL != sce);
sce->fd = -1;
sce->refcnt = 1;
return sce;
}
@ -540,6 +541,8 @@ static void stat_cache_entry_free(void *data) {
stat_cache_entry *sce = data;
if (!sce) return;
if (--sce->refcnt) return;
#ifdef HAVE_FAM_H
/*(decrement refcnt only;
* defer cancelling FAM monitor on dir even if refcnt reaches zero)*/
@ -554,6 +557,15 @@ static void stat_cache_entry_free(void *data) {
free(sce);
}
void stat_cache_entry_refchg(void *data, int mod) {
/*(expect mod == -1 or mod == 1)*/
stat_cache_entry * const sce = data;
if (mod < 0 && 1 == sce->refcnt)
stat_cache_entry_free(data);
else
sce->refcnt += mod;
}
#if defined(HAVE_XATTR) || defined(HAVE_EXTATTR)
static const char *attrname = "Content-Type";
@ -813,8 +825,15 @@ void stat_cache_update_entry(const char *name, uint32_t len,
buffer_clear(&sce->content_type);
#endif
if (sce->fd >= 0) {
close(sce->fd);
sce->fd = -1;
if (1 == sce->refcnt) {
close(sce->fd);
sce->fd = -1;
}
else {
--sce->refcnt; /* stat_cache_entry_free(sce); */
(*sptree)->data = sce = stat_cache_entry_init();
buffer_copy_string_len(&sce->name, name, len);
}
}
sce->st = *st;
}
@ -1056,8 +1075,15 @@ stat_cache_entry * stat_cache_get_entry(const buffer *name) {
if (sce->fd >= 0) {
/* close fd if file changed */
if (!stat_cache_stat_eq(&sce->st, &st)) {
close(sce->fd);
sce->fd = -1;
if (1 == sce->refcnt) {
close(sce->fd);
sce->fd = -1;
}
else {
--sce->refcnt; /* stat_cache_entry_free(sce); */
sptree->data = sce = stat_cache_entry_init();
buffer_copy_string_len(&sce->name, name->ptr, len);
}
}
}

View File

@ -12,10 +12,11 @@
typedef struct stat stat_cache_st;
typedef struct {
typedef struct stat_cache_entry {
buffer name;
time_t stat_ts;
int fd;
int refcnt;
#ifdef HAVE_FAM_H
void *fam_dir;
#endif
@ -35,6 +36,8 @@ int stat_cache_init(struct fdevents *ev, log_error_st *errh);
__attribute_cold__
void stat_cache_free(void);
void stat_cache_entry_refchg(void *data, int mod);
__attribute_cold__
void stat_cache_xattrname (const char *name);