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 CHANGED
@@ -1 +1 @@
1
- 0.0.10
1
+ 0.0.11
@@ -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
- tid = Thread.current.__id__
21
- Thread.pass while @w_mutex.locked? and @locked_by != tid
22
- @reading_threads[tid] = true
23
- @reads += 1
24
- yield
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
- @reading_threads.delete(tid)
27
- @reads -= 1
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
- @w_mutex.synchronize do
38
- begin
39
- tid = Thread.current.__id__
40
- @locked_by = tid
41
-
42
- #Wait for any reads to finish that might have started while we were getting the lock.
43
- #Also allow write if there is only one reading thread and that reading thread is the current thread.
44
- while @reads > 0
45
- raise ThreadError, "Deadlock: Writing is not allowed while reading." if @reading_threads.key?(tid)
46
- Thread.pass
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
- yield
50
- ensure
51
- @locked_by = nil
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
@@ -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(1000) do |count|
102
+ 0.upto(1500) do |count|
103
103
  hash[count] = count
104
104
  end
105
105
 
106
- Timeout.timeout(7) do
106
+ Timeout.timeout(14) do
107
107
  ts = []
108
- 1.upto(5) do
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
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{tsafe}
8
- s.version = "0.0.10"
8
+ s.version = "0.0.11"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kasper Johansen"]
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: tsafe
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.10
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: 1945930080494569977
105
+ hash: -1620018328020202062
106
106
  segments:
107
107
  - 0
108
108
  version: "0"