propUtils#testProp/2: not synchronously callable

Thomas Leonard <[email protected]>
Newsgroups gmane.comp.lang.e.general
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.