Add basic locking to the git_odb structure

We grab the lock while accessing the alternates list, ensuring that
we only initialize it once for the given git_odb.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
Shawn O. Pearce 2008-12-31 13:27:51 -08:00
parent 028ef0de72
commit 5614dc18f6

View File

@ -31,6 +31,8 @@
#include <stdio.h> #include <stdio.h>
struct git_odb { struct git_odb {
git_lck lock;
/** Path to the "objects" directory. */ /** Path to the "objects" directory. */
char *objects_dir; char *objects_dir;
@ -417,12 +419,21 @@ static int open_alternates(git_odb *db)
{ {
unsigned n = 0; unsigned n = 0;
gitlck_lock(&db->lock);
if (db->alternates) {
gitlck_unlock(&db->lock);
return 1;
}
db->alternates = git__malloc(sizeof(*db->alternates) * (n + 1)); db->alternates = git__malloc(sizeof(*db->alternates) * (n + 1));
if (!db->alternates) if (!db->alternates) {
return GIT_ERROR; gitlck_unlock(&db->lock);
return -1;
}
db->alternates[n] = NULL; db->alternates[n] = NULL;
return GIT_SUCCESS; gitlck_unlock(&db->lock);
return 0;
} }
int git_odb_open(git_odb **out, const char *objects_dir) int git_odb_open(git_odb **out, const char *objects_dir)
@ -438,6 +449,7 @@ int git_odb_open(git_odb **out, const char *objects_dir)
} }
db->alternates = NULL; db->alternates = NULL;
gitlck_init(&db->lock);
*out = db; *out = db;
return GIT_SUCCESS; return GIT_SUCCESS;
@ -448,6 +460,8 @@ void git_odb_close(git_odb *db)
if (!db) if (!db)
return; return;
gitlck_lock(&db->lock);
if (db->alternates) { if (db->alternates) {
git_odb **alt; git_odb **alt;
for (alt = db->alternates; *alt; alt++) for (alt = db->alternates; *alt; alt++)
@ -456,6 +470,9 @@ void git_odb_close(git_odb *db)
} }
free(db->objects_dir); free(db->objects_dir);
gitlck_unlock(&db->lock);
gitlck_free(&db->lock);
free(db); free(db);
} }
@ -469,7 +486,7 @@ attempt:
return GIT_SUCCESS; return GIT_SUCCESS;
if (!git_odb__read_loose(out, db, id)) if (!git_odb__read_loose(out, db, id))
return GIT_SUCCESS; return GIT_SUCCESS;
if (!db->alternates && !open_alternates(db)) if (!open_alternates(db))
goto attempt; goto attempt;
out->data = NULL; out->data = NULL;