summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorJens Baumgart2010-07-21 03:35:15 (EDT)
committer Jens Baumgart2010-07-21 03:35:15 (EDT)
commite99c48a61a835149133fca57be117dc9248f5cd2 (patch)
tree4cd7d007dc34b9ec4b119fa398283e7e7fbdaa9e
parentec13e0382ab1f9d32d889068b7aeb9c2ef6a2b60 (diff)
downloadjgit-e99c48a61a835149133fca57be117dc9248f5cd2.zip
jgit-e99c48a61a835149133fca57be117dc9248f5cd2.tar.gz
jgit-e99c48a61a835149133fca57be117dc9248f5cd2.tar.bz2
Fix concurrent read / write issue in GitIndex on Windowsrefs/changes/52/1152/4
GitIndex.write fails if another thread concurrently reads the index file. The problem is fixed by retrying the rename operation if it fails. Bug: 311051 Change-Id: Ib243d2a90adae312712d02521de4834d06804944 Signed-off-by: Jens Baumgart <jens.baumgart@sap.com>
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/GitIndex.java30
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java7
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX_Java5.java5
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX_Java6.java5
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java5
5 files changed, 48 insertions, 4 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/GitIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/GitIndex.java
index defda14..df49063 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/GitIndex.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/GitIndex.java
@@ -297,10 +297,32 @@ public class GitIndex {
fc.write(buf);
fc.close();
fileOutputStream.close();
- if (cacheFile.exists())
- if (!cacheFile.delete())
- throw new IOException(
- JGitText.get().couldNotRenameDeleteOldIndex);
+ if (cacheFile.exists()) {
+ if (db.getFS().retryFailedLockFileCommit()) {
+ // file deletion fails on windows if another
+ // thread is reading the file concurrently
+ // So let's try 10 times...
+ boolean deleted = false;
+ for (int i = 0; i < 10; i++) {
+ if (cacheFile.delete()) {
+ deleted = true;
+ break;
+ }
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+ if (!deleted)
+ throw new IOException(
+ JGitText.get().couldNotRenameDeleteOldIndex);
+ } else {
+ if (!cacheFile.delete())
+ throw new IOException(
+ JGitText.get().couldNotRenameDeleteOldIndex);
+ }
+ }
if (!tmpIndex.renameTo(cacheFile))
throw new IOException(
JGitText.get().couldNotRenameTemporaryIndexFileToIndex);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
index b8d4337..cb5c8bd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -149,6 +149,13 @@ public abstract class FS {
}
/**
+ * Does this file system have problems with atomic renames?
+ *
+ * @return true if the caller should retry a failed rename of a lock file.
+ */
+ public abstract boolean retryFailedLockFileCommit();
+
+ /**
* Determine the user's home directory (location where preferences are).
*
* @return the user's home directory; null if the user does not have one.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX_Java5.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX_Java5.java
index 4ce0366..950d491 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX_Java5.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX_Java5.java
@@ -57,4 +57,9 @@ class FS_POSIX_Java5 extends FS {
public boolean setExecute(final File f, final boolean canExec) {
return false;
}
+
+ @Override
+ public boolean retryFailedLockFileCommit() {
+ return false;
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX_Java6.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX_Java6.java
index 8a86d2e..192d9bb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX_Java6.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX_Java6.java
@@ -104,4 +104,9 @@ class FS_POSIX_Java6 extends FS {
throw new Error(e);
}
}
+
+ @Override
+ public boolean retryFailedLockFileCommit() {
+ return false;
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java
index c86f3e1..4e35e6e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java
@@ -71,4 +71,9 @@ class FS_Win32 extends FS {
public boolean setExecute(final File f, final boolean canExec) {
return false;
}
+
+ @Override
+ public boolean retryFailedLockFileCommit() {
+ return true;
+ }
}