tsafe 0.0.11 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,17 +6,17 @@ class Tsafe::Mrswlock
6
6
  # Sets various variables.
7
7
  def initialize
8
8
  @lock = java.util.concurrent.locks.ReentrantReadWriteLock.new
9
-
10
- #This hash holds thread-IDs for threads that are reading.
9
+
10
+ # This hash holds thread-IDs for threads that are reading.
11
11
  @reading_threads = {}
12
12
  end
13
-
13
+
14
14
  # Runs the given block through the read-synchronization.
15
15
  def rsync
16
16
  @lock.read_lock.lock
17
17
  tid = Thread.current.__id__
18
18
  @reading_threads[tid] = true
19
-
19
+
20
20
  begin
21
21
  yield
22
22
  ensure
@@ -24,8 +24,8 @@ class Tsafe::Mrswlock
24
24
  @lock.read_lock.unlock
25
25
  end
26
26
  end
27
-
28
- #Runs the given block through the write-synchronization (locks both reading and writing).
27
+
28
+ # Runs the given block through the write-synchronization (locks both reading and writing).
29
29
  #===Examples
30
30
  # lock.wsync do
31
31
  # #do something within lock.
@@ -33,7 +33,7 @@ class Tsafe::Mrswlock
33
33
  def wsync
34
34
  tid = Thread.current.__id__
35
35
  raise ThreadError, "Deadlock: Writing is not allowed while reading." if @reading_threads.key?(tid)
36
-
36
+
37
37
  begin
38
38
  @wlock_by = tid
39
39
  @lock.write_lock.lock
@@ -42,4 +42,4 @@ class Tsafe::Mrswlock
42
42
  @lock.write_lock.unlock
43
43
  end
44
44
  end
45
- end
45
+ end
@@ -8,7 +8,7 @@
8
8
  module Tsafe::Mrswlock_synmodule
9
9
  def self.included(base)
10
10
  base.to_s.split("::").inject(Object, :const_get).class_eval do
11
- #Yields the given block within the read-lock.
11
+ # Yields the given block within the read-lock.
12
12
  #===Examples
13
13
  # obj._tsafe_rsync do
14
14
  # #do something within read-lock.
@@ -16,8 +16,8 @@ module Tsafe::Mrswlock_synmodule
16
16
  def _tsafe_rsync(&block)
17
17
  @tsafe_mrswlock.rsync(&block)
18
18
  end
19
-
20
- #Yields the given block within the write-lock (and read-lock).
19
+
20
+ # Yields the given block within the write-lock (and read-lock).
21
21
  #===Examples
22
22
  # obj._tsafe_wsync do
23
23
  # #do something within write-lock.
@@ -25,39 +25,39 @@ module Tsafe::Mrswlock_synmodule
25
25
  def _tsafe_wsync(&block)
26
26
  @tsafe_mrswlock.rsync(&block)
27
27
  end
28
-
29
- #Rename initialize.
28
+
29
+ # Rename initialize.
30
30
  alias_method(:initialize_mrswlock, :initialize)
31
-
32
- #Make another initialize-method that spawns the lock and then calls the original initialize.
31
+
32
+ # Make another initialize-method that spawns the lock and then calls the original initialize.
33
33
  define_method(:initialize) do |*args, &block|
34
34
  @tsafe_mrswlock = Tsafe::Mrswlock.new
35
35
  return initialize_mrswlock(*args, &block)
36
36
  end
37
-
38
- #Makes reader methods go through reader-lock.
37
+
38
+ # Makes reader methods go through reader-lock.
39
39
  base.class_variable_get(:@@tsafe_mrswlock_r_methods).each do |mname|
40
40
  newmname = "tsafe_mrswlock_#{mname}".to_sym
41
41
  alias_method(newmname, mname)
42
-
42
+
43
43
  define_method(mname) do |*args, &block|
44
44
  @tsafe_mrswlock.rsync do
45
- return self.__send__(newmname, *args, &block)
45
+ return __send__(newmname, *args, &block)
46
46
  end
47
47
  end
48
48
  end
49
-
50
- #Makes writer methods go through writer-lock.
49
+
50
+ # Makes writer methods go through writer-lock.
51
51
  base.class_variable_get(:@@tsafe_mrswlock_w_methods).each do |mname|
