Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » scout » Multi-threading issue when using Scout Swing client
Multi-threading issue when using Scout Swing client [message #1012876] Fri, 22 February 2013 11:17 Go to next message
Ken Lee is currently offline Ken Lee
Messages: 97
Registered: March 2012
Member
I analyzed the bug 401191 [1] and came to the conclusion that there might be a potential multi-threading problem in Scout when using the Swing client.
Before I make any changes I'd like to discuss this issue.

Problem description:
As described in the bug 401191, there's a simple form (FruitForm) containing a smartfield where 3 values (fruits) are selectable (banana, pineapple, apple). There's also a context menu (TestMenu) on the smartfield that opens an new empty form (TestForm with an OK and Cancel button).

In the execAction() method of the TestMenu, the value of the smartfield will be set to "apple" after the TestForm has been closed.
In the execChangedValue() method of the smartfield, there's a Thread.sleep(2000) execution to show the wrong behavior.

For example, given that the user selects the fruit "banana" and then opens and closes the Testform via context-menu, the expected result should be "apple" since this is set in the execAction() after testForm.waitFor(). The value "apple" is going to be set, but will be reset to "banana" afterwards.

Analysis:
The reset operation to "banana" is done in the GUI thread while the model thread sets the value to "apple". The GUI thread reads the old value in the UI text field because the change from model has not been propagated to the UI at that point.

After the TestForm gets closed, we got the following sequences of action:


  1. [Model thread]: Set value to "apple" in execAction() in the model.
  2. [Model thread]: Thread is going to sleep in execChangedValue(). The value has not been propagated to the UI.
  3. [GUI thread]: Calls the input verifier on the smartfield upon a WindowClosed event (SwingScoutDialog.P_SwingWindowListener.windowClosed())
  4. [GUI thread]: Reads value in the UI field which is still "banana".
  5. [GUI thread]: Invokes and joins on the model thread to set the value "banana" in the model.
  6. [Model thread]: Wakes up and finishes execChangedValue() method and propogates its new value to the UI.
  7. [Model thread]: Executes the queued job by the GUI thread. This causes the value to be changed from "apple" to "banana" in the model which will be propagated to the UI.
  8. [GUI thread]: Handles the first propagation of the changed value event. Sets "apple" in the UI.
  9. [GUI thread]: Handles the second propagation of the changed value event. Sets "banana" in the UI.
  10. The final value is therefore "banana".


The reason for this multi-threading issue is because of the input verifier that is triggered when the TestForm gets closed.

SwingScoutDialog
private class P_SwingWindowListener extends WindowAdapter {
 ...
  @Override
  public void windowClosed(WindowEvent e) {
    Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
    if (focusOwner != null && focusOwner instanceof JComponent && ((JComponent) focusOwner).getInputVerifier() != null) {
      ((JComponent) focusOwner).getInputVerifier().verify((JComponent) focusOwner);
    }
    fireSwingScoutViewEvent(new SwingScoutViewEvent(SwingScoutDialog.this, SwingScoutViewEvent.TYPE_CLOSED));
  }
}


When the TestForm is closed, the Keyboard focus is on the smartfield of the FruitForm.
(As a remark: If the user initially selects the value "banana" and presses TAB for example such that the focus is NOT on the smartfield, the following action sequences leads to the expected result!).

The main question is why the input must be verified upon a WindowClosed event?. The component having the keyboard focus will never be on the dialog that was closed so the verification will be executed on probably focused component on the previous form. Are there really use cases where the input verification has to be done upon a WindowClosed event?
It makes absolutely sense to verify the input upon a WindowClosing event (this is triggered for example if you close the TestForm by clicking the "X" button to close the window) but in my opinion the WindowClosed event should not trigger an input verification.
If the input verification could be removed upon a WindowClosed event, then the multi-threading issue is solved.
Otherwise, we need to think over the threading concept when values are verified, changed and propagated.

Some technical remarks:

  • The Thread.sleep() in the execChangedValue() method causes a context switch from the Model thread to the GUI thread. However, since execChangedValue() is not atomic such a context switch could always happen even in a single-core architecture.
  • execChangedValue() is executed inside the setValue() method of AbstractValueField. Synchronizing the Model and GUI thread using a critical section does not solve the problem either because the GUI thread will execute the input verification job before the the propagation of the changed values. That means that the input verification will always read the old value.


[1] https://bugs.eclipse.org/bugs/show_bug.cgi?id=401191
Re: Multi-threading issue when using Scout Swing client [message #1012921 is a reply to message #1012876] Fri, 22 February 2013 13:11 Go to previous messageGo to next message
Ken Lee is currently offline Ken Lee
Messages: 97
Registered: March 2012
Member
Another technical remark:
When using the Swing client with Java 6, the outcome is the expected one. The reason for that is the method call to KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() which returns null so that no verification is triggered.
However, I'm not sure if the focus owner will always return null when called inside the windowClosed() handling in a dialog. So we are back at my main question Rolling Eyes


Re: Multi-threading issue when using Scout Swing client [message #1015345 is a reply to message #1012921] Thu, 28 February 2013 09:55 Go to previous message
Ken Lee is currently offline Ken Lee
Messages: 97
Registered: March 2012
Member
Beat gave me a good hint to this problem. In the old smartfield implementations the pop-up form used to be modal. This could be the reason why the input verifier is triggered upon a WindowClosed event. Nowadays, synchronization between UI and model is done over some jobs.

My proposed solution is to introduce a property that can be set in the config.ini file to activate/deactivate the input verification since we don't know if this can really be removed.
By default the input verifier is not triggered anymore when receiving a WindowClosed event. If the property is explicitly set to true, input verification will be executed as before.
Previous Topic:httpexception 500 internal server error
Next Topic:Layout Management
Goto Forum:
  


Current Time: Fri Oct 24 09:37:33 GMT 2014

Powered by FUDForum. Page generated in 0.02889 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software