tsafe 0.0.6 → 0.0.9

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.
@@ -9,6 +9,7 @@ GEM
9
9
  rake
10
10
  rdoc
11
11
  json (1.7.3)
12
+ json (1.7.3-java)
12
13
  rake (0.9.2.2)
13
14
  rdoc (3.12)
14
15
  json (~> 1.4)
@@ -22,6 +23,7 @@ GEM
22
23
  rspec-mocks (2.8.0)
23
24
 
24
25
  PLATFORMS
26
+ java
25
27
  ruby
26
28
 
27
29
  DEPENDENCIES
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.6
1
+ 0.0.9
@@ -4,14 +4,21 @@ require "monitor"
4
4
  module Tsafe
5
5
  #Autoloader for subclasses.
6
6
  def self.const_missing(name)
7
- require "#{File.dirname(__FILE__)}/tsafe_#{name.to_s.downcase}.rb"
7
+ filep = "#{File.dirname(__FILE__)}/tsafe_#{name.to_s.downcase}"
8
+
9
+ if RUBY_ENGINE == "jruby" and File.exists?("#{filep}_jruby.rb")
10
+ require "#{filep}_jruby.rb"
11
+ else
12
+ require filep
13
+ end
14
+
8
15
  raise "Still not loaded: '#{name}'." if !Tsafe.const_defined?(name)
9
16
  return Tsafe.const_get(name)
10
17
  end
11
18
 
12
- #JRuby can corrupt an array in a threadded env. Use this method to only get a synchronized array when running JRuby and not having to write "if RUBY_ENGINE"-stuff.
19
+ #JRuby can corrupt an array in a threadded env. Use this method to only get a synchronized array when running JRuby in order to not having to write "if RUBY_ENGINE"-stuff.
13
20
  def self.std_array
14
- return MonArray.new if RUBY_ENGINE == "jruby"
21
+ return Tsafe::MonArray.new if RUBY_ENGINE == "jruby"
15
22
  return []
16
23
  end
17
24
  end
@@ -8,5 +8,5 @@ class Tsafe::MonArray < ::Array
8
8
  @@tsafe_rwmutex_w_methods = [:<<, :collect, :collect!, :compact!, :delete, :delete_at, :delete_if, :drop, :drop_while, :fill, :flatten!, :insert, :keep_if, :map, :map!, :replace, :shuffle!, :slice!, :shift, :sort!, :sort_by!, :unshift]
9
9
  @@tsafe_rwmutex_r_methods = [:each, :each_index, :take_while]
10
10
 
11
- include Tsafe::SynModule
11
+ include Tsafe::Mrswlock_synmodule
12
12
  end
@@ -8,5 +8,5 @@ class Tsafe::MonHash < ::Hash
8
8
  @@tsafe_mrswlock_w_methods = [:[]=, :clear, :delete, :delete_if, :keep_if, :merge!, :rehash, :reject!, :replace, :select!, :shift, :store, :update, :values_at]
9
9
  @@tsafe_mrswlock_r_methods = [:each, :each_key, :each_pair, :each_value]
10
10
 
11
- include Tsafe::Mrswlock::SynModule
11
+ include Tsafe::Mrswlock_synmodule
12
12
  end
@@ -1,7 +1,7 @@
1
- #A class that allows many simultanious read-synchronizations but locks both reading and writing while calling the write-synchronzie-method.
1
+ # A class that allows many simultanious read-synchronizations but locks both reading and writing while calling the write-synchronzie-method.
2
+ # This version does not work in JRuby! 'const_missing'-autoloader should automatically load the JRuby-version.
3
+ # It is not 'actually' thread-safe, but because of GIL, it wont bug up. If it was actually thread-safe, the performance would go down. So it only works with GIL.
2
4
  class Tsafe::Mrswlock
3
- @@debug = false
4
-
5
5
  # Sets various variables.
6
6
  def initialize
7
7
  @reads = 0
@@ -18,15 +18,9 @@ class Tsafe::Mrswlock
18
18
  def rsync
19
19
  begin
20
20
  tid = Thread.current.__id__
21
-
22
- while @w_mutex.locked? and @locked_by != tid
23
- Thread.pass
24
- print "Passed because lock.\n" if @@debug
25
- end
26
-
21
+ Thread.pass while @w_mutex.locked? and @locked_by != tid
27
22
  @reading_threads[tid] = true
28
23
  @reads += 1
29
- print "Reading more than one at a time! (#{@reads})\n" if @@debug and @reads >= 2
30
24
  yield
31
25
  ensure
32
26
  @reading_threads.delete(tid)
@@ -48,12 +42,8 @@ class Tsafe::Mrswlock
48
42
  #Wait for any reads to finish that might have started while we were getting the lock.
49
43
  #Also allow write if there is only one reading thread and that reading thread is the current thread.
50
44
  while @reads > 0
