Skip to content

Commit 423797c

Browse files
committed
MriMapBackend now has per-instance mutex.
1 parent f8bb41a commit 423797c

File tree

1 file changed

+16
-19
lines changed

1 file changed

+16
-19
lines changed

lib/concurrent/thread_safe/mri_map_backend.rb

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require 'thread'
12
require 'concurrent/thread_safe/non_concurrent_map_backend'
23

34
module Concurrent
@@ -8,61 +9,57 @@ module ThreadSafe
89
# @!visibility private
910
class MriMapBackend < NonConcurrentMapBackend
1011

11-
# We can get away with a single global write lock (instead of a per-instance
12-
# one) because of the GVL/green threads.
13-
#
14-
# NOTE: a neat idea of writing a c-ext to manually perform atomic
15-
# put_if_absent, while relying on Ruby not releasing a GVL while calling a
16-
# c-ext will not work because of the potentially Ruby implemented `#hash`
17-
# and `#eql?` key methods.
18-
WRITE_LOCK = Mutex.new
12+
def initialize(options = nil)
13+
super(options)
14+
@write_lock = Mutex.new
15+
end
1916

2017
def []=(key, value)
21-
WRITE_LOCK.synchronize { super }
18+
@write_lock.synchronize { super }
2219
end
2320

2421
def compute_if_absent(key)
2522
if stored_value = _get(key) # fast non-blocking path for the most likely case
2623
stored_value
2724
else
28-
WRITE_LOCK.synchronize { super }
25+
@write_lock.synchronize { super }
2926
end
3027
end
3128

3229
def compute_if_present(key)
33-
WRITE_LOCK.synchronize { super }
30+
@write_lock.synchronize { super }
3431
end
3532

3633
def compute(key)
37-
WRITE_LOCK.synchronize { super }
34+
@write_lock.synchronize { super }
3835
end
3936

4037
def merge_pair(key, value)
41-
WRITE_LOCK.synchronize { super }
38+
@write_lock.synchronize { super }
4239
end
4340

4441
def replace_pair(key, old_value, new_value)
45-
WRITE_LOCK.synchronize { super }
42+
@write_lock.synchronize { super }
4643
end
4744

4845
def replace_if_exists(key, new_value)
49-
WRITE_LOCK.synchronize { super }
46+
@write_lock.synchronize { super }
5047
end
5148

5249
def get_and_set(key, value)
53-
WRITE_LOCK.synchronize { super }
50+
@write_lock.synchronize { super }
5451
end
5552

5653
def delete(key)
57-
WRITE_LOCK.synchronize { super }
54+
@write_lock.synchronize { super }
5855
end
5956

6057
def delete_pair(key, value)
61-
WRITE_LOCK.synchronize { super }
58+
@write_lock.synchronize { super }
6259
end
6360

6461
def clear
65-
WRITE_LOCK.synchronize { super }
62+
@write_lock.synchronize { super }
6663
end
6764
end
6865
end

0 commit comments

Comments
 (0)