leaningtech / cheerpj-applet-runner

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

Threads do not yield or there is no Swing thread #14

Closed ghost closed 5 years ago

ghost commented 5 years ago

Dear Leaningtech,

I am having problems with porting an applet to the Cheerpj. Somehow everything works fine, except for a small issue that the menus get blocked when my application is running, although its running in a separate thread. Is this something by design or an error?

Already the thread states look strange, I get in the normal applet viewer from JDK-8 and this is what I expect (one thread is waiting):

image

ghost commented 5 years ago

On the other hand cheerpj shows me the following result (I don't see some thread waiting, Thread.getState().name()):

image

ghost commented 5 years ago

The consequences are far fetching in as far, I cannot interrupt my application anymore. Normally I can use the menus via the Swing thread, and then I can kill Thread-2 or Thread-3. Here is an example, I simply use the abort menu of my applicaton:

image

This will set a flag in the thread and the interpreter will bail out:

image

ghost commented 5 years ago

With Cheerpj this aint working anymore. Somehow I cannot use the menus when a thread is busy:

image

And then some Chrome Watchdog comes up, and basically destroys my app.

image

ghost commented 5 years ago

I have no clue what heuristics the Watchdog is using to decide that my application is blocked, because it has only a separate thread running, but if there were a Swing thread as is the case in the JDK appletviewer, the application would respond.

I have some suspicion what causes the problem. If there is no Swing thread, it could be Swing thread time is stolen from other threads whenever they yield, like in a Object.wait(). But unfortunately my application threads do not automatically

yield while running, especially if they don't do some Object.wait(). Currently the console does a Object.wait(), which could explain why porting to Cheerpj did work. On the other hand my abort flag is polled via volatile variable while

running. If I wpould knew that my threads need to yield somehow, I could add such a yield instructions to the polling step, making this part of the application work on cheerpj as well. :-( :-)

alexp-sssup commented 5 years ago

I did not have a chance to analyse the actual applet, but in general in the browser there is only 1 thread. Moreover there is no way to preempt the thread to run other code. This means that a thread that does something like while(1) { } in Java can effectively lock the application.

Ignore the reported thread states, they are not synchronized with the actual internal state (that is a bug).

alexp-sssup commented 5 years ago

To clarify, CheerpJ supports multiple Java threads, but they are emulated on top of the single thread that the browser provides. WebWorkers are not equivalent to threads and can't be used to provide this functionality.

ghost commented 5 years ago

Thank you for your quick response, even during pre-christmas time. I could call Thread.yield() in my while(1) { } loop, would this maybe help?

alexp-sssup commented 5 years ago

That would definitely help

ghost commented 5 years ago

There are mixed results now. The while(1) {} loop, I am now calling Thread.yield() after every 10'000 iterations now. Will probably experiment whats the best number here. So I can now indeed kill an infinite loop. Thats great news!

image

But there is a residual problem with Object.wait() while in some of my Prolog threads, it doesn't react on thread.interrupt(); from the pseudo Swing thread of CheerpJ. I will probably open a new issue.