threadlock 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/USAGE.rb +172 -0
  3. data/lib/threadlock.rb +9 -30
  4. metadata +9 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5572ec2bfc12ce846c7ebedc66bd8e072dd7d96f
4
- data.tar.gz: 49bae1342466bab33abec0830b028bb10cf1a4cd
3
+ metadata.gz: af828e08328bf0b3a7d811cacae465fd81f9a4ae
4
+ data.tar.gz: 3c6da6bc34e39ec90eb92a6cc6b64c688a58d18f
5
5
  SHA512:
6
- metadata.gz: 7cbc19433166cb2688d8fb2b5562bbde9a844371e0c477692a1fbeaf232872c8092c2847ce3d75698ffb0dc11d80897d3cb65bf32519efddd94c17c0f4fb5bbe
7
- data.tar.gz: b9796a59a4b08e96f3534cc56320c716ae39cf2ca6e028068d7de0a3898e198af7b109d8c2a569b6dab275aef26d82d9c560d2f07d9cd19a39f58250b74d6e80
6
+ metadata.gz: 4487deaa6998d99bee44689cd8d0e71c84f45b35e78e98eb1e375f5ec10613ffdb8c3f3c3e9044fadbcc310ba43b18533fe130932b130eedc5b14792c2d13cab
7
+ data.tar.gz: 920c155bf9445bfe699562563aa1b61ce25b12f77a5581bfd2927c005c345f379b970d4ff40c5fa6a2843feba5bfa95c882f2e28a8abad0f55bed6d805b0e2ff
@@ -0,0 +1,172 @@
1
+ $LOAD_PATH.unshift(File.expand_path("./lib", File.dirname(__FILE__)))
2
+ require 'threadlock'
3
+
4
+
5
+ class Example1
6
+
7
+ def foo
8
+ @foo = true
9
+ raise "not synchronized!" if @bar
10
+ sleep 0.2
11
+ raise "not synchronized!" if @bar
12
+ @foo = false
13
+ end
14
+
15
+ def bar
16
+ @bar = true
17
+ raise "not synchronized!" if @foo
18
+ sleep 0.2
19
+ raise "not synchronized!" if @foo
20
+ @bar = false
21
+ end
22
+
23
+ # Wrap foo and bar methods in a re-entrant lock
24
+ threadlock :foo
25
+ threadlock :bar
26
+
27
+ end
28
+
29
+
30
+ class Example2
31
+
32
+ def foo
33
+ @foo = true
34
+ raise "not synchronized!" if @bar
35
+ sleep 0.2
36
+ raise "not synchronized!" if @bar
37
+ @foo = false
38
+ end
39
+
40
+ def bar
41
+ @bar = true
42
+ raise "not synchronized!" if @foo
43
+ sleep 0.2
44
+ raise "not synchronized!" if @foo
45
+ @bar = false
46
+ end
47
+
48
+ # Wrap foo and bar methods in a re-entrant lock
49
+ threadlock :foo, :bar
50
+
51
+ end
52
+
53
+
54
+ class Example3
55
+
56
+ def foo
57
+ @foo = true
58
+ raise "not synchronized!" if @bar
59
+ sleep 0.2
60
+ raise "not synchronized!" if @bar
61
+ @foo = false
62
+ end
63
+
64
+ def bar
65
+ @bar = true
66
+ raise "not synchronized!" if @foo
67
+ sleep 0.2
68
+ raise "not synchronized!" if @foo
69
+ @bar = false
70
+ end
71
+
72
+ # Wrap all newly defined instance methods in a re-entrant lock
73
+ threadlock instance_methods(false)
74
+
75
+ end
76
+
77
+
78
+ class Example4
79
+
80
+ def foo
81
+ @foo = true
82
+ raise "not synchronized!" if @bar
83
+ sleep 0.2
84
+ raise "not synchronized!" if @bar
85
+ @foo = false
86
+ end
87
+
88
+ def bar
89
+ @bar = true
90
+ raise "not synchronized!" if @foo
91
+ sleep 0.2
92
+ raise "not synchronized!" if @foo
93
+ @bar = false
94
+ end
95
+
96
+ # Wrap foo and bar methods in a re-entrant lock named custom_lock_name
97
+ # (default lock name is :@__threadlock__)
98
+ threadlock :foo, :bar, :lock=>:@custom_lock_name
99
+
100
+ end
101
+
102
+
103
+ class Example5
104
+
105
+ def initialize
106
+ @custom_lock_name = Mutex.new
107
+ end
108
+
109
+ def foo
110
+ @foo = true
111
+ raise "not synchronized!" if @bar
112
+ sleep 0.2
113
+ raise "not synchronized!" if @bar
114
+ @foo = false
115
+ end
116
+
117
+ def bar
118
+ @bar = true
119
+ raise "not synchronized!" if @foo
120
+ sleep 0.2
121
+ raise "not synchronized!" if @foo
122
+ @bar = false
123
+ end
124
+
125
+ # Wrap foo and bar methods in a mutex instead of a re-entrant lock
126
+ threadlock :foo, :bar, :lock=>:@custom_lock_name
127
+
128
+ end
129
+
130
+
131
+ class Example6 # Ruby 2.1 only
132
+
133
+ # Ruby 2.1 only: wrap new method foo in a re-entrant lock
134
+ threadlock def foo
135
+ @foo = true
136
+ raise "not synchronized!" if @bar
137
+ sleep 0.2
138
+ raise "not synchronized!" if @bar
139
+ @foo = false
140
+ end
141
+
142
+ def bar
143
+ @bar = true
144
+ raise "not synchronized!" if @foo
145
+ sleep 0.2
146
+ raise "not synchronized!" if @foo
147
+ @bar = false
148
+ end
149
+
150
+ # Wrap method bar in the same re-entrant lock
151
+ threadlock :bar
152
+
153
+ end if RUBY_VERSION>="2.1.0"
154
+
155
+
156
+ # Run tests on Example classes - raise if error
157
+ [
158
+ Example1,
159
+ Example2,
160
+ Example3,
161
+ Example4,
162
+ Example5,
163
+ (Example6 if RUBY_VERSION>="2.1.0"), # Ruby 2.1 only
164
+ ].each do |cls|
165
+ break unless cls
166
+ puts "testing #{cls}"
167
+ obj = cls.new
168
+ [Thread.new { obj.foo }, Thread.new { obj.bar }]
169
+ .each { |t| t.join }
170
+ end
171
+
172
+ puts "passed tests!"
@@ -1,35 +1,14 @@
1
1
  require 'monitor'
