atomic 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|