diff src/org/tmatesoft/hg/internal/DataAccessProvider.java @ 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 48f993aa2f41
children 909306e412e2
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