[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:
parent
e057c5413b
commit
7f8ab9dd29
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue