<AWT Dev> RFR: 8196100: javax/swing/text/JTextComponent/5074573/bug5074573.java fails

Sergey Bylokhov serb at openjdk.java.net
Wed Nov 25 00:52:09 UTC 2020


Here is a fix for one of the annoying bug, which causes random test failures in the CI.

We have a method Robot.waitForIdle(), which supposed to wait until the java and the native queue stabilized. The common use case is to click on the button or show the window, and call waitForIdle() which will wait until the native event will be dispatched by the X11/Windows/macOS as well as followed Java event(paint/focus/etc event) will be dispatched to the EDT.

Currently, it is implemented in this way:
  1. Flush the EventQueue, so all old events will be posted to EDT.
  2. Flush the native event queue, by posting the native event.
  3. Flush the EDT, by posting a java event.
  4. If some events(unrelated to waitForIdle machinery) were dispatched on steps 2. or 3. then repeat since step 1.

It is implemented that they because the native events caused by the OS usually generate the java events, and the java events may generate native events. So we have to wait for both queues (java/native).

But it has the next disadvantages:
 - It is implemented as a busy loop, which does not give a chance for the application to proceed further since it blocks 3 threads EDT/native toolkit thread like appkit/main thread.
- It throws the InfiniteLoop exception if the number of attempts is bigger than 20. And this limitation is too small because some tests generate much more events during startup.
 - Note that the timeout value for the realSync method is 10 seconds, and it was assumed that this method will not be executed longer, but it uses this timeout for all events flushing which can lead up to 600 seconds (20 iters * 3  calls * 10 seconds).


The fix:
 - Add a small delay to the method, so the app can do something useful when waitForIdle() is called
 - The timeout=10 second is taken care of, we calculate the "end" time and exits if it is exceeded
 - The maximum number of attempts is increased to 100 and InfiniteLoop is removed.

Note that I have made one additional change to the new realSync implementation. At the beginning of the method I call:
 EventQueue.invokeAndWait(() -> {/*dummy implementation*/});
It is needed to be sure that we flush the first event on EDT even if we spend more time than 10 seconds.

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

Commit messages:
 - Update SunToolkit.java
 - The new tests
 - Do not use shared state
 - Update SunToolkit.java
 - realSync too slow
 - Update bug5074573.java
 - Test update
 - Initial fix

Changes: https://git.openjdk.java.net/jdk/pull/1424/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1424&range=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8196100
  Stats: 242 lines in 9 files changed: 192 ins; 20 del; 30 mod
  Patch: https://git.openjdk.java.net/jdk/pull/1424.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/1424/head:pull/1424

PR: https://git.openjdk.java.net/jdk/pull/1424


More information about the awt-dev mailing list