52
52
  newmname = "tsafe_mrswlock_#{mname}".to_sym
53
53
  alias_method(newmname, mname)
54
-
54
+
55
55
  define_method(mname) do |*args, &block|
56
56
  @tsafe_mrswlock.wsync do
57
- return self.__send__(newmname, *args, &block)
57
+ return __send__(newmname, *args, &block)
58
58
  end
59
59
  end
60
60
  end
61
61
  end
62
62
  end
63
- end
63
+ end
@@ -1,4 +1,4 @@
1
- #This module can be included on a class to make all method-calls synchronized (by using mutex). Examples with array and hash are below.
1
+ # This module can be included on a class to make all method-calls synchronized (by using mutex). Examples with array and hash are below.
2
2
  #
3
3
  #===Examples
4
4
  # class MySyncedClass < SomeOtherClassThatNeedsToBeSynchronized
@@ -7,23 +7,23 @@
7
7
  module Tsafe::Mutexed
8
8
  def self.included(base)
9
9
  base.to_s.split("::").inject(Object, :const_get).class_eval do
10
- self.instance_methods.each do |method_name|
11
- #These two methods create warnings under JRuby.
10
+ instance_methods.each do |method_name|
11
+ # These two methods create warnings under JRuby.
12
12
  if RUBY_ENGINE == "jruby"
13
- next if method_name == :instance_exec or method_name == :instance_eval
13
+ next if method_name == :instance_exec || method_name == :instance_eval
14
14
  end
15
-
15
+
16
16
  new_method_name = "_ts_#{method_name}"
17
17
  alias_method(new_method_name, method_name)
18
-
18
+
19
19
  define_method method_name do |*args, &block|
20
- #Need to use monitor, since the internal calls might have to run not-synchronized, and we have just overwritten the internal methods.
21
- @_ts_mutex = Mutex.new if !@_ts_mutex
20
+ # Need to use monitor, since the internal calls might have to run not-synchronized, and we have just overwritten the internal methods.
21
+ @_ts_mutex = Mutex.new unless @_ts_mutex
22
22
  @_ts_mutex.synchronize do
23
- return self._ts___send__(new_method_name, *args, &block)
23
+ return _ts___send__(new_method_name, *args, &block)
24
24
  end
25
25
  end
26
26
  end
27
27
  end
28
28
  end
29
- end
29
+ end
@@ -1,13 +1,13 @@
1
- #Instances of this class proxies calls to a given-object by using a mutex or monitor.
1
+ # Instances of this class proxies calls to a given-object by using a mutex or monitor.
2
2
  #
3
3
  #==== Examples
4
4
  # threadsafe_array = Tsafe::Proxy.new(:obj => [])
5
5
  # threadsafe_array << 5
6
6
  # ret = threadsafe_array[0]
7
- #
7
+ #
8
8
  # threadsafe_array = Tsafe::Proxy.new(:obj => [], :monitor => true)
9
9
  class Tsafe::Proxy
10
- #Spawns needed vars.
10
+ # Spawns needed vars.
11
11
  def initialize(args)
12
12
  if args[:monitor]
13
13
  @mutex = Monitor.new
@@ -16,14 +16,14 @@ class Tsafe::Proxy
16
16
  else
17
17
  @mutex = Mutex.new
18
18
  end
19
-
19
+
20
20
  @obj = args[:obj]
21
21
  end
22
-
23
- #Proxies all calls to this object through the mutex.
22
+
23
+ # Proxies all calls to this object through the mutex.
24
24
  def method_missing(method_name, *args, &block)
25
25
  @mutex.synchronize do
26
26
  @obj.__send__(method_name, *args, &block)
27
27
  end
28
28
  end
29
- end
29
+ end
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ cache: bundler
3
+ archive: true
4
+ rvm:
5
+ - ruby-2.1.2
6
+ - ruby-1.9.3-head
7
+ script:
8
+ - bundle exec rspec
9
+ - bundle exec rubocop
10
+ notifications:
11
+ email: false
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
2
 
3
3
  require "timeout"
4
4
 
