tsafe 0.0.10 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/tsafe_mrswlock.rb +42 -21
- data/spec/mrswlock_spec.rb +31 -3
- data/tsafe.gemspec +1 -1
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.11
|
data/lib/tsafe_mrswlock.rb
CHANGED
@@ -6,6 +6,7 @@ class Tsafe::Mrswlock
|
|
6
6
|
def initialize
|
7
7
|
@reads = 0
|
8
8
|
@w_mutex = Mutex.new
|
9
|
+
@threads_read_stopped = []
|
9
10
|
|
10
11
|
#This variable is used to allow reads from the writing thread (monitor-behavior).
|
11
12
|
@locked_by = nil
|
@@ -17,14 +18,25 @@ class Tsafe::Mrswlock
|
|
17
18
|
# Runs the given block through the read-synchronization.
|
18
19
|
def rsync
|
19
20
|
begin
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
begin
|
22
|
+
tid = Thread.current.__id__
|
23
|
+
|
24
|
+
while @w_mutex.locked? and @locked_by != tid
|
25
|
+
@threads_read_stopped << Thread.current
|
26
|
+
Thread.stop
|
27
|
+
end
|
28
|
+
|
29
|
+
@threads_read_stopped.delete(Thread.current)
|
30
|
+
@reading_threads[tid] = true
|
31
|
+
@reads += 1
|
32
|
+
yield
|
33
|
+
ensure
|
34
|
+
@reading_threads.delete(tid)
|
35
|
+
@reads -= 1
|
36
|
+
end
|
25
37
|
ensure
|
26
|
-
|
27
|
-
@reads
|
38
|
+
#Restart stopped writing-thread.
|
39
|
+
@threads_write_stopped.run if @threads_write_stopped and @reads <= 0
|
28
40
|
end
|
29
41
|
end
|
30
42
|
|
@@ -34,21 +46,30 @@ class Tsafe::Mrswlock
|
|
34
46
|
# #do something within lock.
|
35
47
|
# end
|
36
48
|
def wsync
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
49
|
+
begin
|
50
|
+
@w_mutex.synchronize do
|
51
|
+
begin
|
52
|
+
tid = Thread.current.__id__
|
53
|
+
@locked_by = tid
|
54
|
+
|
55
|
+
#Wait for any reads to finish that might have started while we were getting the lock.
|
56
|
+
#Also allow write if there is only one reading thread and that reading thread is the current thread.
|
57
|
+
while @reads > 0
|
58
|
+
raise ThreadError, "Deadlock: Writing is not allowed while reading." if @reading_threads.key?(tid)
|
59
|
+
@threads_write_stopped = Thread.current
|
60
|
+
Thread.stop
|
61
|
+
end
|
62
|
+
|
63
|
+
yield
|
64
|
+
ensure
|
65
|
+
@locked_by = nil
|
66
|
+
@threads_write_stopped = nil
|
47
67
|
end
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
68
|
+
end
|
69
|
+
ensure
|
70
|
+
#Restart any stopped reading-threads.
|
71
|
+
while thread = @threads_read_stopped.shift
|
72
|
+
thread.run
|
52
73
|
end
|
53
74
|
end
|
54
75
|
end
|
data/spec/mrswlock_spec.rb
CHANGED
@@ -99,13 +99,13 @@ describe "Tsafe::Rwmutex" do
|
|
99
99
|
|
100
100
|
it "should be able to read while writing from same thread while other threads are stressing" do
|
101
101
|
hash = Tsafe::MonHash.new
|
102
|
-
0.upto(
|
102
|
+
0.upto(1500) do |count|
|
103
103
|
hash[count] = count
|
104
104
|
end
|
105
105
|
|
106
|
-
Timeout.timeout(
|
106
|
+
Timeout.timeout(14) do
|
107
107
|
ts = []
|
108
|
-
1.upto(
|
108
|
+
1.upto(20) do
|
109
109
|
ts << Thread.new do
|
110
110
|
hash.keep_if do |key, val|
|
111
111
|
hash.each do |key2, val2|
|
@@ -143,4 +143,32 @@ describe "Tsafe::Rwmutex" do
|
|
143
143
|
#ignore - supposed to happen.
|
144
144
|
end
|
145
145
|
end
|
146
|
+
|
147
|
+
it "should include thread-safe array" do
|
148
|
+
arr = Tsafe::MonArray.new
|
149
|
+
0.upto(1000) do |count|
|
150
|
+
arr << count
|
151
|
+
end
|
152
|
+
|
153
|
+
ts = []
|
154
|
+
0.upto(20) do
|
155
|
+
ts << Thread.new do
|
156
|
+
arr.each do |i|
|
157
|
+
something = i + 100 / 5
|
158
|
+
end
|
159
|
+
|
160
|
+
0.upto(1000) do |count|
|
161
|
+
arr << count + 1000
|
162
|
+
end
|
163
|
+
|
164
|
+
arr.delete_if do |count|
|
165
|
+
count > 1000
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
ts.each do |t|
|
171
|
+
t.join
|
172
|
+
end
|
173
|
+
end
|
146
174
|
end
|
data/tsafe.gemspec
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: tsafe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.11
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Kasper Johansen
|
@@ -102,7 +102,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
102
102
|
requirements:
|
103
103
|
- - ">="
|
104
104
|
- !ruby/object:Gem::Version
|
105
|
-
hash:
|
105
|
+
hash: -1620018328020202062
|
106
106
|
segments:
|
107
107
|
- 0
|
108
108
|
version: "0"
|