51
- if @reading_threads.key?(tid)
52
- raise ThreadError, "Deadlock: Writing is not allowed while reading."
53
- end
54
-
45
+ raise ThreadError, "Deadlock: Writing is not allowed while reading." if @reading_threads.key?(tid)
55
46
  Thread.pass
56
- print "Passed because reading.\n" if @@debug
57
47
  end
58
48
 
59
49
  yield
@@ -62,68 +52,4 @@ class Tsafe::Mrswlock
62
52
  end
63
53
  end
64
54
  end
65
-
66
- #This module can be included in order to painlessly make a thread-safe multi-reader-single-writer thread-safe copy of a class.
67
- #===Examples
68
- # class Tsafe::MonHash < ::Hash
69
- # @@tsafe_mrswlock_w_methods = [:[]=, :clear, :delete, :delete_if, :keep_if, :merge!, :rehash, :reject!, :replace, :select!, :shift, :store, :update, :values_at]
70
- # @@tsafe_mrswlock_r_methods = [:each, :each_key, :each_pair, :each_value]
71
- # include Tsafe::Mrswlock::SynModule
72
- # end
73
- module SynModule
74
- def self.included(base)
75
- base.to_s.split("::").inject(Object, :const_get).class_eval do
76
- #Yields the given block within the read-lock.
77
- #===Examples
78
- # obj._tsafe_rsync do
79
- # #do something within read-lock.
80
- # end
81
- def _tsafe_rsync(&block)
82
- @tsafe_mrswlock.rsync(&block)
83
- end
84
-
85
- #Yields the given block within the write-lock (and read-lock).
86
- #===Examples
87
- # obj._tsafe_wsync do
88
- # #do something within write-lock.
89
- # end
90
- def _tsafe_wsync(&block)
91
- @tsafe_mrswlock.rsync(&block)
92
- end
93
-
94
- #Rename initialize.
95
- alias_method(:initialize_mrswlock, :initialize)
96
-
97
- #Make another initialize-method that spawns the lock and then calls the original initialize.
98
- define_method(:initialize) do |*args, &block|
99
- @tsafe_mrswlock = Tsafe::Mrswlock.new
100
- return initialize_mrswlock(*args, &block)
101
- end
102
-
103
- #Makes reader methods go through reader-lock.
104
- base.class_variable_get(:@@tsafe_mrswlock_r_methods).each do |mname|
105
- newmname = "tsafe_mrswlock_#{mname}".to_sym
106
- alias_method(newmname, mname)
107
-
108
- define_method(mname) do |*args, &block|
109
- @tsafe_mrswlock.rsync do
110
- return self.__send__(newmname, *args, &block)
111
- end
112
- end
113
- end
114
-
115
- #Makes writer methods go through writer-lock.
116
- base.class_variable_get(:@@tsafe_mrswlock_w_methods).each do |mname|
117
- newmname = "tsafe_mrswlock_#{mname}".to_sym
118
- alias_method(newmname, mname)
119
-
120
- define_method(mname) do |*args, &block|
121
- @tsafe_mrswlock.wsync do
122
- return self.__send__(newmname, *args, &block)
123
- end
124
- end
125
- end
126
- end
127
- end
128
- end
129
55
  end
