On Mon, 2 Mar 2026 18:49:10 GMT, Andy Goryachev <[email protected]> wrote:
>> This change fixes a potential threading issue in RTImage.draw() method in >> WebView. The issue has been theorized back in >> [JDK-8333374](https://bugs.openjdk.org/browse/JDK-8333374), I have not >> managed to figure out a reliable reproducer for it, but the circumstances >> for it to happen are there. >> >> Issue can happen in `RTimage.draw()` method. In 99% of cases >> `RTImage.draw()` will be called only by QuantumRenderer thread (that is >> during regular drawing to a Stage/Scene), however there is also a >> possibility we will call `RTImage.draw()` from a different thread, notably >> with a `PrinterGraphics` object (or in other words, when printing). Then >> there is a chance we will run some of the initial checks in parallel to >> QuantumRenderer thread. I found two places that can be affected - the >> initial checks at the beginning of the method and the `getTexture()` call >> inside the code block responsible for printing. >> >> The first place was fixed by running the checks on the render thread. That >> way we can ensure the render thread will not overwrite the `tex` reference >> from the render thread while the printing thread reads it. To make this >> happen I added `PrismInvoker.callOnRenderThread()` which functions like >> `PrismInvoker.runOnRenderThread()` but with a `Callable<>` instead of a >> `Runnable` object. >> >> Second place can happen if, for some reason, in between previous checks and >> the `getTexture()` call QuantumRenderer will modify or free RTImage's tex >> reference (ex. while pruning the Vram pool) - then the `getTexture()` call >> will return `null` (introduced as NPE prevention from >> [JDK-8333374](https://bugs.openjdk.org/browse/JDK-8333374)) which can cause >> an NPE on QuantumRenderer thread. If that happens, we skip the >> `readPixels()` call which will print an empty RTImage. >> >> I verified these changes on Windows and Linux with our test suite and with >> manual testing via `HelloWebView` and using an old `SimplePrint.java` >> reproducer from [JDK-8118415](https://bugs.openjdk.org/browse/JDK-8118415); >> both regular drawing and printing work as they did. I found simply loading >> `google.com` via both apps works to trigger this draw call multiple times >> (`SimplePrint.java` needed to be adjusted slightly to print out the web page >> instead of predefined HTML code). Test suite completes successfully (there >> were 3 web.test failures on my end but they also happened on master and >> refer to other, unrelated parts of javafx.web) and printing works the same >> way it used to. > > modules/javafx.web/src/main/java/com/sun/javafx/webkit/prism/PrismInvoker.java > line 83: > >> 81: >> 82: private static boolean isOnRenderThread() { >> 83: return >> Thread.currentThread().getName().startsWith("QuantumRenderer"); > > There are two more files with a similar check (`Disposer`, `NGCanvas`) - do > you think there should be a utility method for it? > > Also, is there a better, faster way other than `startsWith()`? Yes I think there probably should be, and there also probably is a better way. I'm also not a big fan of just checking thread's name, especially if we need to change it for any reason. When working on this bug I stumbled upon an ancient enhancement about this - [JDK-8090484](https://bugs.openjdk.org/browse/JDK-8090484) - so it seems there were at least some theorized attempts to improve this part. I would consider it out of scope of this change though and improve this separately (probably as a part of the above issue), it almost certainly would be a larger improvement reaching over to graphics module. **EDIT:** Also, regarding `Disposer` - I suspect you meant the one residing in graphics under `com/sun/prism/impl/Disposer.java`. We seem to have quite a bit of Disposers in the code base... ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/2092#discussion_r2876748217
