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 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"