rubysl-monitor 2.0.0 → 2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7362242f7582618baaf408e9c8eb46b1bc5c85e2
4
- data.tar.gz: bb1f3e3984987a4143417554aa7526e59b76d54e
3
+ metadata.gz: 58131016ac8f1dad3c38a2e60589dabbf189495e
4
+ data.tar.gz: ef3fd837b8753599ae54ec05b174ba8045bfbf8f
5
5
  SHA512:
6
- metadata.gz: 9f7a6cca87b357fc057709c176dfb7c7104d6fca0e6c3b446c4768c6045933111f88aa54184726f75467d8b9d9c8a0df00b8dc4eacb41e833c2419046e98b1fa
7
- data.tar.gz: 94bc9048a65ea57066ef16059b37aa07b1d973ba795da46693acdfe0d43fffc2b033b8ebfe6c0f23bc36d6105ad38c6271c94214bd5bee4f9df6ae3507e21aa2
6
+ metadata.gz: ca0bfdd83ac029c99a1806a2b7b8591341846dfe63fe998f8f35642771735f60da0a076c2e29ac42e276d4e6952ed12e2cdbb427027edd850255275c001684dd
7
+ data.tar.gz: ce649beccca122344d9387a09203ca412ec40a6b6fb73f9124a04cba9d91b42284e1f4cf91c55544a94fe3043a6a9543e0e9c5327a2ea8b50cdcc4a86cdfd5d7
@@ -1,7 +1,14 @@
1
1
  language: ruby
2
2
  env:
3
3
  - RUBYLIB=lib
4
- script: bundle exec mspec
4
+ - RUBYLIB=
5
+ script: mspec spec
5
6
  rvm:
