-
Notifications
You must be signed in to change notification settings - Fork 190
Let Display#sleep() react to thread interruption #3061
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Let Display#sleep() react to thread interruption #3061
Conversation
1d16fbe to
a919984
Compare
|
I did not find any OS API method that allows to wait for a message until a timeout occurs instead of the inifinitely blocking to boolean messageReceived = false;
while (!messageReceived && !thread.isInterrupted()) {
messageReceived = OS.PeekMessage (msg, 0, 0, 0, OS.PM_NOREMOVE);
try {
Thread.sleep(20);
} catch (InterruptedException e) {
thread.interrupt();
break;
}
}At least the test locally passes with it. |
Thanks for looking into it, the problem is that it will immediately return but always with 20ms delay (what might be too much), I think we can't do any better then on windows for the moment. |
|
On win32 I think you can leave in waitmessage, but always queue a 50ms timer so that you never wait more than 50ms. I don't think it is particularly trivial to do that though as ideally you want the sleep method to handle that particular timer going off locally rather than waiting for the main event loop to handle it. The gtk side looks good to me on code inspection, but I don't know the implications of changing return value, for example in cases where there are two conditions that caused loop to exit, should it still return true. I don't see any real uses of the sleep return value so far in the code base, so not enough of an issue for me to want to spend more time on it. I guess its too bad we can't throw InterruptedException as that would be a very disruptive API change. |
That's a nice idea but you would indeed need to process the timer event inside the I shortly experimented with a simple timer and a timer callback and both of them do not seem to be processed by the event queue afterwards if the timer is killed after it elapsed (and thus made long wakeupId = OS.SetTimer(0, 0, 50, 0);
boolean result = OS.WaitMessage();
OS.KillTimer(0, wakeupId);long timer = WakeupMessage.sendAfter(50);
boolean result = OS.WaitMessage();
OS.KillTimer(0, timer);
...
private static class WakeupMessage {
private final Callback osCallback;
private WakeupMessage() {
// Has to have TIMERPROC signature, see https://learn.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-timerproc
osCallback = new Callback(this, "run", void.class, new Type[] { int.class, int.class, int.class, int.class} );
}
@SuppressWarnings("unused") // Executed as callback method referenced by signature description
public void run(int hwnd, int msg , int idEvent, int dwTime) {
OS.KillTimer(hwnd, idEvent);
System.out.println("lalala");
osCallback.dispose();
}
static long sendAfter(int millis) {
try {
WakeupMessage fakeMessage = new WakeupMessage();
return OS.SetTimer(0, 0, millis, fakeMessage.osCallback.getAddress());
} catch (SWTError error) {
}
return 0;
}
}I now found that is the OS method |
|
I just wanted to mention that I don't want to overcomplicate the matter here and if its not working on windows it is fine for me |
Fix #3059
I did not found a good way on Windows (@HeikoKlare ?) and would like to get feedback on the MacOS part, maybe @akurtakov / @jonahgraham can take a peek on the gtk side?