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 7a03593ab..e33c4bff9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java @@ -299,46 +299,45 @@ public abstract class FS { Path probe = dir.resolve(".probe-" + UUID.randomUUID()); //$NON-NLS-1$ try { Files.createFile(probe); - // ensure we always use the local system clock - FileUtils.touch(probe); - long wait = 512; - long start = System.nanoTime(); FileTime t1 = Files.getLastModifiedTime(probe); FileTime t2 = t1; - while (t2.compareTo(t1) <= 0) { - TimeUnit.NANOSECONDS.sleep(wait); - checkTimeout(s, start); - FileUtils.touch(probe); + Instant t1i = t1.toInstant(); + for (long i = 1; t2.compareTo(t1) <= 0; i += 1 + i / 20) { + Files.setLastModifiedTime(probe, + FileTime.from(t1i.plusNanos(i * 1000))); t2 = Files.getLastModifiedTime(probe); - if (wait < 100_000_000L) { - wait = wait * 2; - } } - Duration resolution = Duration.between(t1.toInstant(), t2.toInstant()); - saveFileTimeResolution(s, resolution); - return Optional.of(resolution); + Duration fsResolution = Duration.between(t1.toInstant(), t2.toInstant()); + Duration clockResolution = measureClockResolution(); + fsResolution = fsResolution.plus(clockResolution); + saveFileTimeResolution(s, fsResolution); + return Optional.of(fsResolution); } catch (AccessDeniedException e) { LOG.warn(e.getLocalizedMessage(), e); // see bug 548648 - } catch (IOException | TimeoutException e) { - LOG.error(e.getLocalizedMessage(), e); - } catch (InterruptedException e) { + } catch (IOException e) { LOG.error(e.getLocalizedMessage(), e); - Thread.currentThread().interrupt(); } finally { deleteProbe(probe); } return Optional.empty(); } - private static void checkTimeout(FileStore s, long start) - throws TimeoutException { - if (System.nanoTime() - start >= FALLBACK_TIMESTAMP_RESOLUTION - .toNanos()) { - throw new TimeoutException(MessageFormat.format(JGitText - .get().timeoutMeasureFsTimestampResolution, - s.toString())); + private static Duration measureClockResolution() { + Duration clockResolution = Duration.ZERO; + for (int i = 0; i < 10; i++) { + Instant t1 = Instant.now(); + Instant t2 = t1; + while (t2.compareTo(t1) <= 0) { + t2 = Instant.now(); + } + Duration r = Duration.between(t1, t2); + if (r.compareTo(clockResolution) > 0) { + clockResolution = r; + } } + return clockResolution; } + private static void deleteProbe(Path probe) { if (Files.exists(probe)) { try {