예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
파일: attrcache.c 프로젝트: 1336/libgit2
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;
}
예제 #4
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);
}
예제 #5
0
파일: global.c 프로젝트: DonkeyWs/libgit2
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]);
	}
}
예제 #6
0
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;
}
예제 #7
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;
}
예제 #8
0
파일: attrcache.c 프로젝트: 1336/libgit2
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);
				}
			}
		});