RFR: 8335468: [XWayland] JavaFX hangs when calling java.awt.Robot.getPixelColor

Alexander Zvegintsev azvegint at openjdk.org
Fri Nov 15 02:13:04 UTC 2024


This is a linux only issue and this PR contains two parts(they are available as two separate commits):

a. [8335468](https://bugs.openjdk.org/browse/JDK-8335468): [XWayland] JavaFX hangs when calling java.awt.Robot.getPixelColor
b. [8335469](https://bugs.openjdk.org/browse/JDK-8335469): [XWayland] crash when an AWT ScreenCast session overlaps with an FX ScreenCast session

`b.` is not reproducible without `a.` being fixed.

More about both cases:

------
`a.`

Previously we used a blocking [`g_main_context_iteration`](https://docs.gtk.org/glib/method.MainContext.iteration.html) call, this prevents normal execution if there is a GTK main loop running in the process.

Now we are handling 3 cases:
1. If there is no GTK main loop running
_Example: just a JDK only application._
In this case we call `g_main_context_iteration(NULL, TRUE)` as before (when [`gtk_main_level() == 0`](https://docs.gtk.org/gtk3/func.main_level.html)).

2. If there is a GTK main loop running, but we are not requesting pixels on its thread
_Example: application showing a `JFXPanel`, but are requesting pixels from a main thread._
Now we are not trying to block thread: `g_main_context_iteration(NULL, FALSE)` (when `gtk_main_level() > 0`) .

3. If there is a GTK main loop running, and we are requesting pixels on its thread
_Example: a JavaFX application trying to get pixels on the FX application thread, e.g. from a button callback._
Now we go nested with [`gtk_main()`](https://docs.gtk.org/gtk3/func.main.html)

[jdk commit](https://github.com/openjdk/jdk/pull/22131/commits/f439eb9739cf53ed6196a98062032b3045dd1cbe)

------

`b.`

After fixing `a.` [the crash](https://bugs.openjdk.org/browse/JDK-8335469) appears:

Internally the ScreenCast session keeps open for 2s (both JDK and JFX, and their implementations are almost identical).
This is to reduce overhead in case of frequent consecutive screen captures.

When we perform a [cleanup](https://github.com/openjdk/jdk/blob/db56266ad164b4ecae59451dc0a832097dbfbd8e/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c#L91) to close the session, we internally call [`pw_deinit`](https://docs.pipewire.org/group__pw__pipewire.html#gafa6045cd7391b467af4575c6752d6c4e).

It becomes a problem if these sessions overlap in time, so that the second session cleanup crashes when it tries to call pipewire functions without initializing the pipewire system by  [`pw_init`](https://docs.pipewire.org/group__pw__pipewire.html#ga06c879b2d800579f4724109054368d99) (please note that `This function can be called multiple times.`).

So the solution is not to call `pw_deinit` because we don't really need it, and it needs to be applied to both the JDK and JavaFX.

[jdk commit](https://github.com/openjdk/jdk/pull/22131/commits/19956fda202269e92ec70670bc88c8d3c7accf73) / [jfx commit](https://github.com/openjdk/jfx/pull/1639/commits/dba8a8871a38831d0a0da697a2be41f0c240c8f0)
[FX review counterpart](https://github.com/openjdk/jfx/pull/1639)

------

Testing in different scenarios looks good.

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

Commit messages:
 - 8335469: [XWayland] crash when an AWT ScreenCast session overlaps with an FX ScreenCast session
 - 8335468: [XWayland] JavaFX hangs when calling java.awt.Robot.getPixelColor

Changes: https://git.openjdk.org/jdk/pull/22131/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=22131&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8335468
  Stats: 67 lines in 6 files changed: 47 ins; 12 del; 8 mod
  Patch: https://git.openjdk.org/jdk/pull/22131.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/22131/head:pull/22131

PR: https://git.openjdk.org/jdk/pull/22131


More information about the client-libs-dev mailing list