2
2
 
3
- def threadlock(*funcs, lock: :@___threadlock___)
4
- for f in funcs.flatten
5
- f2 = f.to_s
6
- .gsub(/\=/, "_eQUAL")
7
- .gsub(/\!/, "_nOT")
8
- .gsub(/\~/, "_tILDE")
9
- .gsub(/\</, "_lESS")
10
- .gsub(/\>/, "_mORE")
11
- .gsub(/\+/, "_aDD")
12
- .gsub(/\-/, "_sUB")
13
- .gsub(/\*/, "_mULT")
14
- .gsub(/\//, "_dIV")
15
- .gsub(/\%/, "_mOD")
16
- .gsub(/\[/, "_bRACKO")
17
- .gsub(/\]/, "_bRACKC")
18
- .gsub(/\@/, "_aTTR")
19
- .gsub(/\&/, "_aMPER")
20
- .gsub(/\|/, "_pIPE")
21
- .gsub(/\^/, "_cARET")
22
- .gsub(/^/, "___")
23
-
24
- class_eval\
25
- ("
26
- alias :#{f2} :#{f}
27
- def #{f}(*args, &block)
28
- #{lock.to_s} ||= Monitor.new
29
- #{lock.to_s}.synchronize do
30
- #{f2}(*args, &block)
31
- end
3
+ def threadlock(*meths, lock: :@___threadlock___)
4
+ meths.flatten.each do |meth|
5
+ m = instance_method(meth)
6
+ define_method(meth) do |*args|
7
+ (instance_variable_get(lock) or \
8
+ instance_variable_set(lock, Monitor.new))
9
+ .synchronize do
10
+ m.bind(self).call(*args)
32
11
  end
33
- ")
12
+ end
34
13
  end
35
14
  end
metadata CHANGED
@@ -1,23 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: threadlock
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe McIlvain
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-22 00:00:00.000000000 Z
11
+ date: 2013-09-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: "Use the threadlock function in your class definition to automatically
13
+ description: 'Use the threadlock function in your class definition to automatically
14
14
  run instance methods inside of an instance-wide re-entrant lock (Monitor). All
15
15
  locked methods in an instance are protect by a single lock. You can protect all
16
- or some of your methods from being run asynchronously. The goal is to be able to
17
- easily make basic objects threadsafe with as little thought and code as using the
18
- attr_accessor family of functions to make your instance attributes accessible. The
19
- codebase is small and I intend to keep it that way, but bug reports and patches
20
- are welcome. \n Enjoy."
16
+ or some of your methods from being run asynchronously. In Ruby>=2.1, threadlock
17
+ can also be syntactically used as a decorator. '
21
18
  email: joe.eli.mac@gmail.com
22
19
  executables: []
23
20
  extensions: []
@@ -26,6 +23,7 @@ files:
26
23
  - lib/threadlock.rb
27
24
  - LICENSE
28
25
  - README.md
26
+ - USAGE.rb
29
27
  homepage: https://github.com/jemc/threadlock/
30
28
  licenses:
31
29
  - MIT License
@@ -37,17 +35,17 @@ require_paths:
37
35
  - lib
38
36
  required_ruby_version: !ruby/object:Gem::Requirement
39
37
  requirements:
40
- - - '>='
38
+ - - ">="
41
39
  - !ruby/object:Gem::Version
42
40
  version: '0'
43
41
  required_rubygems_version: !ruby/object:Gem::Requirement
44
42
  requirements:
45
- - - '>='
43
+ - - ">="
46
44
  - !ruby/object:Gem::Version
47
45
  version: '0'
48
46
  requirements: []
49
47
  rubyforge_project:
50
- rubygems_version: 2.0.2
48
+ rubygems_version: 2.1.5
51
49
  signing_key:
52
50
  specification_version: 4
53
51
  summary: 'threadlock: Easy, featherweight thread protection for basic ruby objects.'