This is an automated email from the ASF dual-hosted git repository.
slawrence pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil.git
The following commit(s) were added to refs/heads/main by this push:
new ee395ad5e Fix detection of OOLAG circular depedencies
ee395ad5e is described below
commit ee395ad5edd4b20bfb4f3f4ce4074e72021a4354
Author: Steve Lawrence <[email protected]>
AuthorDate: Mon Aug 18 13:19:31 2025 -0400
Fix detection of OOLAG circular depedencies
Scala 3 changed how lazy vals work so that circular lazy vals result in
a deadlock. OOLAG was written to detect circular dependencies, but its
internal use of lazy vals could lead to these lazy val deadlocks in
cases of circular dependencies.
Fortunately, the OOLAG lazy vals can be replaced with defs without any
real functional changes since OOLAG already has logic to handle its own
lazy evaluation--the `var value_: Maybe` is Nope until the OOLAG gets a
value and is One once the OOLAG lazy evaluation complete. The existing
logic already handles checking and mutating the value_ variable
correctly. All that we lose by switching some lazy vals to defs is we
now have to check value_ every time an OOLAG is accessed instead of
storing it in a lazy val once its finally evaluated, but that should be
pretty minimal overhead, especially since OOLAG values are usually
stored in other variables once accessed.
DAFFODIL-2986
---
.../src/main/scala/org/apache/daffodil/lib/oolag/OOLAG.scala | 10 ++++------
.../test/scala/org/apache/daffodil/lib/oolag/TestOOLAG.scala | 3 +--
2 files changed, 5 insertions(+), 8 deletions(-)
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/lib/oolag/OOLAG.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/lib/oolag/OOLAG.scala
index 37cbd4a76..4c11006de 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/lib/oolag/OOLAG.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/lib/oolag/OOLAG.scala
@@ -699,11 +699,9 @@ object OOLAG {
res
}
- final lazy val valueAsAny: Any = {
+ final def valueAsAny: Any = {
if (hasValue) value_.get
else {
- // egad.... on 2024-12-19 this was always re-evaluating due to missing
`else` keyword.
- // this should make a substantial difference in schema compilation
time.
val res =
try {
oolagBefore()
@@ -723,7 +721,7 @@ object OOLAG {
}
}
- protected lazy val toOptionAny: Option[Any] = {
+ protected def toOptionAny: Option[Any] = {
if (wasTried) {
if (hasValue) Some(value_.get)
else None
@@ -752,9 +750,9 @@ object OOLAG {
* Use this if you are getting stack-overflows or circular value problems
* caused by an SDE and the SDE infrastructure needing the value of some
LV.
*/
- final lazy val toOption: Option[T] = toOptionAny.asInstanceOf[Option[T]]
+ final def toOption: Option[T] = toOptionAny.asInstanceOf[Option[T]]
- final lazy val value: T = valueAsAny.asInstanceOf[T]
+ final def value: T = valueAsAny.asInstanceOf[T]
}
} // end object
diff --git
a/daffodil-core/src/test/scala/org/apache/daffodil/lib/oolag/TestOOLAG.scala
b/daffodil-core/src/test/scala/org/apache/daffodil/lib/oolag/TestOOLAG.scala
index d597955c6..48a69492d 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/lib/oolag/TestOOLAG.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/lib/oolag/TestOOLAG.scala
@@ -26,7 +26,6 @@ import org.apache.daffodil.lib.util.Maybe
import org.apache.daffodil.lib.util.Maybe.*
import org.junit.Assert.*
-import org.junit.Ignore
import org.junit.Test
class MyException(msg: String) extends Diagnostic(Nope, Nope, Nope,
Maybe(msg)) {
@@ -205,7 +204,7 @@ class TestOOLAG {
// In Scala 3, Circular Definition detection doesn't work with
// lazy vals because the thread hangs on trying to grab the aleady evaluating
// lazy val the 2nd go round. Uncomment the test when the bug is fixed
- @Ignore @Test def testCircularDefinitionDetected(): Unit = {
+ @Test def testCircularDefinitionDetected(): Unit = {
val h = new MyHost
h.setRequiredEvaluationsActive()
var e: Exception = null