Error calling with java a exported function by eta in a multi-thread environment
Boreaso opened this issue · 4 comments
Description
I want to export a function like this:
foreign export java "@static eta.example.MyClass.sayAnything" sayAnythingEta :: String -> IO ()
sayAnythingEta text = do
putStrLn text
return text
How can I call it in java. Further more, how call I call it in java multi-thread mode.
I try to run it in java multi-thread environment, then I got exceptions:
Exception in thread "pool-1-thread-5" eta.runtime.exception.EtaException: thread blocked indefinitely in an MVar operation
at eta.runtime.stg.Capability.detectMVarDeadlock(Capability.java:703)
at eta.runtime.stg.Capability.idleLoop(Capability.java:690)
at eta.runtime.stg.Capability.blockedLoop(Capability.java:728)
at eta.runtime.stg.Capability.blockedLoop(Capability.java:724)
at eta.runtime.concurrent.Concurrent.takeMVar(Concurrent.java:71)
at base.ghc.io.handle.Internals$$wa2.call(Internals.hs:164)
at base.ghc.io.handle.Internals$a3.applyV(Internals.hs:133)
at eta.runtime.exception.Exception.maskAsyncExceptions(Exception.java:42)
at base.ghc.io.handle.Internals$$wa4.call(Internals.hs:131)
at base.ghc.io.handle.Internals$$wa3.call(Internals.hs:237)
at base.ghc.io.handle.Internals$wantWritableHandle1.call(Internals.hs:227)
at base.ghc.io.handle.Text$hPutStr2.call(Text.hs:544)
at main.Main$$fe_sayHelloEta1.call(Main.hs:10)
at main.Main$$fe_sayHelloEta.call(Main.hs:9)
at main.Main$$fe_sayHelloEta.applyV(Main.hs:9)
at eta.runtime.stg.Closures$EvalIO.enter(Closures.java:177)
at eta.runtime.stg.Capability.schedule(Capability.java:246)
at eta.runtime.stg.Capability.scheduleClosure(Capability.java:202)
at eta.runtime.Runtime.evalIO(Runtime.java:400)
at eta.example.Duckling.sayHello(Unknown Source)
at Main$1.run(Main.java:18)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Please help me!
Hi! I think you have made a typo in your example, i suppose it is:
foreign export java "@static eta.example.MyClass.sayAnything" sayAnythingEta :: String -> IO ()
sayAnythingEta text = do
putStrLn text
return ()
I've just test something similar with lastest etlas and eta and it worked for me.
What do you mean with "java multi-thread environment"?
@jneira Hello, jneira, thank you for your answer. Actually, my program is multi-threaded, I want to call this function in multi-threaded state. Just like this:
public static void main(String[] args) {
ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(100);
long t0 = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
threadPool.execute(new Thread() {
@Override
public void run() {
eta.example.MyClass.sayAnything("Hello eta.");
}
});
}
threadPool.shutdown();
try {
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
long t1 = System.currentTimeMillis();
System.out.println("Time: " + (t1 - t0));
}
How can I achieve this?
I've reproduced the error in a test project: https://github.com/jneira/eta-test/blob/print-ffi/java/Utils.java#L47-L71
It may be a bug in the runtime (maybe @rahulmutt could confirm it)
@rahulmutt Is there any solution to this problem?