static void destroy_unrefed(bool all) { struct mail_index_alloc_cache_list **list, *rec; bool seen_ref0 = FALSE; for (list = &indexes; *list != NULL;) { rec = *list; if (rec->refcount == 0 && (all || rec->destroy_time <= ioloop_time)) { *list = rec->next; mail_index_alloc_cache_list_free(rec); } else { if (rec->refcount == 0) seen_ref0 = TRUE; if (all && rec->index->open_count == 1 && rec->referenced) { /* we're the only one keeping this index open. we might be here, because the caller is deleting this mailbox and wants its indexes to be closed. so close it. */ rec->referenced = FALSE; mail_index_close(rec->index); } list = &(*list)->next; } } if (!seen_ref0 && to_index != NULL) timeout_remove(&to_index); }
static struct mail_index_alloc_cache_list * mail_index_alloc_cache_find(const char *mailbox_path, const char *index_dir, const struct stat *index_st) { struct mail_index_alloc_cache_list **indexp, *rec, *match; unsigned int destroy_count; struct stat st; destroy_count = 0; match = NULL; for (indexp = &indexes; *indexp != NULL;) { rec = *indexp; if (match != NULL) { /* already found the index. we're just going through the rest of them to drop 0 refcounts */ } else if (rec->refcount == 0 && rec->index->open_count == 0) { /* index is already closed. don't even try to reuse it. */ } else if (index_dir != NULL && rec->index_dir_ino != 0) { if (index_st->st_ino == rec->index_dir_ino && CMP_DEV_T(index_st->st_dev, rec->index_dir_dev)) { /* make sure the directory still exists. it might have been renamed and we're trying to access it via its new path now. */ if (stat(rec->index->dir, &st) < 0 || st.st_ino != index_st->st_ino || !CMP_DEV_T(st.st_dev, index_st->st_dev)) rec->destroy_time = 0; else match = rec; } } else if (mailbox_path != NULL && rec->mailbox_path != NULL && index_dir == NULL && rec->index_dir_ino == 0) { if (strcmp(mailbox_path, rec->mailbox_path) == 0) match = rec; } if (rec->refcount == 0 && rec != match) { if (rec->destroy_time <= ioloop_time || destroy_count >= INDEX_CACHE_MAX) { *indexp = rec->next; mail_index_alloc_cache_list_free(rec); continue; } else { destroy_count++; } } indexp = &(*indexp)->next; } return match; }
static void destroy_unrefed(bool all) { struct mail_index_alloc_cache_list **list, *rec; bool seen_ref0 = FALSE; for (list = &indexes; *list != NULL;) { rec = *list; if (rec->refcount == 0 && (all || rec->destroy_time <= ioloop_time)) { *list = rec->next; mail_index_alloc_cache_list_free(rec); } else { if (rec->refcount == 0) seen_ref0 = TRUE; list = &(*list)->next; } } if (!seen_ref0 && to_index != NULL) timeout_remove(&to_index); }