@@ -6,112 +6,112 @@ describe "Tsafe::Rwmutex" do
6
6
  it "should work with the modified hash" do
7
7
  Thread.abort_on_exception = true
8
8
  debug = false
9
-
9
+
10
10
  print "Setting initial values.\n" if debug
11
11
  hash = Tsafe::MonHash.new
12
12
  0.upto(15) do |count|
13
- realcount = 100000000 - count
13
+ realcount = 100_000_000 - count
14
14
  hash[realcount] = realcount
15
15
  end
16
-
16
+
17
17
  called = false
18
18
  hash._tsafe_rsync do
19
19
  called = true
20
20
  end
21
-
22
- raise "Expected to be called." if !called
23
-
21
+
22
+ raise "Expected to be called." unless called
23
+
24
24
  called = false
25
25
  hash._tsafe_wsync do
26
26
  called = true
27
27
  end
28
-
29
- raise "Expected to be called." if !called
30
-
28
+
29
+ raise "Expected to be called." unless called
30
+
31
31
  ts = []
32
-
32
+
33
33
  1.upto(10) do |tcount|
34
34
  print "Starting thread #{tcount}\n" if debug
35
35
  ts << Thread.new do
36
36
  1.upto(5000) do |count|
37
37
  hash[count] = count
38
-
38
+
39
39
  hash[count]
40
40
  hash.key?(count)
41
-
41
+
42
42
  hash.delete(count)
43
-
43
+
44
44
  hash.each do |key, val|
45
- #nothing...
45
+ # nothing...
46
46
  end
47
47
  end
48
48
  end
49
49
  end
50
-
50
+
51
51
  ts.each do |t|
52
52
  print "Joining #{t.__id__}\n" if debug
53
53
  t.join
54
54
  end
55
55
  end
56
-
56
+
57
57
  it "should work with manual lock creation" do
58
58
  debug = false
59
-
59
+
60
60
  hash = {}
61
61
  0.upto(15) do |count|
62
- realcount = 100000000 - count
62
+ realcount = 100_000_000 - count
63
63
  hash[realcount] = realcount
64
64
  end
65
-
65
+
66
66
  rwm = Tsafe::Mrswlock.new
67
67
  ts = []
68
-
68
+
69
69
  1.upto(10) do
70
70
  ts << Thread.new do
71
71
  1.upto(5000) do |count|
72
72
  rwm.wsync do
73
73
  hash[count] = count
74
74
  end
75
-
75
+
76
76
  rwm.rsync do
77
77
  hash[count]
78
78
  hash.key?(count)
79
79
  end
80
-
80
+
81
81
  rwm.wsync do
82
82
  hash.delete(count)
83
83
  end
84
-
84
+
85
85
  rwm.rsync do
86
86
  hash.each do |key, val|
87
- #nothing...
87
+ # nothing...
88
88
  end
89
89
  end
90
90
  end
91
91
  end
92
92
  end
93
-
93
+
94
94
  ts.each do |t|
95
95
  print "Joining #{t.__id__}\n" if debug
96
96
  t.join
97
97
  end
98
98
  end
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
102
  0.upto(1500) do |count|
103
103
  hash[count] = count
104
104
  end
105
-
105
+
106
106
  Timeout.timeout(14) do
107
107
  ts = []
108
108
  1.upto(20) do
109
109
  ts << Thread.new do
110
- hash.keep_if do |key, val|
110
+ hash.keep_if do |key, _val|
111
111
  hash.each do |key2, val2|
112
- #ignore.
112
+ # ignore.
113
113
  end
114
-
114
+
115
115
  if key > 500
116
116
  true
117
117
  else
@@ -120,55 +120,51 @@ describe "Tsafe::Rwmutex" do
120
120
  end
121
121
  end
122
122
  end
123
-
124
- ts.each do |t|
125
- t.join
126
- end
123
+
124
+ ts.each(&:join)
127
125
  end
128
126
  end
129
-
127
+
130
128
  it "should not be able to write while reading from same thread" do
131
129
  hash = Tsafe::MonHash.new
132
130
  0.upto(1000) do |count|
133
131
  hash[count] = count
134
132
  end
135
-
133
+
136
134
  begin
