-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix race condition in new LazyVals #16975
Conversation
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was quite subtle!
Perhaps add a comment above LazyValControlState
explaining why it extends Serializable
?
FWIW, Scala 2 uses jcstress to stress-test concurrency tests: scala/scala@3783fe8, it would be good if we could stress-test lazy vals that way too. |
@sjrd How can I test this with scalajs? There is some linking error. |
You cannot do it with something based on But anyway it does not matter on Scala.js, since Scala.js only uses a single thread and therefore always uses the non-thread-safe // scalajs: --skip |
Resolve #16806
In the repro,
Evaluating
was generated as a subtype ofSerializable
, and the type of lazy value was erased toSerializable
- these together broke the optimized condition checking if the value is initialized. For lazy val of typeA
we were checking ifLazyValControlState <: A
, and if that was not the case, we assumed it would be safe to just generate the condition_value.isInstanceOf[A]
. If that condition was true in runtime, we assumed that the value was already calculated and returned it. If it wasEvaluating
andA =:= Serializable
, then we assumed so falsely. The easiest fix is to just make theLazyValControlState <: Serializable
, I will check if it doesn't affect performance.