Skip to content

Commit ac96481

Browse files
authored
Fix #100 (#101)
1 parent 13db599 commit ac96481

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

src/tools.jl

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ May be used to mark a region in parallel code to be executed by a single task on
3131
See [`try_enter!`](@ref) and [`reset!`](@ref).
3232
"""
3333
mutable struct OnlyOneRegion
34-
@atomic latch::Bool
35-
OnlyOneRegion() = new(false)
34+
@atomic task::Union{Task, Nothing}
35+
OnlyOneRegion() = new(nothing)
3636
end
3737

3838
"""
@@ -62,24 +62,23 @@ end
6262
```
6363
"""
6464
function try_enter!(f, s::OnlyOneRegion)
65-
latch = @atomic :monotonic s.latch
66-
if latch
65+
ct = current_task()
66+
t = @atomic :monotonic s.task
67+
if !isnothing(t) && ct != t
6768
return
6869
end
69-
(_, success) = @atomicreplace s.latch false=>true
70-
if !success
71-
return
70+
if ct == t || (@atomicreplace s.task nothing=>ct).success
71+
f()
7272
end
73-
f()
7473
return
7574
end
7675

7776
"""
7877
Reset the `OnlyOneRegion` (so that it can be used again).
7978
"""
8079
function reset!(s::OnlyOneRegion)
81-
@atomicreplace s.latch true=>false
82-
nothing
80+
@atomic s.task = nothing
81+
return
8382
end
8483

8584
"""

test/runtests.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,22 @@ end
454454
catch ErrorException
455455
@test false
456456
end
457+
458+
x = 0
459+
y = 0
460+
try
461+
@tasks for i in 1:10
462+
@set ntasks = 2
463+
464+
y += 1 # not safe (race condition)
465+
@only_one begin
466+
x += 1 # parallel-safe because only a single task will execute this
467+
end
468+
end
469+
@test x == 5 # a single task should have incremented x 5 times
470+
catch ErrorException
471+
@test false
472+
end
457473
end
458474

459475
@testset "@only_one + @one_by_one" begin

0 commit comments

Comments
 (0)