-
Notifications
You must be signed in to change notification settings - Fork 793
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
Add volatile to InterruptibleLazy valueFactory #17090
Conversation
|
6360481
to
292b246
Compare
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.
Thanks!
Would a helper holder type like [<Struct>]
type LazyValue<'T> =
| Factory of valueFactory: (unit -> 'T)
| Created of value: 'T avoid the ordering problem altogether? Though I'm not sure how performant something like this would be: [<Struct>]
type LazyValue<'T> =
| Factory of valueFactory: (unit -> 'T)
| Created of value: 'T
[<Class>]
type InterruptibleLazy<'T> private (lazyValue) =
let mutable lazyValue = lazyValue
new(valueFactory: unit -> 'T) = InterruptibleLazy(Factory valueFactory)
member this.IsValueCreated =
match lazyValue with
| Created _ -> true
| _ -> false
member this.Value =
match lazyValue with
| Created value -> value
| Factory f ->
lock this <| fun () ->
match lazyValue with
| Created value -> value
| _ ->
try
let value = f ()
lazyValue <- Created value
value
with _ ->
Unchecked.defaultof<'T>
member this.Force() = this.Value
static member FromValue(value) = InterruptibleLazy(Created value)
|
@majocha, In the structural DU, the fields of all cases are linearized into a single structure (and in the current example also depend on T). Therefore, updating such a structure will not be atomic and will suffer from struct tearing, which will lead to the following problems in multithreaded access:
I wouldn't take risks and would opt for a simpler and more reliable option. |
Thanks @DedSec256, so, I understand, it would be necessary to lock on all reads and not just writes, unlike current implementation. |
Description
This PR includes the volatile modifier for the
valueFactory
field. Without this modifier, this code may lead to unexpected situations where, for example, IsValueCreated = true, but Value = null, because of reordering.NO_RELEASE_NOTES