changeset 440:299870249a28

Issue 30: bogus IOException for mmap file on linux
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 19 Apr 2012 19:18:25 +0200
parents 2bf6f917a7e5
children 2a08466838d3
files src/org/tmatesoft/hg/internal/DataAccessProvider.java src/org/tmatesoft/hg/internal/RevlogStream.java
diffstat 2 files changed, 25 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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();
 		}