[e-lang] propUtils#testProp/2: not synchronously callable

Thomas Leonard talex5 at gmail.com
Tue Dec 29 07:57:04 PST 2009


Hi all,

In my "Fixed race condition in the boot-comm system" patch (r718), I
added this comment to some existing code:

+                //XXX This doesn't look safe; what if
optHandler.myTarget changes
+                //while we're packaging it? We could just
fall-through to the code
+                //below, but that seems to break one of the test cases.

On closer inspection, it wasn't a test case that was failing, it was a
utility method that tests whether a property is "true" or "false", and
it fails unpredictably with or without the suggested change. I guess I
was just unlucky when I tried building it that way.

The actual error during the build is:

make[1]: Entering directory `/home/talex/src/e/src/jsrc/com/hp/orc'
"java" -cp "../../../../../src/safej:../../../../../src/esrc:../../../../../src/bin/resources:../../../../../classes:../../../../../src/bin/linux-motif/x86_64/swt.jar"
-De.safej.bind-var-to-propName=true
-Djava.library.path=../../../../../src/bin/"linux-motif/x86_64"
org.erights.e.elang.interp.Rune
../../../../../src/esrc/scripts/newlines.e OrcParser.java
=== 2009-12-29T15:27:50.570Z (PendingEvent.report:PendingEvent.java:107) WRN
causality: Problem in turn <<Vat start in <runs in start>>,4>:
--vvvv--
Failed: not synchronously callable

@ run/2
- org.erights.e.tools.collect.propUtils$propUtils#testProp/2:
<file:/home/talex/src/e/src/esrc/org/erights/e/tools/collect/propUtils.emaker#:span::10:7::10:14>
. <propUtils>.testProp(["java.vendor" => "Sun Microsystems Inc.",
"sun...llow", "java.specification.version" => "1.6"],
"e.interp.expand")
@ testProp/2: <file:/home/talex/src/e/src/esrc/org/erights/e/elang/cmd/cmdLoopMakerAuthor.emaker#:span::23:20::23:27>
- org.erights.e.elang.cmd.cmdLoopMakerAuthor$cmdLoopMakerAuthor$cmdLoopMaker#run/4:
<file:/home/talex/src/e/src/esrc/org/erights/e/elang/cmd/cmdLoopMakerAuthor.emaker#:span::15:20::15:20>
. <cmdLoopMaker>(["OrcParser.java"], ["java.vendor" =...ion" =>
"1.6"], <a Scope>, false)
@ run/4: <file:/home/talex/src/e/src/esrc/org/erights/e/elang/cmd/makeEvalPrinterAuthor.emaker#:span::28:36::28:36>
- org.erights.e.elang.cmd.makeEvalPrinterAuthor$makeEvalPrinterAuthor$makeEvalPrinter#run/4:
<file:/home/talex/src/e/src/esrc/org/erights/e/elang/cmd/makeEvalPrinterAuthor.emaker#:span::21:23::21:23>
. <makeEvalPrinter>(<makeImplicitEvalContext>, ["OrcParser.java"],
["java.vendor..." => "1.6"], false)
@ run/4: <file:/home/talex/src/e/src/esrc/org/erights/e/elang/launcher/eLauncherAuthor.emaker#:span::141:58::141:58>
- org.erights.e.elang.launcher.eLauncherAuthor$eLauncherAuthor$eLauncher$_$startRepl#run/1:
<file:/home/talex/src/e/src/esrc/org/erights/e/elang/launcher/eLauncherAuthor.emaker#:span::134:33::134:33>
. <startRepl>(["OrcParser.java"])

java.lang.RuntimeException: Failed: not synchronously callable

The code is:

def propUtils {
    to testProp(props, propName :String) :boolean {
        def propValue := props.fetch(propName, fn{"false"})
        switch (propValue) {
            match `true`  { true }
            match `false` { false }
            match _ { throw(`$propValue must be true or false`) }
        }
    }
}

After adding some more information to the error message, it seems that
__matchBind is sometimes only a promise. The error message can be made
easily reproducible by adding a delay to the top of
elang/expand/__matchBind.emaker, e.g. this makes the build fail every
time for me:

pragma.syntax("0.9")

var x := 0
while (x < 100000) {
    x += 1
}

...

I thought the problem might be in LazyEvalSlot, which is used to get
the value of __matchBind when needed. A comment in the code says:

            synchronized (myLock) {
                // If it's asked for while it's doing its own evaluation, it
                // returns a promise for what it'll evaluate to.
                myOptValue = promise[0];
                myOptScope = null;
                myOptSource = null;
            }

However, making the whole method synchronised didn't help. I also
thought it might be something to do with ImportLoader, which does a
similar trick, but I can't see why either of these would be shared
between threads; ScopeSetup seems to make a new ImportLoader in
privileged/7. Why are they "synchronized"? ImportLoader says:

  * As explained in the superclass comment, this must be thread-safe.

I'm not sure what comment this is referring to, though.


Thanks,


-- 
Dr Thomas Leonard		ROX desktop / Zero Install
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1


More information about the e-lang mailing list