Browse Source

Retry loading config when locked by another process

When loading the config, a FileNotFoundException may occur if the file
exists but cannot be read (see [1]). This is the case on Windows with a
virus scanner checking the file. Therefore if the file exists and that
exception is thrown, retry multiple times, similar to how this was
already implemented for IOException.

[1] https://docs.oracle.com/javase/8/docs/api/java/io/FileNotFoundException.html

Bug: 529522
Change-Id: Ic5dc3b7b24bb0005d6256ed00513bc7c0b91e613
Signed-off-by: Michael Keppler <Michael.Keppler@gmx.de>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
stable-5.5
Michael Keppler 6 years ago committed by Matthias Sohn
parent
commit
e9abe09809
  1. 1
      org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
  2. 1
      org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
  3. 21
      org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java

1
org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties

@ -139,6 +139,7 @@ configSubsectionContainsNewline=config subsection name contains newline
configSubsectionContainsNullByte=config subsection name contains byte 0x00 configSubsectionContainsNullByte=config subsection name contains byte 0x00
configValueContainsNullByte=config value contains byte 0x00 configValueContainsNullByte=config value contains byte 0x00
configHandleIsStale=config file handle is stale, {0}. retry configHandleIsStale=config file handle is stale, {0}. retry
configHandleMayBeLocked=config file handle may be locked by other process, {0}. retry
connectionFailed=connection failed connectionFailed=connection failed
connectionTimeOut=Connection time out: {0} connectionTimeOut=Connection time out: {0}
contextMustBeNonNegative=context must be >= 0 contextMustBeNonNegative=context must be >= 0

1
org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java

@ -200,6 +200,7 @@ public class JGitText extends TranslationBundle {
/***/ public String configSubsectionContainsNullByte; /***/ public String configSubsectionContainsNullByte;
/***/ public String configValueContainsNullByte; /***/ public String configValueContainsNullByte;
/***/ public String configHandleIsStale; /***/ public String configHandleIsStale;
/***/ public String configHandleMayBeLocked;
/***/ public String connectionFailed; /***/ public String connectionFailed;
/***/ public String connectionTimeOut; /***/ public String connectionTimeOut;
/***/ public String contextMustBeNonNegative; /***/ public String contextMustBeNonNegative;

21
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java

@ -148,7 +148,8 @@ public class FileBasedConfig extends StoredConfig {
*/ */
@Override @Override
public void load() throws IOException, ConfigInvalidException { public void load() throws IOException, ConfigInvalidException {
final int maxStaleRetries = 5; final int maxRetries = 5;
int retryDelayMillis = 20;
int retries = 0; int retries = 0;
while (true) { while (true) {
final FileSnapshot oldSnapshot = snapshot; final FileSnapshot oldSnapshot = snapshot;
@ -177,6 +178,22 @@ public class FileBasedConfig extends StoredConfig {
} }
return; return;
} catch (FileNotFoundException noFile) { } catch (FileNotFoundException noFile) {
// might be locked by another process (see exception Javadoc)
if (retries < maxRetries && configFile.exists()) {
if (LOG.isDebugEnabled()) {
LOG.debug(MessageFormat.format(
JGitText.get().configHandleMayBeLocked,
Integer.valueOf(retries)), noFile);
}
try {
Thread.sleep(retryDelayMillis);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
retries++;
retryDelayMillis *= 2; // max wait 1260 ms
continue;
}
if (configFile.exists()) { if (configFile.exists()) {
throw noFile; throw noFile;
} }
@ -185,7 +202,7 @@ public class FileBasedConfig extends StoredConfig {
return; return;
} catch (IOException e) { } catch (IOException e) {
if (FileUtils.isStaleFileHandle(e) if (FileUtils.isStaleFileHandle(e)
&& retries < maxStaleRetries) { && retries < maxRetries) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug(MessageFormat.format( LOG.debug(MessageFormat.format(
JGitText.get().configHandleIsStale, JGitText.get().configHandleIsStale,

Loading…
Cancel
Save