# HG changeset patch # User Artem Tikhomirov # Date 1334855905 -7200 # Node ID 299870249a282b977f8bdc51658c1e7f408d2d4d # Parent 2bf6f917a7e5a16d158b5f44d079314ba3e1e716 Issue 30: bogus IOException for mmap file on linux diff -r 2bf6f917a7e5 -r 299870249a28 src/org/tmatesoft/hg/internal/DataAccessProvider.java --- a/src/org/tmatesoft/hg/internal/DataAccessProvider.java Thu Apr 19 19:17:31 2012 +0200 +++ b/src/org/tmatesoft/hg/internal/DataAccessProvider.java Thu Apr 19 19:18:25 2012 +0200 @@ -167,7 +167,27 @@ position += buffer.position(); } long left = size - position; - buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, position, left < memBufferSize ? left : memBufferSize); + for (int i = 0; i < 3; i++) { + try { + buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, position, left < memBufferSize ? left : memBufferSize); + return; + } catch (IOException ex) { + if (i == 2) { + throw ex; + } + if (i == 0) { + // if first attempt failed, try to free some virtual memory, see Issue 30 for details + logFacility.warn(getClass(), ex, "Memory-map failed, gonna try gc() to free virtual memory"); + } + try { + buffer = null; + System.gc(); + Thread.sleep((1+i) * 1000); + } catch (Throwable t) { + logFacility.error(getClass(), t, "Bad luck"); + } + } + } } @Override diff -r 2bf6f917a7e5 -r 299870249a28 src/org/tmatesoft/hg/internal/RevlogStream.java --- a/src/org/tmatesoft/hg/internal/RevlogStream.java Thu Apr 19 19:17:31 2012 +0200 +++ b/src/org/tmatesoft/hg/internal/RevlogStream.java Thu Apr 19 19:18:25 2012 +0200 @@ -119,7 +119,7 @@ int actualLen = daIndex.readInt(); return actualLen; } catch (IOException ex) { - throw new HgInvalidControlFileException(null, ex, indexFile); + throw new HgInvalidControlFileException(null, ex, indexFile).setRevisionIndex(revisionIndex); } finally { daIndex.done(); } @@ -141,7 +141,7 @@ daIndex.readBytes(rv, 0, 20); return rv; } catch (IOException ex) { - throw new HgInvalidControlFileException(null, ex, indexFile); + throw new HgInvalidControlFileException("Revision lookup failed", ex, indexFile).setRevisionIndex(revisionIndex); } finally { daIndex.done(); } @@ -162,7 +162,7 @@ int linkRev = daIndex.readInt(); return linkRev; } catch (IOException ex) { - throw new HgInvalidControlFileException(null, ex, indexFile); + throw new HgInvalidControlFileException("Linked revision lookup failed", ex, indexFile).setRevisionIndex(revisionIndex); } finally { daIndex.done(); } @@ -193,7 +193,7 @@ daIndex.skip(inline ? 12 + compressedLen : 12); } } catch (IOException ex) { - throw new HgInvalidControlFileException("Failed", ex, indexFile).setRevision(nodeid); + throw new HgInvalidControlFileException("Revision lookup failed", ex, indexFile).setRevision(nodeid); } finally { daIndex.done(); }