threadlock 1.2.1 → 1.3.0
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.
- checksums.yaml +4 -4
- data/USAGE.rb +172 -0
- data/lib/threadlock.rb +9 -30
- metadata +9 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af828e08328bf0b3a7d811cacae465fd81f9a4ae
|
4
|
+
data.tar.gz: 3c6da6bc34e39ec90eb92a6cc6b64c688a58d18f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4487deaa6998d99bee44689cd8d0e71c84f45b35e78e98eb1e375f5ec10613ffdb8c3f3c3e9044fadbcc310ba43b18533fe130932b130eedc5b14792c2d13cab
|
7
|
+
data.tar.gz: 920c155bf9445bfe699562563aa1b61ce25b12f77a5581bfd2927c005c345f379b970d4ff40c5fa6a2843feba5bfa95c882f2e28a8abad0f55bed6d805b0e2ff
|
data/USAGE.rb
ADDED
@@ -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!"
|
data/lib/threadlock.rb
CHANGED
@@ -1,35 +1,14 @@
|
|
1
1
|
require 'monitor'
|
2
2
|
|
3
|
-
def threadlock(*
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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.
|
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-
|
11
|
+
date: 2013-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description:
|
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.
|
17
|
-
|
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.
|
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.'
|