Skip to content
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

Compatibility with Threads? #131

Open
DrChainsaw opened this issue Oct 6, 2020 · 4 comments
Open

Compatibility with Threads? #131

DrChainsaw opened this issue Oct 6, 2020 · 4 comments

Comments

@DrChainsaw
Copy link

Trying to run jcall in a separate thread kills the julia session:

PS > julia -i -t 8 --project -e "using JavaCall; JavaCall.init()"
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.5.1 (2020-08-25)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> versioninfo()
Julia Version 1.5.1
Commit 697e782ab8 (2020-08-25 20:08 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, skylake)

julia> Threads.@spawn begin
       jlm = @jimport java.lang.Math
       jcall(jlm, "sin", jdouble, (jdouble,), pi/2)
       end

Please submit a bug report with steps to reproduce this fault, and any error messages that follow (in their entirety). Thanks.
Exception: EXCEPTION_ACCESS_VIOLATION at 0x708e3523 -- JVM_ResolveClass at C:\Program Files\Java\jre1.8.0_181\bin\server\jvm.dll (unknown line)
in expression starting at none:0
JVM_ResolveClass at C:\Program Files\Java\jre1.8.0_181\bin\server\jvm.dll (unknown line)
unknown function (ip: AA0000000006F755)
Allocations: 14080219 (Pool: 14076404; Big: 3815); GC: 14
@mkitti
Copy link
Member

mkitti commented Oct 7, 2020

Did you set the environmental variable JULIA_COPY_STACKS=1 ?

@mkitti
Copy link
Member

mkitti commented Oct 7, 2020

Oh, you're on Windows... hmm.

Also we may need to do something with AttachCurrentThread: https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html

@mkitti
Copy link
Member

mkitti commented Oct 7, 2020

I'm going to drop some hints here. Essentially to get this to work, you'll have to tap the lower level JNI interface in JavaCall: JavaCall.JNI.

using JavaCall
JavaCall.init()

# The following is a pointer to the AttachCurrentThread function of the JVM. Use ccall or @ccall to call that.
JavaCall.JNI.jvmfunc[].AttachCurrentThread

The C definition of that is

jint AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args);

The call to that is going to look a lot like
https://github.com/JuliaInterop/JavaCall.jl/blob/master/src/JNI.jl#L145-L146

So something like:

        using JavaCall.JNI
        import JavaCall.JNI: JavaVMInitArgs
        ppenv_this_thread = Ref(Ptr{JNIEnv}(C_NULL))
        ppjvm = JavaCall.JNI.ppjvm
        res < 0 && throw(JavaCall.JNI.JNIError("Unable to initialise Java VM: $(res)"))
        JavaCall.JNI.ppenv[] = ppenv_this_thread[]

When using JavaCall from a new thread:

    empty!(JavaCall._jmc_cache) # You might need to do @jimport anew
    JavaCall.JNI.ppenv[] = ppenv_this_thread[]

There are synchronization issues there. The real solution is to to figure out the new thread specific ppenv into the individual JNI calls:

GetVersion(penv=ppenv[]) =
  ccall(jniref[].GetVersion, jint, (Ptr{JNIEnv},), penv)


DefineClass(name::AnyString, loader::jobject_arg, buf::Array{jbyte,1}, len::Integer, penv=ppenv[]) =
  ccall(jniref[].DefineClass, jclass, (Ptr{JNIEnv}, Cstring, jobject, Ptr{jbyte}, jsize,), penv, name, loader, buf, len)
[...]

@mkitti
Copy link
Member

mkitti commented Oct 12, 2020

I started an experimental branch to push multithreading forwards on Linux / MacOS:
https://github.com/JuliaInterop/JavaCall.jl/tree/multithreading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants