RFR: 8370141: [macOS] Crash after PrinterJob ends when Graphics.create() is used. [v2]

Phil Race prr at openjdk.org
Fri Oct 24 18:35:28 UTC 2025


On Tue, 21 Oct 2025 21:39:05 GMT, Sergey Bylokhov <serb at openjdk.org> wrote:

>> delegate.dispose just replaces the reference in the graphics with a NullSurfaceData.
>> There's no synchronization needed.
>
> multi-threaded version of the `PrintJobAfterEndTest` always crashed for me even with a patch:
> 
> 
> import java.awt.Frame;
> import java.awt.Graphics;
> import java.awt.JobAttributes;
> import java.awt.JobAttributes.DialogType;
> import java.awt.PageAttributes;
> import java.awt.PrintJob;
> import java.awt.Toolkit;
> import java.util.concurrent.CountDownLatch;
> 
> public final class MTPrintJobAfterEndTest {
> 
>     public static void main(String[] args) throws InterruptedException {
> 
>         JobAttributes jobAttributes = new JobAttributes();
>         jobAttributes.setDialog(DialogType.NONE);
>         PageAttributes pageAttributes = new PageAttributes();
>         Frame f = new Frame();
>         Toolkit toolkit = f.getToolkit();
> 
>         for (int i = 0; i < 1000; i++) {
>             PrintJob job = toolkit.getPrintJob(f, "Crash Test",jobAttributes,
>                                                pageAttributes);
>             if (job != null) {
>                 Graphics g = job.getGraphics();
>                 CountDownLatch latch = new CountDownLatch(1);
>                 
>                 Thread endThread = new Thread(() -> {
>                     try {
>                         latch.await();
>                         job.end();
>                     } catch (Throwable ignore) {}
>                 });
>                 
>                 Thread drawThread = new Thread(() -> {
>                     try {
>                         latch.await();
>                         g.drawLine(0, 100, 200, 100);
>                     } catch (Throwable ignore) {}
>                 });
>                 
>                 endThread.start();
>                 drawThread.start();
>                 latch.countDown();
>                 
>                 endThread.join();
>                 drawThread.join();
>             }
>         }
>     }
> }

I have updated the fix making the SurfaceData methods synchronized and wrapped the disposed with synchronizing on the same surface.
So now it is not possible to have the state changed whilst executing any of these methods.
This fixes the MT crash. I've updated both the tests to use MT and also added more primitives being drawn.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27905#discussion_r2461599854


More information about the client-libs-dev mailing list