summaryrefslogtreecommitdiff
path: root/src/odb_pack.c
diff options
context:
space:
mode:
authorMichael Schubert <schu@schu.io>2012-09-14 21:33:50 +0200
committerMichael Schubert <schu@schu.io>2012-09-14 22:35:10 +0200
commit3d7617e49e22053e3a34061fc6f109d27c67d1d2 (patch)
tree8919f2ca3b044c29fee1d96566ceec95e7723a56 /src/odb_pack.c
parentb200a813c090c2ccf12ee4b5a99b45300fead2e8 (diff)
downloadlibgit2-3d7617e49e22053e3a34061fc6f109d27c67d1d2.tar.gz
odb_pack: fix race condition
last_found is the last packfile a wanted object was found in. Since last_found is shared among all searching threads, it might changes while we're searching. As suggested by @arrbee, put a copy on the stack to fix the race condition.
Diffstat (limited to 'src/odb_pack.c')
-rw-r--r--src/odb_pack.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/src/odb_pack.c b/src/odb_pack.c
index d33d06456..b4f958b6f 100644
--- a/src/odb_pack.c
+++ b/src/odb_pack.c
@@ -267,9 +267,10 @@ static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backen
{
int error;
unsigned int i;
+ struct git_pack_file *last_found = backend->last_found;
- if (backend->last_found &&
- git_pack_entry_find(e, backend->last_found, oid, GIT_OID_HEXSZ) == 0)
+ if (last_found &&
+ git_pack_entry_find(e, last_found, oid, GIT_OID_HEXSZ) == 0)
return 0;
if ((error = packfile_refresh_all(backend)) < 0)
@@ -279,7 +280,7 @@ static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backen
struct git_pack_file *p;
p = git_vector_get(&backend->packs, i);
- if (p == backend->last_found)
+ if (p == last_found)
continue;
if (git_pack_entry_find(e, p, oid, GIT_OID_HEXSZ) == 0) {
@@ -300,12 +301,13 @@ static int pack_entry_find_prefix(
int error;
unsigned int i;
unsigned found = 0;
+ struct git_pack_file *last_found = backend->last_found;
if ((error = packfile_refresh_all(backend)) < 0)
return error;
- if (backend->last_found) {
- error = git_pack_entry_find(e, backend->last_found, short_oid, len);
+ if (last_found) {
+ error = git_pack_entry_find(e, last_found, short_oid, len);
if (error == GIT_EAMBIGUOUS)
return error;
if (!error)
@@ -316,7 +318,7 @@ static int pack_entry_find_prefix(
struct git_pack_file *p;
p = git_vector_get(&backend->packs, i);
- if (p == backend->last_found)
+ if (p == last_found)
continue;
error = git_pack_entry_find(e, p, short_oid, len);