leaningtech / cheerpj-applet-runner

CheerpJ Applet Runner - Chrome Extension to Enable Java Applets
http://www.leaningtech.com/cheerpj
57 stars 3 forks source link

About thread interrupt #18

Closed ghost closed 5 years ago

ghost commented 5 years ago

Dear Leaningtech,

Could already figure out how to work around this issue https://github.com/leaningtech/cheerpj-appletrunner/issues/14 but there is a residual issue. I now tried to verify that monitors are not interruptible. Pickeled my code as follows to show the problem:

Thread that gets repeatedly called and might get interrupted:

            while (ts.getBufferSize() == 0) {
                try {
                    ts.wait(1000);
                    System.err.println("timeout or notify");
                } catch (InterruptedException x) {
                    System.err.println("interrupt exception");
                    throw new InterruptedIOException();
                }
            }
ghost commented 5 years ago

Here is what happens in the original JVM when I interrupt the thread:

timeout or notify
timeout or notify
timeout or notify
interrupt exception
timeout or notify
timeout or notify
timeout or notify

And this is what CheerpJ gives me at the moment:

timeout or notify
timeout or notify
timeout or notify
timeout or notify
timeout or notify
timeout or notify

I also tried to query Thread.interrupted(), but the flag gets not set.

alexp-sssup commented 5 years ago

Can you provide a fully self contained test case?

ghost commented 5 years ago

I see it in the applet, but this might not be a stripped down test case. But in the applet it is seen as follows, I interrupt the reading of a query, this is in JDK 1.8:

image

And the reading of a query gets interrrupted (a new ?-, I know this looks a little strange, but this is only an example, the interrupt is also used for other stuff):

image

ghost commented 5 years ago

With CheerpJ, since no InterruptedException is thrown, it simply does nothing, after using the Run | Abort menu item:

unbenannt

http://www.jekejeke.ch/asterix/page.html

But I know that the interrupt was delivered. Since a separate custom flag was also set by the menu item. As a workaround I could poll this separate custom flag, and not rely on interrupt at all.

I guess I would need to replace every Object.wait() by Object.wait(1000) as in the example code above, and further have some little extra code that navigates to my separate custom flag and checks it.

ghost commented 5 years ago

I could find a polling work-around, as follows:

            while (ts.getBufferSize() == 0) {
                try {
                    if (AbstractLivestock.liveGetSignal(Thread.currentThread()) != null)
                        throw new InterruptedException();
                    ts.wait(1000);
                } catch (InterruptedException x) {
                    throw new InterruptedIOException();
                }
            }

Which works fine, as can be seen here:

unbenannt

This solves a lot of my problems, since I also use interrupt to close tabs etc.. Woa! But I now need to apply the same workaround also elsewhere, for example in my queue library etc.. everywhere where Object.wait() is used, a prospective workaround could be the above pattern.

alexp-sssup commented 5 years ago

This problem should be fixed in CheerpJ Applet Runner 6.7