tsafe 0.0.11 → 0.0.12

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.
@@ -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