Bug 259833 - Allow flushing asynchronous runnables
Summary: Allow flushing asynchronous runnables
Status: NEW
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.4   Edit
Hardware: All All
: P3 minor (vote)
Target Milestone: ---   Edit
Assignee: Steve Northover CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-12-31 12:43 EST by Ed Kohlwey CLA
Modified: 2019-09-06 16:06 EDT (History)
5 users (show)

See Also:


Attachments
modified Display.java, as recommended in report (147.44 KB, application/octet-stream)
2008-12-31 12:43 EST, Ed Kohlwey CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ed Kohlwey CLA 2008-12-31 12:43:07 EST
Created attachment 121401 [details]
modified Display.java, as recommended in report

org.eclipse.swt.widgets.Display should allow flushing of the asynchronous message queue, since a developer may have the desire (or need) to explicitly process all pending asynchronous messages.

Although the javadoc for the readAndDispatch() method suggests that the method will flush the queue, it actually only processes the first pending message. Its clear that although the functionality was intended, the class just doesn't match the javadoc. The javadoc should be modified to make sure that developers don't mistakenly think this is the case, and the 

This can be accomplished by either:
1. adding a new public method which simply calls Display.runAsyncMessages(true)
2. making Display.runAsyncMessages(.) public.
3. modifying readAndDispatch() so that it runs all asynchronous messages (ie, calls Display.runAsyncMessages(true)).

I've attached a new copy of Display.java that implements option (2).
Comment 1 Remy Suen CLA 2008-12-31 15:16:59 EST
I had a similar need on some unit tests I was writing since we were scheduling some UIJobs and/or asynchronous messages. I ended up putting the test in a loop to constantly check if there were any pending UIJobs and/or calling readAndDispatch() constantly. It wasn't very elegant but oh well...
Comment 2 Ed Kohlwey CLA 2009-01-02 11:20:57 EST
After some additional thought I realized that the display class I included could potentially hang the display in the quite common case that one would continue spawning asynchronous messages as part of a loop. The correct implementation should actually move the current contents of the message queue to a temporary queue, process the temporary queue, and then return true if new messages have been generated in the temporary queue as a result of processing the existing asynchronous messages.
Comment 3 Felipe Heidrich CLA 2009-01-05 10:36:05 EST
can't you call readAndDispatch in a loop ?

while (display.readAndDispatch());

?
Comment 4 Ed Kohlwey CLA 2009-01-05 13:27:06 EST
Unfortunately line 3417

if (OS.PeekMessage (msg, 0, 0, 0, OS.PM_REMOVE)) {

can prevent you from ever processing the asynchronous messages. If you have, for instance, a slider widget and would like to execute asynchronous messages while the user is dragging the slider, the asynchronous messages will not be processed because the body of the if statement (above) always returns true while the slider is selected, preventing the call to runAsyncMessages() from ever executing.
Comment 5 Steve Northover CLA 2009-01-05 14:22:20 EST
Do you have code that shows the slider problem?  By definition, asynchronous messages run when the user interface is idle.
Comment 6 Ed Kohlwey CLA 2009-01-05 14:24:40 EST
Unfortunately I can't release the code that I've generated this issue in, however, I'll see if I can reproduce it when I have some spare time.
Comment 7 Randy Hudson CLA 2009-01-07 12:24:19 EST
See also:
Bug 104851: DCR - Display.postEvent(Runnable)
Bug 103863: Support encapsulation in SWT layout mechanism (talks about "runWithEvent(Runnable)")
Bug 256469: Popup Outline Ctrl+O has non-deterministic behavior (chars are lost)



Perhaps Display could have some new method with this behavior?:
public void readAndDispatchEverything() {
    while ([stuff to do]) {
      [run OS events]
      [run deferred OS events?]
      if (nothing has been done yet)
         [run first async-ed Runnable]
    }
}

It's funny that a single call to readAndDispatch() sometimes sends multiple events, due to deferredEvents. I guess the argument is why not keep going and do more?

Anyway, when someone calls asyncExec(Runnable) from the Display's thread, then what they really want is a way to execute a Runnable after the event currently being dispatched has completed (and sometimes all other pending OS events). The thread is already awake, so posting a bogus OS.WM_NULL Message wouldn't be necessary, which might fix 256469. Instead, Display could just push the Runnable onto its "asyncQueue", and not worry about waking the already awake thread.
Comment 8 Eclipse Webmaster CLA 2019-09-06 16:06:20 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.