Skip to content

Commit

Permalink
Add a RentrantLock for thread safety
Browse files Browse the repository at this point in the history
  • Loading branch information
NicholasWMRitchie committed Jul 5, 2022
1 parent ffe90d8 commit 3f0c031
Showing 1 changed file with 11 additions and 3 deletions.
14 changes: 11 additions & 3 deletions src/Procrastinate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ever be used. By deferring the computation, the cost is avoided if the datum is
never used.
`Deferred` takes advantage of closures to ensure that the necessary data will be
available when needed.
available when needed. `Deferred` is thread safe.
# Example:
```julia-repl
Expand All @@ -31,11 +31,15 @@ julia> d()
"""
struct Deferred
func::Function
lock::ReentrantLock
item::Base.RefValue{Any}

function Deferred(f::Function)
@assert applicable(f) "The function passed to the Deferred constructor must take exactly zero-arguments."
new(f, Base.RefValue{Any}())
new(f, ReentrantLock(), Base.RefValue{Any}())
end
function Deferred(value)
new((x->@assert false), ReentrantLock(), value)
end
end

Expand All @@ -45,7 +49,11 @@ end

function (df::Deferred)()
if !isassigned(df.item)
df.item[] = df.func()
lock(df.lock) do
if !isassigned(df.item)
df.item[] = df.func()
end
end
end
return df.item[]
end
Expand Down

0 comments on commit 3f0c031

Please sign in to comment.