From e584e3202b4596d62434126c9f5ee0f66133a42a Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Mon, 20 Jun 2011 16:58:07 -0500 Subject: [PATCH] Add delay-retry loop for handling temporarily locked image file writes --- src/main/java/org/dynmap/flat/FlatMap.java | 4 +-- .../dynmap/kzedmap/DefaultTileRenderer.java | 6 ++-- .../org/dynmap/utils/FileLockManager.java | 29 +++++++++++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/dynmap/flat/FlatMap.java b/src/main/java/org/dynmap/flat/FlatMap.java index 4a12b507..f97e9add 100644 --- a/src/main/java/org/dynmap/flat/FlatMap.java +++ b/src/main/java/org/dynmap/flat/FlatMap.java @@ -281,7 +281,7 @@ public class FlatMap extends MapType { if(!outputFile.getParentFile().exists()) outputFile.getParentFile().mkdirs(); try { - ImageIO.write(im.buf_img, "png", outputFile); + FileLockManager.imageIOWrite(im.buf_img, "png", outputFile); } catch (IOException e) { Debug.error("Failed to save image: " + outputFile.getPath(), e); } catch (java.lang.NullPointerException e) { @@ -308,7 +308,7 @@ public class FlatMap extends MapType { if(!dayfile.getParentFile().exists()) dayfile.getParentFile().mkdirs(); try { - ImageIO.write(im_day.buf_img, "png", dayfile); + FileLockManager.imageIOWrite(im_day.buf_img, "png", dayfile); } catch (IOException e) { Debug.error("Failed to save image: " + dayfile.getPath(), e); } catch (java.lang.NullPointerException e) { diff --git a/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java b/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java index ffc3d39b..d5c068f7 100644 --- a/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java +++ b/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java @@ -265,7 +265,7 @@ public class DefaultTileRenderer implements MapTileRenderer { if(!fname.getParentFile().exists()) fname.getParentFile().mkdirs(); try { - ImageIO.write(img.buf_img, "png", fname); + FileLockManager.imageIOWrite(img.buf_img, "png", fname); } catch (IOException e) { Debug.error("Failed to save image: " + fname.getPath(), e); } catch (java.lang.NullPointerException e) { @@ -291,7 +291,7 @@ public class DefaultTileRenderer implements MapTileRenderer { if(!dfname.getParentFile().exists()) dfname.getParentFile().mkdirs(); try { - ImageIO.write(img_day.buf_img, "png", dfname); + FileLockManager.imageIOWrite(img_day.buf_img, "png", dfname); } catch (IOException e) { Debug.error("Failed to save image: " + dfname.getPath(), e); } catch (java.lang.NullPointerException e) { @@ -365,7 +365,7 @@ public class DefaultTileRenderer implements MapTileRenderer { zoomFile.getParentFile().mkdirs(); try { - ImageIO.write(zIm, "png", zoomFile); + FileLockManager.imageIOWrite(zIm, "png", zoomFile); Debug.debug("Saved zoom-out tile at " + zoomFile.getName()); } catch (IOException e) { Debug.error("Failed to save zoom-out tile: " + zoomFile.getName(), e); diff --git a/src/main/java/org/dynmap/utils/FileLockManager.java b/src/main/java/org/dynmap/utils/FileLockManager.java index c60efcf5..c3f4d679 100644 --- a/src/main/java/org/dynmap/utils/FileLockManager.java +++ b/src/main/java/org/dynmap/utils/FileLockManager.java @@ -1,6 +1,10 @@ package org.dynmap.utils; import java.io.File; +import java.io.FileNotFoundException; import java.util.HashMap; +import java.awt.image.BufferedImage; +import java.io.IOException; +import javax.imageio.ImageIO; import org.dynmap.Log; /** @@ -102,4 +106,29 @@ public class FileLockManager { } //Log.info("releaseReadLock(" + f + ")"); } + private static final int MAX_WRITE_RETRIES = 6; + /** + * Wrapper for IOImage.write - implements retries for busy files + */ + public static void imageIOWrite(BufferedImage img, String type, File fname) throws IOException { + int retrycnt = 0; + boolean done = false; + + while(!done) { + try { + ImageIO.write(img, type, fname); + done = true; + } catch (FileNotFoundException fnfx) { /* This seems to be what we get when file is locked by reader */ + if(retrycnt < MAX_WRITE_RETRIES) { + Log.info("Image file " + fname.getPath() + " - unable to write - retry #" + retrycnt); + try { Thread.sleep(50 << retrycnt); } catch (InterruptedException ix) { throw fnfx; } + retrycnt++; + } + else { + Log.info("Image file " + fname.getPath() + " - unable to write - failed"); + throw fnfx; + } + } + } + } }