atomic 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/atomic.gemspec +1 -1
- data/lib/atomic.rb +17 -34
- data/test/test_atomic.rb +20 -4
- metadata +3 -3
data/atomic.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{atomic}
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.2"
|
6
6
|
s.authors = ["Charles Oliver Nutter", "MenTaLguY"]
|
7
7
|
s.date = Time.now.strftime('YYYY-MM-DD')
|
8
8
|
s.description = "An atomic reference implementation for JRuby and green or GIL-threaded impls"
|
data/lib/atomic.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
class Atomic
|
2
4
|
class ConcurrentUpdateError < ThreadError
|
3
5
|
end
|
4
6
|
|
@@ -38,42 +40,23 @@ end
|
|
38
40
|
|
39
41
|
if defined? RUBY_ENGINE && RUBY_ENGINE == "jruby"
|
40
42
|
require 'java'
|
41
|
-
Atomic =
|
42
|
-
InternalReference = java.util.concurrent.atomic.AtomicReference
|
43
|
-
end
|
43
|
+
Atomic::InternalReference = java.util.concurrent.atomic.AtomicReference
|
44
44
|
else
|
45
|
-
Atomic
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
alias_method :set, :value=
|
45
|
+
class Atomic::InternalReference
|
46
|
+
attr_accessor :value
|
47
|
+
alias_method :get, :value
|
48
|
+
alias_method :set, :value=
|
50
49
|
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
def initialize(value)
|
51
|
+
@value = value
|
52
|
+
end
|
54
53
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
60
|
-
true
|
61
|
-
end
|
62
|
-
|
63
|
-
HAS_EXCLUSIVE = defined? Thread.exclusive
|
64
|
-
def _exclusive
|
65
|
-
if HAS_EXCLUSIVE
|
66
|
-
Thread.exclusive {yield}
|
67
|
-
else
|
68
|
-
begin
|
69
|
-
Thread.critical = true
|
70
|
-
yield
|
71
|
-
ensure
|
72
|
-
Thread.critical = false
|
73
|
-
end
|
74
|
-
end
|
54
|
+
def compare_and_set(old_value, new_value)
|
55
|
+
Thread.exclusive do
|
56
|
+
return false unless @value.equal? old_value
|
57
|
+
@value = new_value
|
75
58
|
end
|
76
|
-
|
59
|
+
true
|
77
60
|
end
|
78
61
|
end
|
79
|
-
end
|
62
|
+
end
|
data/test/test_atomic.rb
CHANGED
@@ -19,17 +19,33 @@ class TestAtomic < Test::Unit::TestCase
|
|
19
19
|
|
20
20
|
def test_update
|
21
21
|
atomic = Atomic.new(0)
|
22
|
-
atomic.update {|v| v + 1}
|
22
|
+
res = atomic.update {|v| v + 1}
|
23
23
|
|
24
24
|
assert_equal 1, atomic.value
|
25
|
+
assert_equal 0, res
|
25
26
|
end
|
26
27
|
|
27
28
|
def test_try_update
|
28
29
|
atomic = Atomic.new(0)
|
29
|
-
atomic.try_update {|v| v + 1}
|
30
|
+
res = atomic.try_update {|v| v + 1}
|
30
31
|
|
31
32
|
assert_equal 1, atomic.value
|
33
|
+
assert_equal 0, res
|
32
34
|
end
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
+
def test_try_update_fails
|
37
|
+
atomic = Atomic.new(0)
|
38
|
+
assert_raise Atomic::ConcurrentUpdateError do
|
39
|
+
# assigning within block exploits implementation detail for test
|
40
|
+
atomic.try_update{|v| atomic.value = 1 ; v + 1}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_update_retries
|
45
|
+
tries = 0
|
46
|
+
atomic = Atomic.new(0)
|
47
|
+
# assigning within block exploits implementation detail for test
|
48
|
+
atomic.update{|v| tries += 1 ; atomic.value = 1 ; v + 1}
|
49
|
+
assert_equal 2, tries
|
50
|
+
end
|
51
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Charles Oliver Nutter
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-06-08 00:
|
18
|
+
date: 2010-06-08 00:29:12.585000 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|