6
- - 1.9.3
7
- - rbx-nightly-19mode
7
+ - 2.0.0
8
+ - rbx-2.2.1
9
+ matrix:
10
+ exclude:
11
+ - rvm: 2.0.0
12
+ env: RUBYLIB=lib
13
+ - rvm: rbx-2.2.1
14
+ env: RUBYLIB=
@@ -0,0 +1,56 @@
1
+ Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
2
+ You can redistribute it and/or modify it under either the terms of the
3
+ 2-clause BSDL (see the file BSDL), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) give non-standard binaries non-standard names, with
21
+ instructions on where to get the original software distribution.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or binary form,
26
+ provided that you do at least ONE of the following:
27
+
28
+ a) distribute the binaries and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c) give non-standard binaries non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under these terms.
43
+
44
+ For the list of those files and their copying conditions, see the
45
+ file LEGAL.
46
+
47
+ 5. The scripts and library files supplied as input to or produced as
48
+ output from the software do not automatically fall under the
49
+ copyright of the software, but belong to whomever generated them,
50
+ and may be sold commercially, and may be aggregated with this
51
+ software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ PURPOSE.
@@ -1 +1,300 @@
1
- require "rubysl/monitor"
1
+ # = monitor.rb
2
+ #
3
+ # Copyright (C) 2001 Shugo Maeda <shugo@ruby-lang.org>
4
+ #
5
+ # This library is distributed under the terms of the Ruby license.
6
+ # You can freely distribute/modify this library.
7
+ #
8
+
9
+ require 'thread'
10
+
11
+ #
12
+ # In concurrent programming, a monitor is an object or module intended to be
13
+ # used safely by more than one thread. The defining characteristic of a
14
+ # monitor is that its methods are executed with mutual exclusion. That is, at
15
+ # each point in time, at most one thread may be executing any of its methods.
16
+ # This mutual exclusion greatly simplifies reasoning about the implementation
17
+ # of monitors compared to reasoning about parallel code that updates a data
18
+ # structure.
19
+ #
20
+ # You can read more about the general principles on the Wikipedia page for
21
+ # Monitors[http://en.wikipedia.org/wiki/Monitor_%28synchronization%29]
22
+ #
23
+ # == Examples
24
+ #
25
+ # === Simple object.extend
26
+ #
27
+ # require 'monitor.rb'
28
+ #
29
+ # buf = []
30
+ # buf.extend(MonitorMixin)
31
+ # empty_cond = buf.new_cond
32
+ #
33
+ # # consumer
34
+ # Thread.start do
35
+ # loop do
36
+ # buf.synchronize do
37
+ # empty_cond.wait_while { buf.empty? }
38
+ # print buf.shift
39
+ # end
40
+ # end
41
+ # end
42
+ #
43
+ # # producer
44
+ # while line = ARGF.gets
45
+ # buf.synchronize do
46
+ # buf.push(line)
47
+ # empty_cond.signal
48
+ # end
49
+ # end
50
+ #
51
+ # The consumer thread waits for the producer thread to push a line to buf
52
+ # while <tt>buf.empty?</tt>. The producer thread (main thread) reads a
53
+ # line from ARGF and pushes it into buf then calls <tt>empty_cond.signal</tt>
54
+ # to notify the consumer thread of new data.
55
+ #
56
+ # === Simple Class include
57
+ #
58
+ # require 'monitor'
59
+ #
60
+ # class SynchronizedArray < Array
61
+ #
62
+ # include MonitorMixin
63
+ #
64
+ # def initialize(*args)
65
+ # super(*args)
66
+ # end
67
+ #
68
+ # alias :old_shift :shift
69
+ # alias :old_unshift :unshift
70
+ #
71
+ # def shift(n=1)
72
+ # self.synchronize do
73
+ # self.old_shift(n)
74
+ # end
75
+ # end
76
+ #
77
+ # def unshift(item)
78
+ # self.synchronize do
79
+ # self.old_unshift(item)
80
+ # end
81
+ # end
82
+ #
83
+ # # other methods ...
84
+ # end
85
+ #
86
+ # +SynchronizedArray+ implements an Array with synchronized access to items.
87
+ # This Class is implemented as subclass of Array which includes the
88
+ # MonitorMixin module.
89
+ #
90
+ module MonitorMixin
91
+ #
92
+ # FIXME: This isn't documented in Nutshell.
93
+ #
94
+ # Since MonitorMixin.new_cond returns a ConditionVariable, and the example
95
+ # above calls while_wait and signal, this class should be documented.
96
+ #
97
+ class ConditionVariable
98
+ class Timeout < Exception; end
99
+
100
+ #
101
+ # Releases the lock held in the associated monitor and waits; reacquires the lock on wakeup.
102
+ #
103
+ # If +timeout+ is given, this method returns after +timeout+ seconds passed,
104
+ # even if no other thread doesn't signal.
105
+ #
106
+ def wait(timeout = nil)
107
+ @monitor.__send__(:mon_check_owner)
108
+ count = @monitor.__send__(:mon_exit_for_cond)
109
+ begin
110
+ @cond.wait(@monitor.instance_variable_get(:@mon_mutex), timeout)
111
+ return true
112
+ ensure
113
+ @monitor.__send__(:mon_enter_for_cond, count)
114
+ end
115
+ end
116
+
117
+ #
118
+ # Calls wait repeatedly while the given block yields a truthy value.
119
+ #
120
+ def wait_while
121
+ while yield
122
+ wait
123
+ end
124
+ end
125
+
126
+ #
127
+ # Calls wait repeatedly until the given block yields a truthy value.
128
+ #
129
+ def wait_until
130
+ until yield
131
+ wait
132
+ end
133
+ end
134
+
135
+ #
136
+ # Wakes up the first thread in line waiting for this lock.
137
+ #
138
+ def signal
139
+ @monitor.__send__(:mon_check_owner)
140
+ @cond.signal
141
+ end
142
+
143
+ #
144
+ # Wakes up all threads waiting for this lock.
145
+ #
146
+ def broadcast
147
+ @monitor.__send__(:mon_check_owner)
148
+ @cond.broadcast
149
+ end
150
+
151
+ private
152
+
153
+ def initialize(monitor)
154
+ @monitor = monitor
155
+ @cond = ::ConditionVariable.new
156
+ end
157
+ end
158
+
159
+ def self.extend_object(obj)
160
+ super(obj)
161
+ obj.__send__(:mon_initialize)
162
+ end
163
+
164
+ #
165
+ # Attempts to enter exclusive section. Returns +false+ if lock fails.
166
+ #
167
+ def mon_try_enter
168
+ if @mon_owner != Thread.current
169
+ unless @mon_mutex.try_lock
170
+ return false
171
+ end
172
+ @mon_owner = Thread.current
173
+ end
174
+ @mon_count += 1
175
+ return true
176
+ end
177
+ # For backward compatibility
178
+ alias try_mon_enter mon_try_enter
179
+
180
+ #
181
+ # Enters exclusive section.
182
+ #
183
+ def mon_enter
184
+ if @mon_owner != Thread.current
185
+ @mon_mutex.lock
186
+ @mon_owner = Thread.current
187
+ end
188
+ @mon_count += 1
189
+ end
190
+
191
+ #
192
+ # Leaves exclusive section.
193
+ #
194
+ def mon_exit
195
+ mon_check_owner
196
+ @mon_count -=1
197
+ if @mon_count == 0
198
+ @mon_owner = nil
199
+ @mon_mutex.unlock
200
+ end
201
+ end
202
+
203
+ #
204
+ # Enters exclusive section and executes the block. Leaves the exclusive
205
+ # section automatically when the block exits. See example under
206
+ # +MonitorMixin+.
207
+ #
208
+ def mon_synchronize
209
+ mon_enter
210
+ begin
211
+ yield
212
+ ensure
213
+ mon_exit
214
+ end
215
+ end
216
+ alias synchronize mon_synchronize
217
+
218
+ #
219
+ # Creates a new MonitorMixin::ConditionVariable associated with the
220
+ # receiver.
221
+ #
222
+ def new_cond
223
+ return ConditionVariable.new(self)
224
+ end
225
+
226
+ private
227
+
228
+ # Use <tt>extend MonitorMixin</tt> or <tt>include MonitorMixin</tt> instead
229
+ # of this constructor. Have look at the examples above to understand how to
230
+ # use this module.
231
+ def initialize(*args)
232
+ super
233
+ mon_initialize
234
+ end
235
+
236
+ # Initializes the MonitorMixin after being included in a class or when an
237
+ # object has been extended with the MonitorMixin
238
+ def mon_initialize
239
+ @mon_owner = nil
240
+ @mon_count = 0
241
+ @mon_mutex = Mutex.new
242
+ end
243
+
244
+ def mon_check_owner
245
+ if @mon_owner != Thread.current
246
+ raise ThreadError, "current thread not owner"
247
+ end
248
+ end
249
+
250
+ def mon_enter_for_cond(count)
251
+ @mon_owner = Thread.current
252
+ @mon_count = count
253
+ end
254
+
255
+ def mon_exit_for_cond
256
+ count = @mon_count
257
+ @mon_owner = nil
258
+ @mon_count = 0
259
+ return count
260
+ end
261
+ end
262
+
263
+ # Use the Monitor class when you want to have a lock object for blocks with
264
+ # mutual exclusion.
265
+ #
266
+ # require 'monitor'
267
+ #
268
+ # lock = Monitor.new
269
+ # lock.synchronize do
270
+ # # exclusive access
271
+ # end
272
+ #
273
+ class Monitor
274
+ include MonitorMixin
275
+ alias try_enter try_mon_enter
276
+ alias enter mon_enter
277
+ alias exit mon_exit
278
+ end
279
+
280
+
281
+ # Documentation comments:
282
+ # - All documentation comes from Nutshell.
283
+ # - MonitorMixin.new_cond appears in the example, but is not documented in
284
+ # Nutshell.
285
+ # - All the internals (internal modules Accessible and Initializable, class
286
+ # ConditionVariable) appear in RDoc. It might be good to hide them, by
287
+ # making them private, or marking them :nodoc:, etc.
288
+ # - RDoc doesn't recognise aliases, so we have mon_synchronize documented, but
289
+ # not synchronize.
290
+ # - mon_owner is in Nutshell, but appears as an accessor in a separate module
291
+ # here, so is hard/impossible to RDoc. Some other useful accessors
292
+ # (mon_count and some queue stuff) are also in this module, and don't appear
293
+ # directly in the RDoc output.
294
+ # - in short, it may be worth changing the code layout in this file to make the
295
+ # documentation easier
296
+
297
+ # Local variables:
298
+ # mode: Ruby
299
+ # tab-width: 8
300
+ # End:
@@ -1,2 +1,3 @@
1
1
  require "rubysl/monitor/version"
2
2
  require "rubysl/monitor/monitor"
3
+ require "monitor"
@@ -1,5 +1,5 @@
1
1
  module RubySL
2
2
  module Monitor
3
- VERSION = "2.0.0"
3
+ VERSION = "2.1"
4
4
  end
5
5
  end
@@ -21,4 +21,5 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
  spec.add_development_dependency "mspec", "~> 1.5"
24
+ spec.add_development_dependency "rubysl-prettyprint", "~> 2.0"
24
25
  end
metadata CHANGED
@@ -1,57 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubysl-monitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: '2.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Shirai
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-17 00:00:00.000000000 Z
11
+ date: 2017-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.3'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '10.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: mspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '1.5'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubysl-prettyprint
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.0'
55
69
  description: Ruby standard library Monitor.
56
70
  email:
57
71
  - brixen@gmail.com
@@ -59,15 +73,15 @@ executables: []
59
73
  extensions: []
60
74
  extra_rdoc_files: []
61
75
  files:
62
- - .gitignore
63
- - .travis.yml
76
+ - ".gitignore"
77
+ - ".travis.yml"
64
78
  - Gemfile
65
79
  - LICENSE
80
+ - MRI_LICENSE
66
81
  - README.md
67
82
  - Rakefile
68
83
  - lib/monitor.rb
69
84
  - lib/rubysl/monitor.rb
70
- - lib/rubysl/monitor/monitor.rb
71
85
  - lib/rubysl/monitor/version.rb
72
86
  - rubysl-monitor.gemspec
73
87
  homepage: https://github.com/rubysl/rubysl-monitor
@@ -80,17 +94,17 @@ require_paths:
80
94
  - lib
81
95
  required_ruby_version: !ruby/object:Gem::Requirement
82
96
  requirements:
83
- - - ~>
97
+ - - "~>"
84
98
  - !ruby/object:Gem::Version
85
99
  version: '2.0'
86
100
  required_rubygems_version: !ruby/object:Gem::Requirement
87
101
  requirements:
88
- - - '>='
102
+ - - ">="
89
103
  - !ruby/object:Gem::Version
90
104
  version: '0'
91
105
  requirements: []
92
106
  rubyforge_project:
93
- rubygems_version: 2.0.7
107
+ rubygems_version: 2.5.1
94
108
  signing_key:
95
109
  specification_version: 4
96
110
  summary: Ruby standard library Monitor.
@@ -1,300 +0,0 @@
1
- # = monitor.rb
2
- #
3
- # Copyright (C) 2001 Shugo Maeda <shugo@ruby-lang.org>
4
- #
5
- # This library is distributed under the terms of the Ruby license.
6
- # You can freely distribute/modify this library.
7
- #
8
-
9
- require 'thread'
10
-
11
- #
12
- # In concurrent programming, a monitor is an object or module intended to be
13
- # used safely by more than one thread. The defining characteristic of a
14
- # monitor is that its methods are executed with mutual exclusion. That is, at
15
- # each point in time, at most one thread may be executing any of its methods.
16
- # This mutual exclusion greatly simplifies reasoning about the implementation
17
- # of monitors compared to reasoning about parallel code that updates a data
18
- # structure.
19
- #
20
- # You can read more about the general principles on the Wikipedia page for
21
- # Monitors[http://en.wikipedia.org/wiki/Monitor_%28synchronization%29]
22
- #
23
- # == Examples
24
- #
25
- # === Simple object.extend
26
- #
27
- # require 'monitor.rb'
28
- #
29
- # buf = []
30
- # buf.extend(MonitorMixin)
31
- # empty_cond = buf.new_cond
32
- #
33
- # # consumer
34
- # Thread.start do
35
- # loop do
36
- # buf.synchronize do
37
- # empty_cond.wait_while { buf.empty? }
38
- # print buf.shift
39
- # end
40
- # end
41
- # end
42
- #
43
- # # producer
44
- # while line = ARGF.gets
45
- # buf.synchronize do
46
- # buf.push(line)
47
- # empty_cond.signal
48
- # end
49
- # end
50
- #
51
- # The consumer thread waits for the producer thread to push a line to buf
52
- # while <tt>buf.empty?</tt>. The producer thread (main thread) reads a
53
- # line from ARGF and pushes it into buf then calls <tt>empty_cond.signal</tt>
54
- # to notify the consumer thread of new data.
55
- #
56
- # === Simple Class include
57
- #
58
- # require 'monitor'
59
- #
60
- # class SynchronizedArray < Array
61
- #
62
- # include MonitorMixin
63
- #
64
- # def initialize(*args)
65
- # super(*args)
66
- # end
67
- #
68
- # alias :old_shift :shift
69
- # alias :old_unshift :unshift
70
- #
71
- # def shift(n=1)
72
- # self.synchronize do
73
- # self.old_shift(n)
74
- # end
75
- # end
76
- #
77
- # def unshift(item)
78
- # self.synchronize do
79
- # self.old_unshift(item)
80
- # end
81
- # end
82
- #
83
- # # other methods ...
84
- # end
85
- #
86
- # +SynchronizedArray+ implements an Array with synchronized access to items.
87
- # This Class is implemented as subclass of Array which includes the
88
- # MonitorMixin module.
89
- #
90
- module MonitorMixin
91
- #
92
- # FIXME: This isn't documented in Nutshell.
93
- #
94
- # Since MonitorMixin.new_cond returns a ConditionVariable, and the example
95
- # above calls while_wait and signal, this class should be documented.
96
- #
97
- class ConditionVariable
98
- class Timeout < Exception; end
99
-
100
- #
101
- # Releases the lock held in the associated monitor and waits; reacquires the lock on wakeup.
102
- #
103
- # If +timeout+ is given, this method returns after +timeout+ seconds passed,
104
- # even if no other thread doesn't signal.
105
- #
106
- def wait(timeout = nil)
107
- @monitor.__send__(:mon_check_owner)
108
- count = @monitor.__send__(:mon_exit_for_cond)
109
- begin
110
- @cond.wait(@monitor.instance_variable_get(:@mon_mutex), timeout)
111
- return true
112
- ensure
113
- @monitor.__send__(:mon_enter_for_cond, count)
114
- end
115
- end
116
-
117
- #
118
- # Calls wait repeatedly while the given block yields a truthy value.
119
- #
120
- def wait_while
121
- while yield
122
- wait
123
- end
124
- end
125
-
126
- #
127
- # Calls wait repeatedly until the given block yields a truthy value.
128
- #
129
- def wait_until
130
- until yield
131
- wait
132
- end
133
- end
134
-
135
- #
136
- # Wakes up the first thread in line waiting for this lock.
137
- #
138
- def signal
139
- @monitor.__send__(:mon_check_owner)
140
- @cond.signal
141
- end
142
-
143
- #
144
- # Wakes up all threads waiting for this lock.
145
- #
146
- def broadcast
147
- @monitor.__send__(:mon_check_owner)
148
- @cond.broadcast
149
- end
150
-
151
- private
152
-
153
- def initialize(monitor)
154
- @monitor = monitor
155
- @cond = ::ConditionVariable.new
156
- end
157
- end
158
-
159
- def self.extend_object(obj)
160
- super(obj)
161
- obj.__send__(:mon_initialize)
162
- end
163
-
164
- #
165
- # Attempts to enter exclusive section. Returns +false+ if lock fails.
166
- #
167
- def mon_try_enter
168
- if @mon_owner != Thread.current
169
- unless @mon_mutex.try_lock
170
- return false
171
- end
172
- @mon_owner = Thread.current
173
- end
174
- @mon_count += 1
175
- return true
176
- end
177
- # For backward compatibility
178
- alias try_mon_enter mon_try_enter
179
-
180
- #
181
- # Enters exclusive section.
182
- #
183
- def mon_enter
184
- if @mon_owner != Thread.current
185
- @mon_mutex.lock
186
- @mon_owner = Thread.current
187
- end
188
- @mon_count += 1
189
- end
190
-
191
- #
192
- # Leaves exclusive section.
193
- #
194
- def mon_exit
195
- mon_check_owner
196
- @mon_count -=1
197
- if @mon_count == 0
198
- @mon_owner = nil
199
- @mon_mutex.unlock
200
- end
201
- end
202
-
203
- #
204
- # Enters exclusive section and executes the block. Leaves the exclusive
205
- # section automatically when the block exits. See example under
206
- # +MonitorMixin+.
207
- #
208
- def mon_synchronize
209
- mon_enter
210
- begin
211
- yield
212
- ensure
213
- mon_exit
214
- end
215
- end
216
- alias synchronize mon_synchronize
217
-
218
- #
219
- # Creates a new MonitorMixin::ConditionVariable associated with the
220
- # receiver.
221
- #
222
- def new_cond
223
- return ConditionVariable.new(self)
224
- end
225
-
226
- private
227
-
228
- # Use <tt>extend MonitorMixin</tt> or <tt>include MonitorMixin</tt> instead
229
- # of this constructor. Have look at the examples above to understand how to
230
- # use this module.
231
- def initialize(*args)
232
- super
233
- mon_initialize
234
- end
235
-
236
- # Initializes the MonitorMixin after being included in a class or when an
237
- # object has been extended with the MonitorMixin
238
- def mon_initialize
239
- @mon_owner = nil
240
- @mon_count = 0
241
- @mon_mutex = Mutex.new
242
- end
243
-
244
- def mon_check_owner
245
- if @mon_owner != Thread.current
246
- raise ThreadError, "current thread not owner"
247
- end
248
- end
249
-
250
- def mon_enter_for_cond(count)
251
- @mon_owner = Thread.current
252
- @mon_count = count
253
- end
254
-
255
- def mon_exit_for_cond
256
- count = @mon_count
257
- @mon_owner = nil
258
- @mon_count = 0
259
- return count
260
- end
261
- end
262
-
263
- # Use the Monitor class when you want to have a lock object for blocks with
264
- # mutual exclusion.
265
- #
266
- # require 'monitor'
267
- #
268
- # lock = Monitor.new
269
- # lock.synchronize do
270
- # # exclusive access
271
- # end
272
- #
273
- class Monitor
274
- include MonitorMixin
275
- alias try_enter try_mon_enter
276
- alias enter mon_enter
277
- alias exit mon_exit
278
- end
279
-
280
-
281
- # Documentation comments:
282
- # - All documentation comes from Nutshell.
283
- # - MonitorMixin.new_cond appears in the example, but is not documented in
284
- # Nutshell.
285
- # - All the internals (internal modules Accessible and Initializable, class
286
- # ConditionVariable) appear in RDoc. It might be good to hide them, by
287
- # making them private, or marking them :nodoc:, etc.
288
- # - RDoc doesn't recognise aliases, so we have mon_synchronize documented, but
289
- # not synchronize.
290
- # - mon_owner is in Nutshell, but appears as an accessor in a separate module
291
- # here, so is hard/impossible to RDoc. Some other useful accessors
292
- # (mon_count and some queue stuff) are also in this module, and don't appear
293
- # directly in the RDoc output.
294
- # - in short, it may be worth changing the code layout in this file to make the
295
- # documentation easier
296
-
297
- # Local variables:
298
- # mode: Ruby
299
- # tab-width: 8
300
- # End: