void *git_cache_try_store(git_cache *cache, void *entry) { uint32_t hash; const git_oid *oid; cache_node *node = NULL; oid = &((git_cached_obj*)entry)->oid; memcpy(&hash, oid->id, sizeof(hash)); node = &cache->nodes[hash & cache->size_mask]; /* increase the refcount on this object, because * the cache now owns it */ git_cached_obj_incref(entry); git_mutex_lock(&node->lock); if (node->ptr == NULL) { node->ptr = entry; } else if (git_cached_obj_compare(node->ptr, oid) == 0) { git_cached_obj_decref(entry, cache->free_obj); entry = node->ptr; } else { git_cached_obj_decref(node->ptr, cache->free_obj); node->ptr = entry; } /* increase the refcount again, because we are * returning it to the user */ git_cached_obj_incref(entry); git_mutex_unlock(&node->lock); return entry; }
int git_attr_file__parse_buffer( git_repository *repo, git_attr_file *attrs, const char *data) { int error = 0; const char *scan = data, *context = NULL; git_attr_rule *rule = NULL; /* if subdir file path, convert context for file paths */ if (attrs->entry && git_path_root(attrs->entry->path) < 0 && !git__suffixcmp(attrs->entry->path, "/" GIT_ATTR_FILE)) context = attrs->entry->path; if (git_mutex_lock(&attrs->lock) < 0) { giterr_set(GITERR_OS, "Failed to lock attribute file"); return -1; } while (!error && *scan) { /* allocate rule if needed */ if (!rule && !(rule = git__calloc(1, sizeof(*rule)))) { error = -1; break; } rule->match.flags = GIT_ATTR_FNMATCH_ALLOWNEG | GIT_ATTR_FNMATCH_ALLOWMACRO; /* parse the next "pattern attr attr attr" line */ if (!(error = git_attr_fnmatch__parse( &rule->match, &attrs->pool, context, &scan)) && !(error = git_attr_assignment__parse( repo, &attrs->pool, &rule->assigns, &scan))) { if (rule->match.flags & GIT_ATTR_FNMATCH_MACRO) /* TODO: warning if macro found in file below repo root */ error = git_attr_cache__insert_macro(repo, rule); else error = git_vector_insert(&attrs->rules, rule); } /* if the rule wasn't a pattern, on to the next */ if (error < 0) { git_attr_rule__clear(rule); /* reset rule contents */ if (error == GIT_ENOTFOUND) error = 0; } else { rule = NULL; /* vector now "owns" the rule */ } } git_mutex_unlock(&attrs->lock); git_attr_rule__free(rule); return error; }
GIT_INLINE(int) attr_cache_lock(git_attr_cache *cache) { GIT_UNUSED(cache); /* avoid warning if threading is off */ if (git_mutex_lock(&cache->lock) < 0) { giterr_set(GITERR_OS, "Unable to get attr cache lock"); return -1; } return 0; }
static void attr_file_free(git_attr_file *file) { bool unlock = !git_mutex_lock(&file->lock); git_attr_file__clear_rules(file, false); git_pool_clear(&file->pool); if (unlock) git_mutex_unlock(&file->lock); git_mutex_free(&file->lock); git__memzero(file, sizeof(*file)); git__free(file); }
void openssl_locking_function(int mode, int n, const char *file, int line) { int lock; GIT_UNUSED(file); GIT_UNUSED(line); lock = mode & CRYPTO_LOCK; if (lock) { git_mutex_lock(&openssl_locks[n]); } else { git_mutex_unlock(&openssl_locks[n]); } }
int git_attr_file__clear_rules(git_attr_file *file, bool need_lock) { unsigned int i; git_attr_rule *rule; if (need_lock && git_mutex_lock(&file->lock) < 0) { giterr_set(GITERR_OS, "Failed to lock attribute file"); return -1; } git_vector_foreach(&file->rules, i, rule) git_attr_rule__free(rule); git_vector_free(&file->rules); if (need_lock) git_mutex_unlock(&file->lock); return 0; }
void *git_cache_get(git_cache *cache, const git_oid *oid) { uint32_t hash; cache_node *node = NULL; void *result = NULL; memcpy(&hash, oid->id, sizeof(hash)); node = &cache->nodes[hash & cache->size_mask]; git_mutex_lock(&node->lock); { if (node->ptr && git_cached_obj_compare(node->ptr, oid) == 0) { git_cached_obj_incref(node->ptr); result = node->ptr; } } git_mutex_unlock(&node->lock); return result; }
static void attr_cache__free(git_attr_cache *cache) { bool unlock; if (!cache) return; unlock = (git_mutex_lock(&cache->lock) == 0); if (cache->files != NULL) { git_attr_file_entry *entry; git_attr_file *file; int 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); } } });