Fix deadlock issue with custom Enum implementation
authorSteve Lawrence <slawrence@apache.org>
Wed, 15 Jun 2022 18:45:01 +0000 (14:45 -0400)
committerSteve Lawrence <stephen.d.lawrence@gmail.com>
Thu, 16 Jun 2022 11:22:26 +0000 (07:22 -0400)
commit0f5ebcab73bc54394e58597b6e44d36ddfbfd8ee
tree8d7db09db208029de4365314e76f14158d4801cd
parent6c9cc40e86cfa54eaa49f4b2f724f1a3b12e3434
Fix deadlock issue with custom Enum implementation

Our Enum implementation use for property values/lookups has important
benefits over Scala Enumerations. However, it seems like the way we
implement it can lead to circular deadlocks. When a Value is initialized
it causes the Enum to be initialized. And the Enum initialized calls
forceConstruction to initialized all the Values. This leads to circular
instantiating that works in most cases, but sometimes leads to a
deadlock. Where this deadlock exists or how to fix it is not clear. It's
also not clear what changed to make this deadlock much more likely.

To avoid this, we this change removes the forceConstruction function and
replaces it with a manually managed Array of Enum Values. This Array is
lazily evaluated so that instantiated an Enum does not also directly
instantiate the Enum Value, avoiding the circular deadlock. This does
require extra code to define an Enum, but the majority of Enums are in
generated code so doesn't add much maintenance burden.

DAFFODIL-2704
daffodil-cli/src/main/scala/org/apache/daffodil/Main.scala
daffodil-core/src/test/scala/org/apache/daffodil/schema/annotation/props/TestPropertyRuntime.scala
daffodil-lib/src/main/scala/org/apache/daffodil/schema/annotation/props/ByHandMixins.scala
daffodil-lib/src/main/scala/org/apache/daffodil/schema/annotation/props/Properties.scala
daffodil-lib/src/test/scala/org/apache/daffodil/schema/annotation/props/TestGeneratedProperties.scala
daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/PropertyGenerator.scala
daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/TunableGenerator.scala
daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/WarnIDGenerator.scala
daffodil-runtime1-layers/src/main/scala/org/apache/daffodil/layers/LineFoldedTransformer.scala
daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/RunnerFactory.scala