6818960: ImageFetcher ( MediaTracker) Thread leak
authorbae
Wed, 09 Feb 2011 22:24:42 +0300
changeset 8353 2834083cdb2c
parent 8352 956b231fed62
child 8354 3189b5e18f80
6818960: ImageFetcher ( MediaTracker) Thread leak Reviewed-by: igor, prr
jdk/src/share/classes/sun/awt/image/ImageFetcher.java
jdk/src/share/classes/sun/awt/image/InputStreamImageSource.java
--- a/jdk/src/share/classes/sun/awt/image/ImageFetcher.java	Tue Feb 08 14:24:14 2011 -0800
+++ b/jdk/src/share/classes/sun/awt/image/ImageFetcher.java	Wed Feb 09 22:24:42 2011 +0300
@@ -61,8 +61,10 @@
     /**
       * Adds an ImageFetchable to the queue of items to fetch.  Instantiates
       * a new ImageFetcher if it's reasonable to do so.
+      * If there is no available fetcher to process an ImageFetchable, then
+      * reports failure to caller.
       */
-    public static void add(ImageFetchable src) {
+    public static boolean add(ImageFetchable src) {
         final FetcherInfo info = FetcherInfo.getFetcherInfo();
         synchronized(info.waitList) {
             if (!info.waitList.contains(src)) {
@@ -71,9 +73,23 @@
                             info.numFetchers < info.fetchers.length) {
                     createFetchers(info);
                 }
-                info.waitList.notify();
+                /* Creation of new fetcher may fail due to high vm load
+                 * or some other reason.
+                 * If there is already exist, but busy, fetcher, we leave
+                 * the src in queue (it will be handled by existing
+                 * fetcher later).
+                 * Otherwise, we report failure: there is no fetcher
+                 * to handle the src.
+                 */
+                if (info.numFetchers > 0) {
+                    info.waitList.notify();
+                } else {
+                    info.waitList.removeElement(src);
+                    return false;
+                }
             }
         }
+        return true;
     }
 
     /**
@@ -291,11 +307,15 @@
          public Object run() {
              for (int i = 0; i < info.fetchers.length; i++) {
                if (info.fetchers[i] == null) {
-                   info.fetchers[i] = new ImageFetcher(
+                   ImageFetcher f = new ImageFetcher(
                            fetcherGroup, i);
-                   info.fetchers[i].start();
-                   info.numFetchers++;
-                   break;
+                   try {
+                       f.start();
+                       info.fetchers[i] = f;
+                       info.numFetchers++;
+                       break;
+                   } catch (Error e) {
+                   }
                }
              }
           return null;
--- a/jdk/src/share/classes/sun/awt/image/InputStreamImageSource.java	Tue Feb 08 14:24:14 2011 -0800
+++ b/jdk/src/share/classes/sun/awt/image/InputStreamImageSource.java	Wed Feb 09 22:24:42 2011 +0300
@@ -164,8 +164,13 @@
 
     private synchronized void startProduction() {
         if (!awaitingFetch) {
-            ImageFetcher.add(this);
-            awaitingFetch = true;
+            if (ImageFetcher.add(this)) {
+                awaitingFetch = true;
+            } else {
+                ImageConsumerQueue cq = consumers;
+                consumers = null;
+                errorAllConsumers(cq, false);
+            }
         }
     }