137
- hash.each do |key, val|
135
+ hash.each do |key, _val|
138
136
  hash.delete(key)
139
137
  end
140
-
138
+
141
139
  raise "Expected ThreadError but didnt get raised."
142
- rescue ThreadError
143
- #ignore - supposed to happen.
140
+ rescue ThreadError # rubocop:disable Lint/HandleExceptions
141
+ # Ignore - supposed to happen.
144
142
  end
145
143
  end
146
-
144
+
147
145
  it "should include thread-safe array" do
148
146
  arr = Tsafe::MonArray.new
149
147
  0.upto(1000) do |count|
150
148
  arr << count
151
149
  end
152
-
150
+
153
151
  ts = []
154
152
  0.upto(20) do
155
153
  ts << Thread.new do
156
154
  arr.each do |i|
157
- something = i + 100 / 5
155
+ i + 100 / 5
158
156
  end
159
-
157
+
160
158
  0.upto(1000) do |count|
161
159
  arr << count + 1000
162
160
  end
163
-
161
+
164
162
  arr.delete_if do |count|
165
163
  count > 1000
166
164
  end
167
165
  end
168
166
  end
169
-
170
- ts.each do |t|
171
- t.join
172
- end
167
+
168
+ ts.each(&:join)
173
169
  end
174
170
  end
@@ -1,12 +1,11 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
2
2
  $LOAD_PATH.unshift(File.dirname(__FILE__))
3
- require 'rspec'
4
- require 'tsafe'
3
+ require "rspec"
4
+ require "tsafe"
5
5
 
6
6
  # Requires supporting files with custom matchers and macros, etc,
7
7
  # in ./support/ and its subdirectories.
8
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
9
9
 
10
10
  RSpec.configure do |config|
11
-
12
11
  end
@@ -1,58 +1,57 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
2
 
3
3
  describe "Tsafe" do
4
4
  it "should be able to spawn threadsafe proxy-objects" do
5
- arr = Tsafe::Proxy.new(:obj => {})
6
-
5
+ arr = Tsafe::Proxy.new(obj: {})
6
+
7
7
  0.upto(5) do |i|
8
8
  arr[i] = i
9
9
  end
10
-
10
+
11
11
  Thread.new do
12
12
  begin
13
- arr.each do |key, val|
14
- res = key + val
13
+ arr.each do
15
14
  sleep 0.1
16
15
  end
17
- rescue Exception => e
18
- print e.inspect
16
+ rescue Exception => e # rubocop:disable Lint/RescueException
17
+ puts e.inspect
19
18
  end
20
19
  end
21
-
20
+
22
21
  5.upto(10) do |i|
23
22
  arr[i] = i
24
23
  sleep 0.1
25
24
  end
26
25
  end
27
-
26
+
28
27
  it "should be able to spawn special classes" do
29
- #Create new synchronized hash.
28
+ # Create new synchronized hash.
30
29
  arr = Tsafe::MonHash.new
31
-
32
- #Make sure we get the right results.
30
+
31
+ # Make sure we get the right results.
33
32
  arr[1] = 2
34
-
33
+
35
34
  res = arr[1]
36
- raise "Expected 2 but got '#{res}'." if res != 2
37
-
38
- #Set some values to test with.
35
+ raise "Expected 2 but got '#{res}'." unless res == 2
36
+
37
+ # Set some values to test with.
39
38
  0.upto(5) do |i|
40
39
  arr[i] = i
41
40
  end
42
-
43
- #Try to call through each through a thread and then also try to set new values, which normally would crash the hash.
41
+
42
+ # Try to call through each through a thread and then also try to set new values, which normally would crash the hash.
44
43
  Thread.new do
45
44
  begin
46
45
  arr.each do |key, val|
47
46
  res = key + val
48
47
  sleep 0.1
49
48
  end
50
- rescue Exception => e
51
- print e.inspect
49
+ rescue Exception => e # rubocop:disable Lint/RescueException
50
+ puts e.inspect
52
51
  end
53
52
  end
54
-
55
- #This should not crash it, since they should wait for each other.
53
+
54
+ # This should not crash it, since they should wait for each other.
56
55
  5.upto(10) do |i|
57
56
  arr[i] = i
58
57
  sleep 0.1