tsafe 0.0.10 → 0.0.11
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/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"
|