]> source.dussan.org Git - jgit.git/commit
Fix MissingObjectException race in ObjectDirectory 62/21362/2
authorShawn Pearce <spearce@spearce.org>
Fri, 31 Jan 2014 00:25:49 +0000 (16:25 -0800)
committerShawn Pearce <spearce@spearce.org>
Mon, 3 Feb 2014 22:19:32 +0000 (14:19 -0800)
commitd1aacc415a3336144e4b3b55c402a025e920a031
treeaedf338b01feda4cc5259755989f266d7a5aef91
parent8352d1729ca63d4d6d831b2da0b168c950bc6f52
Fix MissingObjectException race in ObjectDirectory

Johannes Carlsson identified a race condition[1] that can lead to
spurious MissingObjectExceptions at read time. If two threads are
active inside of ObjectDirectory looking for a packed object and the
packList is currently the empty NO_PACKS list, thread A will find
no object and eventually consider tryAgain1(). If thread A is put
to sleep and this point and thread B also does not find the object,
loads the packs, when thread A wakes up its tryAgain1 would return
false and the thread never considers the packs.

Rework the internal API of ObjectDirectory to keep a handle on the
exact PackList that was iterated by thread A, allowing it to always
retry walking through the packs if the new PackList is different.

This had some ripple effect into the CachedObjectDirectory and
the shared FileObjectDatabase interface. The new code should be
slightly easier to follow, especially from the perspective of the
CachedObjectDirectory trying to minimize the number of open system
calls it makes to files matching "$GIT_DIR/objects/??/?x{38}".

[1] http://dev.eclipse.org/mhonarc/lists/jgit-dev/msg02401.html

Change-Id: I9a1c9d6ad6cb38404b7b9178167b714077561353
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CachedObjectDirectory.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileObjectDatabase.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LargePackedDeltaObject.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java