Skip Menu |

This queue is for tickets about the Inline-Java CPAN distribution.

Report information
The Basics
Id: 15748
Status: resolved
Priority: 0/
Queue: Inline-Java

People
Owner: patl [...] cpan.org
Requestors: avatar [...] hot.ee
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.50
Fixed in: 0.50_90



Subject: InlineJavaPerlInterpreter.eval() hangs when called from another thread
InlineJavaPerlInterpreter.eval() hangs if called from a thread different from the one where InlineJavaPerlInterpreter.create() was called. Program reproducing the bug: ======================================================================= import org.perl.inline.java.*; class PerlEvalBug extends Thread { InlineJavaPerlInterpreter pi; PerlEvalBug() throws InlineJavaPerlException, InlineJavaException { pi = InlineJavaPerlInterpreter.create(); // if I call print without newline in the end, // nothing happens until a newline is output later pi.eval("print \"called from the constructor\\n\";"); } public void run() { try // this hangs! {pi.eval("print \"called from the second thread\\n\";");} catch(Exception e) {e.printStackTrace();} } public void call() throws InlineJavaPerlException, InlineJavaException { // this works pi.eval("print \"called from the main thread\\n\";"); } public void finalize() { pi.destroy(); } public static void main(String[] args) throws InlineJavaPerlException, InlineJavaException { PerlEvalBug bug = new PerlEvalBug(); bug.call(); bug.start(); } } ======================================================================= Output (with debug level 10): ======================================================================= [java][2] creating temporary JNI InlineJavaServer [java][2] temporary JNI InlineJavaServer created [java][2] creating InlineJavaPerlInterpreter [java][2] loading shared library /usr/lib/perl5/site_perl/5.8.7/i586-linux-thread-multi/auto/Inline/Java/PerlInterpreter/PerlInterpreter.so [java][2] shared library /usr/lib/perl5/site_perl/5.8.7/i586-linux-thread-multi/auto/Inline/Java/PerlInterpreter/PerlInterpreter.so loaded [java][2] constructing perl interpreter [java][2] perl interpreter constructed called from the constructor called from the main thread (hangs...) ======================================================================= Configuration: ======================================================================= avatar:~/.cpan/build/Inline-Java-0.50 # perl Makefile.PL Welcome to the Inline::Java installation procedure. Default J2SDK for Inline::Java will be '/usr/lib/jvm/java-1.4.2-sun/'. See module documentation for information on how to use a different J2SDK or change this default value. Inline::Java can use a JNI extension that allows the Java Virtual Machine (JVM) to be dynamically linked with Perl instead of running as a separate process. The use of this extension is optional, and building it still allows Inline::Java to run the JVM in the default (separate process) fashion. Note: You need a C compiler to build the extension. Note: You must build the extension if you wish to use PerlNatives or PerlInterpreter. Do you wish to build the JNI extension? [y] y Building JNI extension. 1) /usr/lib/jvm/java-1.4.2-sun/jre/lib/i386/server 2) /usr/lib/jvm/java-1.4.2-sun/jre/lib/i386/client Please select from the above list which 'libjvm.so' to use: [2] 1 Building with: /usr/lib/jvm/java-1.4.2-sun/include/jni.h /usr/lib/jvm/java-1.4.2-sun/include/linux/jni_md.h /usr/lib/jvm/java-1.4.2-sun/jre/lib/i386/server/libjvm.so Note: In order for Inline::Java to use the JNI extension, you will need to use the JNI configuration option or set the PERL_INLINE_JAVA_JNI environment variable to a true value. You will also need to add the following directories to your LD_LIBRARY_PATH environment variable: /usr/lib/jvm/java-1.4.2-sun/jre/lib/i386/server /usr/lib/jvm/java-1.4.2-sun/jre/lib/i386/native_threads /usr/lib/jvm/java-1.4.2-sun/jre/lib/i386 See README.JNI for more information. The PerlNatives extension allows for callbacks to be defined as native Java methods. It is still EXPERIMENTAL and may not build or work properly on all platforms. See documentation for more details. Note: PerlNatives requires J2SDK 1.4 or greater. Do you wish to build the PerlNatives extension? [n] y The PerlInterpreter extension allows Inline::Java to be loaded directly from Java using an embedded Perl interpreter. It is still EXPERIMENTAL and may not build or work properly on all platforms. See documentation for more details. Do you wish to build the PerlInterpreter extension? [n] y Writing Makefile for Inline::Java::PerlNatives Writing Makefile for Inline::Java::PerlInterpreter Writing Makefile for Inline::Java::JNI Writing Makefile for Inline::Java You can continue the installation with the following commands: % make java % make % make test % make install ======================================================================= Regards, Misha
Hi, Since the perl part of Inline::Java is not thread aware, all callbacks from threads other than the thread that created the PerlInterpreter object are queued and dispatched only when the callback loop is in effect. Apply this patch to your code to get an idea of how it works. Patrick *** test.java.ori 2005-11-14 12:37:21.000000000 -0500 --- test.java 2005-11-14 12:40:26.000000000 -0500 *************** *** 16,22 **** { try // this hangs! ! {pi.eval("print \"called from the second thread\\n\";");} catch(Exception e) {e.printStackTrace();} } --- 16,26 ---- { try // this hangs! ! { ! pi.eval("print \"called from the second thread\\n\";"); ! // Return control to the main thread ! pi.StopCallbackLoop(); ! } catch(Exception e) {e.printStackTrace();} } *************** *** 37,41 **** --- 41,49 ---- PerlEvalBug bug = new PerlEvalBug(); bug.call(); bug.start(); + // Callback will hang until we start the callback loop + bug.pi.StartCallbackLoop() ; + // Now this thread is blocked until someone else calls pi.StopCallbackLoop() + bug.call(); } }
BTW, this did not work properly until 0.50_90.
From: avatar [...] hot.ee
Yes, in 0.50_90 your code works perfectly. Thanks a lot! Misha