Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5231,13 +5231,19 @@ public boolean sleep () {
try {
addPool();
allowTimers = runAsyncMessages = false;
NSRunLoop.currentRunLoop().runMode(OS.NSDefaultRunLoopMode, NSDate.distantFuture());
/*
* Use a timeout-based approach to allow checking for thread interruption.
* Sleep for a maximum of 50 milliseconds at a time, similar to GTK.
*/
do {
NSRunLoop.currentRunLoop().runMode(OS.NSDefaultRunLoopMode, NSDate.dateWithTimeIntervalSinceNow(0.05));
} while (synchronizer.isMessagesEmpty() && !thread.isInterrupted());
allowTimers = runAsyncMessages = true;
} finally {
removePool();
}
sendPostExternalEventDispatchEvent ();
return true;
return !thread.isInterrupted();
}

int sourceProc (int info) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5633,11 +5633,11 @@ public boolean sleep () {
OS.g_main_context_check (context, max_priority [0], fds, nfds);
OS.g_main_context_release (context);
}
} while (!result && synchronizer.isMessagesEmpty() && !wake);
} while (!result && synchronizer.isMessagesEmpty() && !wake && !thread.isInterrupted());
wake = false;
if (!GTK.GTK4) GDK.gdk_threads_enter ();
sendPostExternalEventDispatchEvent ();
return true;
return !thread.isInterrupted();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,47 @@ public void run() {
}
}

@Test
@DisabledOnOs(value = org.junit.jupiter.api.condition.OS.WINDOWS, disabledReason = "Windows uses WaitMessage() which does not support timeout-based interruption checking")
public void test_sleep_respondToInterrupt() {
final Display display = new Display();
Shell shell = new Shell(display);
try {
shell.open();
Thread uiThread = Thread.currentThread();

// Start a thread that will interrupt the UI thread after 1 second
Thread interrupter = new Thread(() -> {
try {
Thread.sleep(1000);
uiThread.interrupt();
} catch (InterruptedException e) {
// Ignore
}
});
interrupter.start();

// Event loop with timeout to prevent hanging if sleep() never responds to interrupt
long deadline = System.currentTimeMillis() + 5000;
while (!shell.isDisposed() && System.currentTimeMillis() < deadline) {
if (!display.readAndDispatch()) {
boolean hasMoreWork = display.sleep();
// When interrupted, sleep() returns false and interrupt flag is preserved
if (!hasMoreWork && uiThread.isInterrupted()) {
// Success! Clean up and return
Thread.interrupted(); // clear flag
return;
}
}
}
// If we get here, the test failed
fail("sleep() did not respond to thread interruption within timeout");
} finally {
shell.dispose();
display.dispose();
}
}

@Test
public void test_syncExecLjava_lang_Runnable() {
final Display display = new Display();
Expand Down
Loading