From 277aed2927170a1bb9a9bc870cb731cb1414e891 Mon Sep 17 00:00:00 2001 From: Georg Haaser Date: Thu, 16 Jan 2020 16:28:48 +0100 Subject: [PATCH] * fixed transaction bug * proper locking in WeakOutputSet --- RELEASE_NOTES.md | 4 ++++ src/FSharp.Data.Adaptive/Core/AdaptiveObject.fs | 2 +- src/FSharp.Data.Adaptive/Core/Core.fs | 14 +++++++++----- src/FSharp.Data.Adaptive/Core/Transaction.fs | 6 +++--- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index ff679c7..b5f70be 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,7 @@ +### 0.0.16 +* fixed transaction bug +* proper locking in WeakOutputSet + ### 0.0.15 * consistent equality everywhere * DefaultEqualityComparer.SetProvider allows to override default equality before first use diff --git a/src/FSharp.Data.Adaptive/Core/AdaptiveObject.fs b/src/FSharp.Data.Adaptive/Core/AdaptiveObject.fs index 3403446..25e0181 100644 --- a/src/FSharp.Data.Adaptive/Core/AdaptiveObject.fs +++ b/src/FSharp.Data.Adaptive/Core/AdaptiveObject.fs @@ -98,7 +98,7 @@ module AdadptiveObjectExtensions = static val mutable private _Callbacks : list unit> static member Add(action : unit -> unit) = - if AdaptiveObject.UnsafeEvaluationDepth <= 0 then action() + if AdaptiveObject.UnsafeEvaluationDepth <= 0 then transact action elif isNull (AfterEvaluateCallbacks._Callbacks :> obj) then AfterEvaluateCallbacks._Callbacks <- [action] else AfterEvaluateCallbacks._Callbacks <- action :: AfterEvaluateCallbacks._Callbacks diff --git a/src/FSharp.Data.Adaptive/Core/Core.fs b/src/FSharp.Data.Adaptive/Core/Core.fs index 5072c62..e992b7f 100644 --- a/src/FSharp.Data.Adaptive/Core/Core.fs +++ b/src/FSharp.Data.Adaptive/Core/Core.fs @@ -419,15 +419,19 @@ and internal WeakOutputSet() = ) member x.Clear() = - data <- Unchecked.defaultof<_> - setOps <- 0 + lock x (fun () -> + data <- Unchecked.defaultof<_> + setOps <- 0 + ) /// Indicates whether the set is (conservatively) known to be empty. /// Note that we don't dereference any WeakReferences here. member x.IsEmpty = - match data.Tag with - | 0 -> isNull data.Single - | _ -> false + lock x (fun () -> + match data.Tag with + | 0 -> isNull data.Single + | _ -> false + ) interface IWeakOutputSet with member x.IsEmpty = x.IsEmpty diff --git a/src/FSharp.Data.Adaptive/Core/Transaction.fs b/src/FSharp.Data.Adaptive/Core/Transaction.fs index 6280f8e..e0ef142 100644 --- a/src/FSharp.Data.Adaptive/Core/Transaction.fs +++ b/src/FSharp.Data.Adaptive/Core/Transaction.fs @@ -129,6 +129,8 @@ type Transaction() = else e.EnterWrite() try + outputCount <- 0 + // if the element is already outOfDate we // do not traverse the graph further. if e.OutOfDate then @@ -159,7 +161,6 @@ type Transaction() = else e.OutOfDate <- false - outputCount <- 0 // if Mark told us not to continue we're done here () @@ -169,7 +170,6 @@ type Transaction() = // mark it upToDate again (since it would otherwise not be processed again) e.Level <- max e.Level newLevel e.OutOfDate <- false - q.Enqueue(e.Level, e) finally @@ -208,7 +208,7 @@ module Transaction = | Some c -> Some c | None -> None - let using (t : Transaction) (action : unit -> 'T) = + let useTransaction (t : Transaction) (action : unit -> 'T) = let old = Transaction.Current try Transaction.Current <- Some t