From 9e471915d08f67e07411fba898ccb1c446c2f59f Mon Sep 17 00:00:00 2001 From: brinn <brinn> Date: Thu, 10 Feb 2011 23:10:44 +0000 Subject: [PATCH] fix: avoid hanging threads on RuntimeExceptions (merged from branch S99.x) SVN: 19893 --- .../api/v1/ScreeningOpenbisServiceFacade.java | 62 +++++++++++++------ .../client/api/v1/WellImageCache.java | 46 +++++++++++++- 2 files changed, 87 insertions(+), 21 deletions(-) diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java index 06009376cfc..2b0a47476bd 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java @@ -979,17 +979,28 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa final WellImages images = imageCache.getWellImages(imageReference, size, imageMetadata); if (images.isLoaderCall()) { - final List<PlateImageReference> imageReferences = - createPlateImageReferences(imageDatasetId, imageMetadata, null, - Collections.singletonList(imageReference.getWellPosition())); - loadImages(imageReferences, imageSizeOrNull, new IPlateImageHandler() - { - public void handlePlateImage(PlateImageReference plateImageReference, - byte[] imageFileBytes) + try + { + final List<PlateImageReference> imageReferences = + createPlateImageReferences(imageDatasetId, imageMetadata, null, + Collections.singletonList(imageReference.getWellPosition())); + loadImages(imageReferences, imageSizeOrNull, new IPlateImageHandler() { - images.putImage(plateImageReference, imageFileBytes); - } - }); + public void handlePlateImage(PlateImageReference plateImageReference, + byte[] imageFileBytes) + { + images.putImage(plateImageReference, imageFileBytes); + } + }); + } catch (IOException ex) + { + images.cancel(ex); + throw ex; + } catch (RuntimeException ex) + { + images.cancel(ex); + throw ex; + } } final CachedImage imageOrNull = images.getImage(imageReference); if (imageOrNull == null) @@ -1065,17 +1076,28 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa .getThumbnailHeight()), imageMetadata); if (images.isLoaderCall()) { - final List<PlateImageReference> imageReferences = - createPlateImageReferences(imageDatasetId, imageMetadata, null, - Collections.singletonList(imageReference.getWellPosition())); - loadThumbnailImages(imageReferences, new IPlateImageHandler() - { - public void handlePlateImage(PlateImageReference plateImageReference, - byte[] imageFileBytes) + try + { + final List<PlateImageReference> imageReferences = + createPlateImageReferences(imageDatasetId, imageMetadata, null, + Collections.singletonList(imageReference.getWellPosition())); + loadThumbnailImages(imageReferences, new IPlateImageHandler() { - images.putImage(plateImageReference, imageFileBytes); - } - }); + public void handlePlateImage(PlateImageReference plateImageReference, + byte[] imageFileBytes) + { + images.putImage(plateImageReference, imageFileBytes); + } + }); + } catch (IOException ex) + { + images.cancel(ex); + throw ex; + } catch (RuntimeException ex) + { + images.cancel(ex); + throw ex; + } } final CachedImage imageOrNull = images.getImage(imageReference); if (imageOrNull == null) diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/WellImageCache.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/WellImageCache.java index c0de3a0fb95..1bf490dddec 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/WellImageCache.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/WellImageCache.java @@ -16,6 +16,7 @@ package ch.systemsx.cisd.openbis.plugin.screening.client.api.v1; +import java.io.IOException; import java.lang.ref.SoftReference; import java.util.HashMap; import java.util.Map; @@ -156,6 +157,10 @@ final class WellImageCache private final CountDownLatch ready = new CountDownLatch(1); private byte[] imageData; + + private IOException ioe; + + private RuntimeException rex; void set(byte[] imageData) { @@ -163,17 +168,40 @@ final class WellImageCache ready.countDown(); } - byte[] getImageData() + byte[] getImageData() throws IOException { try { ready.await(); + if (ioe != null) + { + throw ioe; + } + if (rex != null) + { + throw rex; + } return imageData; } catch (InterruptedException ex) { throw new RuntimeException("Image fetching interrupted."); } } + + void release(IOException ex) + { + this.ioe = ex; + ready.countDown(); + } + + void release(RuntimeException ex) + { + if (ready.getCount() > 0) + { + this.rex = ex; + ready.countDown(); + } + } } static final class WellImages @@ -204,6 +232,22 @@ final class WellImageCache { return loaderCall; } + + void cancel(IOException ex) + { + for (CachedImage image : imageMap.values()) + { + image.release(ex); + } + } + + void cancel(RuntimeException ex) + { + for (CachedImage image : imageMap.values()) + { + image.release(ex); + } + } } -- GitLab