deadlock in loading images

XMLWordPrintable

    • Type: Bug
    • Resolution: Fixed
    • Priority: P4
    • 5.0
    • Affects Version/s: 1.4.1
    • Component/s: client-libs
    • 2d
    • tiger
    • generic
    • solaris_2.6

      Apple sometimes hits the deadlock below while running the JCK in -Xcomp mode on a dual processor system during the JCK 1.4 api/java_awt/Toolkit/index.html#Cursor testcase.

      The testcase fetches different images simultaneously using Toolkit.getImage(). This is a classic example of lock inversion deadlock.

      Here is the relevant information:
      FOUND A JAVA LEVEL DEADLOCK:
      ----------------------------
      "Image Fetcher 3":
         waiting to lock monitor 0x4bc44 (object 0x680067b0, a
      sun.awt.image.GifImageDecoder),
         which is locked by "Image Fetcher 1"
      "Image Fetcher 1":
         waiting to lock monitor 0x4bc1c (object 0x682dbeb8, a
      sun.awt.image.URLImageSource),
         which is locked by "Image Fetcher 3"

      Here are the two threads in question:

      Java Stack for "Image Fetcher 1":
      ==========
      at
      sun.awt.image.InputStreamImageSource.isConsumer(InputStreamImageSource.j
      ava:111) <----waits on InputStreamImageSource lock
      at sun.awt.image.PixelStore.replay(PixelStore.java:152)
      at sun.awt.image.PixelStore.replay(PixelStore.java:144)
      at
      sun.awt.image.GifImageDecoder.catchupConsumer(GifImageDecoder.java:66)
      <---- gets ImageDecoder lock
      at
      sun.awt.image.InputStreamImageSource.latchConsumers(InputStreamImageSour
      ce.java:372)
      at sun.awt.image.ImageDecoder.setPixels(ImageDecoder.java:102)
      at sun.awt.image.GifImageDecoder.sendPixels(GifImageDecoder.java:458)
      at sun.awt.image.GifImageDecoder.parseImage(Native Method)
      at sun.awt.image.GifImageDecoder.readImage(GifImageDecoder.java:571)
      at sun.awt.image.GifImageDecoder.produceImage(GifImageDecoder.java:218)
      at
      sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java
      :252)
      at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:167)
      at sun.awt.image.ImageFetcher.run(ImageFetcher.java:135)

      GifImageDecoder.java:66
           public synchronized boolean catchupConsumer(InputStreamImageSource
      src, ImageConsumer ic)
           {
               return (cancatchup && (store == null || store.replay(src, ic)));
           }

      InputStreamImageSource.java:111
           public synchronized boolean isConsumer(ImageConsumer ic) {
               for (ImageDecoder id = decoders; id != null; id = id.next) {
                   if (id.isConsumer(ic)) {
                       return true;
                   }
               }
               return ImageConsumerQueue.isConsumer(consumers, ic);
           }

      Java Stack for "Image Fetcher 3":
      ==========
      at sun.awt.image.ImageDecoder.close(ImageDecoder.java:161) <----waits
      on ImageDecoder lock
      at sun.awt.image.ImageDecoder.abort(ImageDecoder.java:150)
      at sun.awt.image.ImageDecoder.removeConsumer(ImageDecoder.java:36)
      at
      sun.awt.image.InputStreamImageSource.removeConsumer(InputStreamImageSour
      ce.java:135) <---- gets InputStreamImageSource lock
      at
      java.awt.image.FilteredImageSource.removeConsumer(FilteredImageSource.java:87)
      at java.awt.image.PixelGrabber.imageComplete(PixelGrabber.java:599)
      at java.awt.image.ImageFilter.imageComplete(ImageFilter.java:168)
      at sun.awt.image.PixelStore.replay(PixelStore.java:224)
      at sun.awt.image.PixelStore.replay(PixelStore.java:144)
      at sun.awt.image.InputStreamImageSource.updateFromStore(InputStreamImageSou rce.java:286)
      at
      sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java
      :239)
      at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:167)
      at sun.awt.image.ImageFetcher.run(ImageFetcher.java:135)

      InputStreamImageSource.java:135
           public synchronized void removeConsumer(ImageConsumer ic) {
               for (ImageDecoder id = decoders; id != null; id = id.next) {
                   id.removeConsumer(ic);
               }
               consumers = ImageConsumerQueue.removeConsumer(consumers, ic,
      false);
               if (consumers == null) {
                   stopProduction();
               }
           }

      ImageDecoder.java:161
           public synchronized void close() {
               if (input != null) {
                   try {
                       input.close();
                   } catch (IOException e) {
                   }
               }
           }

            Assignee:
            Dmitri Trembovetski (Inactive)
            Reporter:
            Kirill Soshalskiy (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: