Skip to content

Commit 62eac0f

Browse files
committed
Better range checking on MutexAtomicFixnum.
1 parent c5eab83 commit 62eac0f

File tree

2 files changed

+39
-7
lines changed

2 files changed

+39
-7
lines changed

lib/concurrent/atomic/atomic_fixnum.rb

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ class MutexAtomicFixnum < Synchronization::Object
3535
# @param [Fixnum] init the initial value
3636
# @raise [ArgumentError] if the initial value is not a `Fixnum`
3737
def initialize(initial = 0)
38-
raise ArgumentError.new('initial value must be a Fixnum') unless initial.is_a?(Fixnum)
3938
super(initial)
4039
end
4140

@@ -58,8 +57,7 @@ def value
5857
#
5958
# @raise [ArgumentError] if the new value is not a `Fixnum`
6059
def value=(value)
61-
raise ArgumentError.new('value must be a Fixnum') unless value.is_a?(Fixnum)
62-
synchronize { @value = value }
60+
synchronize { ns_set(value) }
6361
end
6462

6563
# @!macro [attach] atomic_fixnum_method_increment
@@ -68,7 +66,7 @@ def value=(value)
6866
#
6967
# @return [Fixnum] the current value after incrementation
7068
def increment
71-
synchronize { @value += 1 }
69+
synchronize { ns_set(@value + 1) }
7270
end
7371

7472
alias_method :up, :increment
@@ -79,7 +77,7 @@ def increment
7977
#
8078
# @return [Fixnum] the current value after decrementation
8179
def decrement
82-
synchronize { @value -= 1 }
80+
synchronize { ns_set(@value -1) }
8381
end
8482

8583
alias_method :down, :decrement
@@ -107,7 +105,26 @@ def compare_and_set(expect, update)
107105
protected
108106

109107
def ns_initialize(initial)
110-
@value = initial
108+
ns_set(initial)
109+
end
110+
111+
private
112+
113+
def ns_set(value)
114+
range_check!(value)
115+
@value = value
116+
end
117+
118+
def range_check!(value)
119+
if !value.is_a?(Fixnum)
120+
raise ArgumentError.new('value value must be a Fixnum')
121+
elsif value > MAX_VALUE
122+
raise RangeError.new("#{value} is greater than the maximum value of #{MAX_VALUE}")
123+
elsif value < MIN_VALUE
124+
raise RangeError.new("#{value} is less than the maximum value of #{MIN_VALUE}")
125+
else
126+
value
127+
end
111128
end
112129
end
113130

spec/concurrent/atomic/atomic_fixnum_spec.rb

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,26 @@ module Concurrent
115115
describe MutexAtomicFixnum do
116116

117117
it_should_behave_like :atomic_fixnum
118+
119+
context 'construction' do
120+
121+
it 'raises en exception if the initial value is too big' do
122+
expect {
123+
described_class.new(described_class::MAX_VALUE + 1)
124+
}.to raise_error
125+
end
126+
127+
it 'raises en exception if the initial value is too small' do
128+
expect {
129+
described_class.new(described_class::MIN_VALUE - 1)
130+
}.to raise_error
131+
end
132+
end
118133

119134
context 'instance methods' do
120135

121136
before(:each) do
122-
expect(subject).to receive(:synchronize).with(no_args).and_return(10)
137+
expect(subject).to receive(:synchronize).with(no_args).and_call_original
123138
end
124139

125140
specify 'value is synchronized' do

0 commit comments

Comments
 (0)