ScriptingContainer.put() does not always work (race condition?)
---------------------------------------------------------------

                 Key: JRUBY-5635
                 URL: http://jira.codehaus.org/browse/JRUBY-5635
             Project: JRuby
          Issue Type: Bug
          Components: Embedding
    Affects Versions: JRuby 1.6
         Environment: OS X 10.6.6 (64-bit) and java 1.6.0_24
            Reporter: Adam Murray


BACKGROUND
Even though JRuby 1.6 performance is supposedly better, I have found the 
startup time for ScriptingContainer to be noticeably slower than JRuby 1.5.6, 
especially when constructing a pool of ScriptingContainers at once. While 
investigating this with some timing tests, I discovered more serious issues.


ISSUE SUMMARY
When instantiating a new ScriptingContainer and immediately calling put() to 
set a variable, the variable will occasionally be undefined in the next 
runScriptlet() call. Additionally, if you do this too many times you will 
eventually crash the JVM with a java.lang.OutOfMemoryError. These behaviors are 
regressions that I cannot reproduce in JRuby 1.5.6.


REPRODUCTION STEPS
Save this code as container_put_test.java and run it against JRuby 1.6.0 
complete jar:

----------------------------
import org.jruby.embed.ScriptingContainer;

public class container_put_test {

  public static void main(String[] args) {
    for(int i = 0; i < 1000; i++) {
      ScriptingContainer container = new ScriptingContainer();
      container.put("$x", 0);
      container.runScriptlet("puts $x");
    }
  }
}
----------------------------

You should see all 0s printed to the screen, but I occasionally see a nil.

If I change the i<1000 in the loop to i<10000, I consistently get a 
java.lang.OutOfMemoryError with JRuby 1.6. The threshold at which this occurs 
probably depends on your machine and JVM settings. 


MORE DETAILS
To check the behavior with different variable types, I changed the loop to this:

for(int i = 0; i < 10000; i++) {
  ScriptingContainer container = new ScriptingContainer();
  container.put("message", "local variable");
  container.put("@message", "instance variable");
  container.put("$message", "global variable");
  container.put("MESSAGE", "constant");
  String script =
        "puts message\n" +
        "puts @message\n" +
        "puts $message\n" +
        "puts MESSAGE";
  container.runScriptlet(script);
}

For this test, I sometimes get an undefined local/constant variable error, and 
other times I get the following exception:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 
2
        at java.util.ArrayList.RangeCheck(ArrayList.java:547)
        at java.util.ArrayList.remove(ArrayList.java:387)
        at java.util.Collections$SynchronizedList.remove(Collections.java:1825)
        at 
org.jruby.embed.variable.VariableInterceptor.terminateLocalVariables(VariableInterceptor.java:237)
        at 
org.jruby.embed.internal.BiVariableMap.terminate(BiVariableMap.java:391)
        at 
org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:146)
        at 
org.jruby.embed.ScriptingContainer.runUnit(ScriptingContainer.java:1229)
        at 
org.jruby.embed.ScriptingContainer.runScriptlet(ScriptingContainer.java:1222)
        at jruby_embed_perf.main(jruby_embed_perf.java:25)

As mentioned before, all these tests run flawlessly with JRuby 1.5.6. 


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://jira.codehaus.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply via email to