diff options
Diffstat (limited to 'src/attrcache.c')
-rw-r--r-- | src/attrcache.c | 122 |
1 files changed, 61 insertions, 61 deletions
diff --git a/src/attrcache.c b/src/attrcache.c index a7dc0c887..925abb57f 100644 --- a/src/attrcache.c +++ b/src/attrcache.c @@ -24,7 +24,7 @@ GIT_INLINE(void) attr_cache_unlock(git_attr_cache *cache) git_mutex_unlock(&cache->lock); } -GIT_INLINE(git_attr_cache_entry *) attr_cache_lookup_entry( +GIT_INLINE(git_attr_file_entry *) attr_cache_lookup_entry( git_attr_cache *cache, const char *path) { khiter_t pos = git_strmap_lookup_index(cache->files, path); @@ -35,15 +35,15 @@ GIT_INLINE(git_attr_cache_entry *) attr_cache_lookup_entry( return NULL; } -int git_attr_cache_entry__new( - git_attr_cache_entry **out, +int git_attr_cache__alloc_file_entry( + git_attr_file_entry **out, const char *base, const char *path, git_pool *pool) { size_t baselen = 0, pathlen = strlen(path); - size_t cachesize = sizeof(git_attr_cache_entry) + pathlen + 1; - git_attr_cache_entry *ce; + size_t cachesize = sizeof(git_attr_file_entry) + pathlen + 1; + git_attr_file_entry *ce; if (base != NULL && git_path_root(path) < 0) { baselen = strlen(base); @@ -72,41 +72,41 @@ int git_attr_cache_entry__new( /* call with attrcache locked */ static int attr_cache_make_entry( - git_attr_cache_entry **out, git_repository *repo, const char *path) + git_attr_file_entry **out, git_repository *repo, const char *path) { int error = 0; git_attr_cache *cache = git_repository_attr_cache(repo); - git_attr_cache_entry *ce = NULL; + git_attr_file_entry *entry = NULL; - error = git_attr_cache_entry__new( - &ce, git_repository_workdir(repo), path, &cache->pool); + error = git_attr_cache__alloc_file_entry( + &entry, git_repository_workdir(repo), path, &cache->pool); if (!error) { - git_strmap_insert(cache->files, ce->path, ce, error); + git_strmap_insert(cache->files, entry->path, entry, error); if (error > 0) error = 0; } - *out = ce; + *out = entry; return error; } /* insert entry or replace existing if we raced with another thread */ static int attr_cache_upsert(git_attr_cache *cache, git_attr_file *file) { - git_attr_cache_entry *ce; + git_attr_file_entry *entry; git_attr_file *old; if (attr_cache_lock(cache) < 0) return -1; - ce = attr_cache_lookup_entry(cache, file->ce->path); - - old = ce->file[file->source]; + entry = attr_cache_lookup_entry(cache, file->entry->path); - GIT_REFCOUNT_OWN(file, ce); + GIT_REFCOUNT_OWN(file, entry); GIT_REFCOUNT_INC(file); - ce->file[file->source] = file; + + old = git__compare_and_swap( + &entry->file[file->source], entry->file[file->source], file); if (old) { GIT_REFCOUNT_OWN(old, NULL); @@ -120,7 +120,7 @@ static int attr_cache_upsert(git_attr_cache *cache, git_attr_file *file) static int attr_cache_remove(git_attr_cache *cache, git_attr_file *file) { int error = 0; - git_attr_cache_entry *ce; + git_attr_file_entry *entry; bool found = false; if (!file) @@ -128,27 +128,29 @@ static int attr_cache_remove(git_attr_cache *cache, git_attr_file *file) if ((error = attr_cache_lock(cache)) < 0) return error; - if ((ce = attr_cache_lookup_entry(cache, file->ce->path)) != NULL && - ce->file[file->source] == file) - { - ce->file[file->source] = NULL; - GIT_REFCOUNT_OWN(file, NULL); - found = true; - } + if ((entry = attr_cache_lookup_entry(cache, file->entry->path)) != NULL) + file = git__compare_and_swap(&entry->file[file->source], file, NULL); attr_cache_unlock(cache); - if (found) + if (found) { + GIT_REFCOUNT_OWN(file, NULL); git_attr_file__free(file); + } return error; } +/* Look up cache entry and file. + * - If entry is not present, create it while the cache is locked. + * - If file is present, increment refcount before returning it, so the + * cache can be unlocked and it won't go away. + */ static int attr_cache_lookup( git_attr_file **out_file, - git_attr_cache_entry **out_ce, + git_attr_file_entry **out_entry, git_repository *repo, - git_attr_cache_source source, + git_attr_file_source source, const char *base, const char *filename) { @@ -156,7 +158,7 @@ static int attr_cache_lookup( git_buf path = GIT_BUF_INIT; const char *wd = git_repository_workdir(repo), *relfile; git_attr_cache *cache = git_repository_attr_cache(repo); - git_attr_cache_entry *ce = NULL; + git_attr_file_entry *entry = NULL; git_attr_file *file = NULL; /* join base and path as needed */ @@ -174,20 +176,20 @@ static int attr_cache_lookup( if ((error = attr_cache_lock(cache)) < 0) goto cleanup; - ce = attr_cache_lookup_entry(cache, relfile); - if (!ce) { - if ((error = attr_cache_make_entry(&ce, repo, relfile)) < 0) + entry = attr_cache_lookup_entry(cache, relfile); + if (!entry) { + if ((error = attr_cache_make_entry(&entry, repo, relfile)) < 0) goto cleanup; - } else if (ce->file[source] != NULL) { - file = ce->file[source]; + } else if (entry->file[source] != NULL) { + file = entry->file[source]; GIT_REFCOUNT_INC(file); } attr_cache_unlock(cache); cleanup: - *out_file = file; - *out_ce = ce; + *out_file = file; + *out_entry = entry; git_buf_free(&path); return error; @@ -196,29 +198,26 @@ cleanup: int git_attr_cache__get( git_attr_file **out, git_repository *repo, - git_attr_cache_source source, + git_attr_file_source source, const char *base, const char *filename, - git_attr_cache_parser parser, - void *payload) + git_attr_file_parser parser) { int error = 0; git_attr_cache *cache = git_repository_attr_cache(repo); - git_attr_cache_entry *ce = NULL; + git_attr_file_entry *entry = NULL; git_attr_file *file = NULL; - if ((error = attr_cache_lookup(&file, &ce, repo, source, base, filename)) < 0) + if ((error = attr_cache_lookup( + &file, &entry, repo, source, base, filename)) < 0) goto cleanup; - /* if this is not a file backed entry, just create a new empty one */ - if (!parser) { - if (!file && !(error = git_attr_file__new(&file, ce, source))) - error = attr_cache_upsert(cache, file); - } - /* otherwise load and/or reload as needed */ - else if (!file || (error = git_attr_file__out_of_date(repo, file)) > 0) { - if (!(error = git_attr_file__load( - &file, repo, ce, source, parser, payload))) + /* if file not found or out of date, load up-to-date data and replace */ + if (!file || (error = git_attr_file__out_of_date(repo, file)) > 0) { + /* decrement refcount (if file was found) b/c we will not return it */ + git_attr_file__free(file); + + if (!(error = git_attr_file__load(&file, repo, entry, source, parser))) error = attr_cache_upsert(cache, file); } @@ -245,13 +244,13 @@ cleanup: bool git_attr_cache__is_cached( git_repository *repo, - git_attr_cache_source source, + git_attr_file_source source, const char *filename) { git_attr_cache *cache = git_repository_attr_cache(repo); git_strmap *files; khiter_t pos; - git_attr_cache_entry *ce; + git_attr_file_entry *entry; if (!(cache = git_repository_attr_cache(repo)) || !(files = cache->files)) @@ -261,9 +260,9 @@ bool git_attr_cache__is_cached( if (!git_strmap_valid_index(files, pos)) return false; - ce = git_strmap_value_at(files, pos); + entry = git_strmap_value_at(files, pos); - return ce && (ce->file[source] != NULL); + return entry && (entry->file[source] != NULL); } @@ -307,14 +306,15 @@ static void attr_cache__free(git_attr_cache *cache) unlock = (git_mutex_lock(&cache->lock) == 0); if (cache->files != NULL) { - git_attr_cache_entry *ce; + git_attr_file_entry *entry; + git_attr_file *file; int i; - git_strmap_foreach_value(cache->files, ce, { - for (i = 0; i < GIT_ATTR_CACHE_NUM_SOURCES; ++i) { - if (ce->file[i]) { - GIT_REFCOUNT_OWN(ce->file[i], NULL); - git_attr_file__free(ce->file[i]); + git_strmap_foreach_value(cache->files, entry, { + for (i = 0; i < GIT_ATTR_FILE_NUM_SOURCES; ++i) { + if ((file = git__swap(entry->file[i], NULL)) != NULL) { + GIT_REFCOUNT_OWN(file, NULL); + git_attr_file__free(file); } } }); @@ -345,7 +345,7 @@ static void attr_cache__free(git_attr_cache *cache) git__free(cache); } -int git_attr_cache__init(git_repository *repo) +int git_attr_cache__do_init(git_repository *repo) { int ret = 0; git_attr_cache *cache = git_repository_attr_cache(repo); |