Could you please elaborate why the implementation of sun.awt.X11.XTextAreaPeer#repaintText <https://github.com/openjdk/jdk/blob/8ec6b8de3bb3d7aeebdcb45d761b18cce3bab75e/src/java.desktop/unix/classes/sun/awt/X11/XTextAreaPeer.java#L258> is *correct*?
Also let me add more context to the question: With one of the X11 regression tests on our infrastructure, we're struggling with a deadlock when the test invokes the public AWT's API method *java.awt.TextComponent#setText* *outside of EDT* while EDT is dispatching an input event. Sometimes, it leads to the situation when EDT obtains the AWT tree lock and is trying to lock the instance of *java.awt.TextComponent* while the call of *java.awt.TextComponent#setText* (which is on a different thread), in opposite, locks self and is trying to obtain the AWT tree lock. Here is a classical deadlock. Before this discussion, I was strongly convinced that AWT guarantees thread-safety in the sense that it's safe to invoke any of its (not Swing's) public UI operations on any thread. However I can't find any proof (or refutation) about this in the AWT documentation now. Is it wrong? If there's such a guarantee, let's take a look at the case described above again: * The test seems correctly written, although it invokes *java.awt.TextComponent#setText* outside of EDT. * But it internally leads to a call of sun.awt.X11.XTextAreaPeer#repaintText <https://github.com/openjdk/jdk/blob/8ec6b8de3bb3d7aeebdcb45d761b18cce3bab75e/src/java.desktop/unix/classes/sun/awt/X11/XTextAreaPeer.java#L258> which, in this case, calls Swing API outside of EDT, which is definitely incorrect. Thus we must fix the implementation of XTextAreaPeer#repaintText, not the test, right? *Summarizing all the questions:* * Does AWT (still) guarantee thread-safety? The question is about AWT only, excluding Swing. * If it does, the implementation of sun.awt.X11.XTextAreaPeer#repaintText <https://github.com/openjdk/jdk/blob/8ec6b8de3bb3d7aeebdcb45d761b18cce3bab75e/src/java.desktop/unix/classes/sun/awt/X11/XTextAreaPeer.java#L258> doesn't take this into account, so it must be fixed, mustn't it? Thanks in advance! Best regards, Nikita Provotorov On Fri, Nov 17, 2023 at 7:42 PM Philip Race <[email protected]> wrote: > No, the code that calls setText() is where it starts. > > -phil. > > On 11/17/23 2:51 AM, Nikita Provotorov wrote: > > Thanks for the response! > However I'd like to clarify: is it correct to say that the current > implementation of sun.awt.X11.XTextAreaPeer#repaintText > <https://github.com/openjdk/jdk/blob/8ec6b8de3bb3d7aeebdcb45d761b18cce3bab75e/src/java.desktop/unix/classes/sun/awt/X11/XTextAreaPeer.java#L258> > is > wrong because it doesn't make sure if > *javax.swing.JComponent#paintImmediately* is called on EDT only (e.g. via > *SwingUtilities#invokeLater*)? > > Best regards, > Nikita Provotorov > > > On Thu, Nov 16, 2023 at 9:30 PM Philip Race <[email protected]> > wrote: > >> Because (like in this case), an AWT component might actually be >> implemented using Swing, >> the recommendation is to treat AWT components like Swing, and update them >> only on the EDT. >> >> -phil. >> >> On 11/15/23 4:01 PM, Nikita Provotorov wrote: >> >> Hello! >> I've discovered that on X11 platforms a call >> of java.awt.TextComponent#setText can lead to a call >> of javax.swing.JComponent#paintImmediately(java.awt.Rectangle) on the same >> thread. >> Since java.awt.TextComponent#setText is allowed to be called on any >> thread (because it's AWT, not Swing), JComponent#paintImmediately may be >> called outside of EDT. Is this a valid behavior? >> >> The following stacktrace shows how exactly this can happen: >> >>> at javax.swing.JComponent.paintImmediately >>> at sun.awt.X11.XTextAreaPeer$AWTTextArea.repaintNow >>> at sun.awt.X11.XTextAreaPeer.repaintText >>> at sun.awt.X11.XTextAreaPeer.setText >>> at java.awt.TextComponent.setText >> >> >> Best regards, >> Nikita Provotorov >> >> >> >