@@ -0,0 +1,45 @@
1
+ require "java"
2
+
3
+ # A class that allows many simultanious read-synchronizations but locks both reading and writing while calling the write-synchronzie-method.
4
+ # This is the JRuby-version and will not work under anything else. It uses 'java.util.concurrent.locks.ReentrantReadWriteLock' instead of doing the locking in Ruby.
5
+ class Tsafe::Mrswlock
6
+ # Sets various variables.
7
+ def initialize
8
+ @lock = java.util.concurrent.locks.ReentrantReadWriteLock.new
9
+
10
+ #This hash holds thread-IDs for threads that are reading.
11
+ @reading_threads = {}
12
+ end
13
+
14
+ # Runs the given block through the read-synchronization.
15
+ def rsync
16
+ @lock.read_lock.lock
17
+ tid = Thread.current.__id__
18
+ @reading_threads[tid] = true
19
+
20
+ begin
21
+ yield
22
+ ensure
23
+ @reading_threads.delete(tid)
24
+ @lock.read_lock.unlock
25
+ end
26
+ end
27
+
28
+ #Runs the given block through the write-synchronization (locks both reading and writing).
29
+ #===Examples
30
+ # lock.wsync do
31
+ # #do something within lock.
32
+ # end
33
+ def wsync
34
+ tid = Thread.current.__id__
35
+ raise ThreadError, "Deadlock: Writing is not allowed while reading." if @reading_threads.key?(tid)
36
+
37
+ begin
38
+ @wlock_by = tid
39
+ @lock.write_lock.lock
40
+ yield
41
+ ensure
42
+ @lock.write_lock.unlock
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,63 @@
1
+ # This module can be included in order to painlessly make a thread-safe multi-reader-single-writer thread-safe copy of a class.
2
+ #===Examples
3
+ # class Tsafe::MonHash < ::Hash
4
+ # @@tsafe_mrswlock_w_methods = [:[]=, :clear, :delete, :delete_if, :keep_if, :merge!, :rehash, :reject!, :replace, :select!, :shift, :store, :update, :values_at]
5
+ # @@tsafe_mrswlock_r_methods = [:each, :each_key, :each_pair, :each_value]
6
+ # include Tsafe::Mrswlock::SynModule
7
+ # end
8
+ module Tsafe::Mrswlock_synmodule
9
+ def self.included(base)
10
+ base.to_s.split("::").inject(Object, :const_get).class_eval do
11
+ #Yields the given block within the read-lock.
12
+ #===Examples
13
+ # obj._tsafe_rsync do
14
+ # #do something within read-lock.
15
+ # end
16
+ def _tsafe_rsync(&block)
17
+ @tsafe_mrswlock.rsync(&block)
18
+ end
19
+
20
+ #Yields the given block within the write-lock (and read-lock).
21
+ #===Examples
22
+ # obj._tsafe_wsync do
23
+ # #do something within write-lock.
24
+ # end
25
+ def _tsafe_wsync(&block)
26
+ @tsafe_mrswlock.rsync(&block)
27
+ end
28
+
29
+ #Rename initialize.
30
+ alias_method(:initialize_mrswlock, :initialize)
31
+
32
+ #Make another initialize-method that spawns the lock and then calls the original initialize.
33
+ define_method(:initialize) do |*args, &block|
34
+ @tsafe_mrswlock = Tsafe::Mrswlock.new
35
+ return initialize_mrswlock(*args, &block)
36
+ end
37
+
38
+ #Makes reader methods go through reader-lock.
39
+ base.class_variable_get(:@@tsafe_mrswlock_r_methods).each do |mname|
40
+ newmname = "tsafe_mrswlock_#{mname}".to_sym
41
+ alias_method(newmname, mname)
42
+
43
+ define_method(mname) do |*args, &block|
44
+ @tsafe_mrswlock.rsync do
45
+ return self.__send__(newmname, *args, &block)
46
+ end
47
+ end
48
+ end
49
+
50
+ #Makes writer methods go through writer-lock.
51
+ base.class_variable_get(:@@tsafe_mrswlock_w_methods).each do |mname|
52
+ newmname = "tsafe_mrswlock_#{mname}".to_sym
53
+ alias_method(newmname, mname)
54
+
55
+ define_method(mname) do |*args, &block|
56
+ @tsafe_mrswlock.wsync do
57
+ return self.__send__(newmname, *args, &block)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{tsafe}
8
- s.version = "0.0.6"
8
+ s.version = "0.0.9"
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"]
12
- s.date = %q{2012-07-25}
12
+ s.date = %q{2012-07-27}
13
13
  s.description = %q{Proxy-objects for making another object threadsafe by proxying calls through mutex and method_missing. Monitored array and hash where all methods are going through monitor. Threadsafe class for including into a class that extends another class in order to make it threadsafe.}
14
14
  s.email = %q{k@spernj.org}
15
15
  s.extra_rdoc_files = [
@@ -30,6 +30,8 @@ Gem::Specification.new do |s|
30
30
  "lib/tsafe_monhash.rb",
31
31
  "lib/tsafe_monitored.rb",
32
32
  "lib/tsafe_mrswlock.rb",
33
+ "lib/tsafe_mrswlock_jruby.rb",
34
+ "lib/tsafe_mrswlock_synmodule.rb",
33
35
  "lib/tsafe_mutexed.rb",
34
36
  "lib/tsafe_proxy.rb",
35
37
  "spec/mrswlock_spec.rb",
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: tsafe
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.6
5
+ version: 0.0.9
6
6
  platform: ruby
7
7
  authors:
8
8
  - Kasper Johansen
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-07-25 00:00:00 +02:00
13
+ date: 2012-07-27 00:00:00 +02:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -80,6 +80,8 @@ files:
80
80
  - lib/tsafe_monhash.rb
81
81
  - lib/tsafe_monitored.rb
82
82
  - lib/tsafe_mrswlock.rb
83
+ - lib/tsafe_mrswlock_jruby.rb
84
+ - lib/tsafe_mrswlock_synmodule.rb
83
85
  - lib/tsafe_mutexed.rb
84
86
  - lib/tsafe_proxy.rb
85
87
  - spec/mrswlock_spec.rb
@@ -100,7 +102,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
102
  requirements:
101
103
  - - ">="
102
104
  - !ruby/object:Gem::Version
103
- hash: 1466962052017061704
105
+ hash: 3863386299653534485
104
106
  segments:
105
107
  - 0
106
108
  version: "0"