1
1
require 'concurrent/atomic/condition'
2
2
3
3
module Concurrent
4
-
5
4
class MutexSemaphore
6
-
7
5
# @!macro [attach] semaphore_method_initialize
8
6
#
9
7
# Create a new `Semaphore` with the initial `count`.
@@ -13,7 +11,7 @@ class MutexSemaphore
13
11
# @raise [ArgumentError] if `count` is not an integer or is less than zero
14
12
def initialize ( count )
15
13
unless count . is_a? ( Fixnum ) && count >= 0
16
- raise ArgumentError . new ( 'count must be an non-negative integer' )
14
+ fail ArgumentError , 'count must be an non-negative integer'
17
15
end
18
16
@mutex = Mutex . new
19
17
@condition = Condition . new
@@ -22,16 +20,18 @@ def initialize(count)
22
20
23
21
# @!macro [attach] semaphore_method_acquire
24
22
#
25
- # Acquires the given number of permits from this semaphore, blocking until all are available.
23
+ # Acquires the given number of permits from this semaphore,
24
+ # blocking until all are available.
26
25
#
27
26
# @param [Fixnum] permits Number of permits to acquire
28
27
#
29
- # @raise [ArgumentError] if `permits` is not an integer or is less than one
28
+ # @raise [ArgumentError] if `permits` is not an integer or is less than
29
+ # one
30
30
#
31
31
# @return [True]
32
32
def acquire ( permits = 1 )
33
33
unless permits . is_a? ( Fixnum ) && permits > 0
34
- raise ArgumentError . new ( 'permits must be an integer greater than zero' )
34
+ fail ArgumentError , 'permits must be an integer greater than zero'
35
35
end
36
36
@mutex . synchronize do
37
37
try_acquire_timed ( permits , nil )
@@ -60,19 +60,23 @@ def drain_permits
60
60
61
61
# @!macro [attach] semaphore_method_try_acquire
62
62
#
63
- # Acquires the given number of permits from this semaphore, only if all are available at the time of invocation.
63
+ # Acquires the given number of permits from this semaphore,
64
+ # only if all are available at the time of invocation or within
65
+ # `timeout` interval
64
66
#
65
67
# @param [Fixnum] permits the number of permits to acquire
66
68
#
67
- # @param [Fixnum] timeout the number of seconds to wait for the counter or `nil`
68
- # to return immediately
69
+ # @param [Fixnum] timeout the number of seconds to wait for the counter
70
+ # or `nil` to return immediately
69
71
#
70
- # @raise [ArgumentError] if `permits` is not an integer or is less than one
72
+ # @raise [ArgumentError] if `permits` is not an integer or is less than
73
+ # one
71
74
#
72
- # @return [Boolean] `false` if no permits are available, `true` when acquired a permit
75
+ # @return [Boolean] `false` if no permits are available, `true` when
76
+ # acquired a permit
73
77
def try_acquire ( permits = 1 , timeout = nil )
74
78
unless permits . is_a? ( Fixnum ) && permits > 0
75
- raise ArgumentError . new ( 'permits must be an integer greater than zero' )
79
+ fail ArgumentError , 'permits must be an integer greater than zero'
76
80
end
77
81
@mutex . synchronize do
78
82
if timeout . nil?
@@ -94,7 +98,7 @@ def try_acquire(permits = 1, timeout = nil)
94
98
# @return [True]
95
99
def release ( permits = 1 )
96
100
unless permits . is_a? ( Fixnum ) && permits > 0
97
- raise ArgumentError . new ( 'permits must be an integer greater than zero' )
101
+ fail ArgumentError , 'permits must be an integer greater than zero'
98
102
end
99
103
@mutex . synchronize do
100
104
@free += permits
@@ -116,14 +120,13 @@ def release(permits = 1)
116
120
# @return [True]
117
121
def reduce_permits ( reduction )
118
122
unless reduction . is_a? ( Fixnum ) && reduction >= 0
119
- raise ArgumentError . new ( 'reduction must be an non-negative integer' )
123
+ fail ArgumentError , 'reduction must be an non-negative integer'
120
124
end
121
125
unless @free - reduction >= 0
122
- raise ArgumentError . new ( 'cannot reduce number of available_permits below zero' )
123
- end
124
- @mutex . synchronize do
125
- @free -= reduction
126
+ fail ( ArgumentError ,
127
+ 'cannot reduce number of available_permits below zero' )
126
128
end
129
+ @mutex . synchronize { @free -= reduction }
127
130
true
128
131
end
129
132
@@ -150,116 +153,78 @@ def try_acquire_timed(permits, timeout)
150
153
151
154
if RUBY_PLATFORM == 'java'
152
155
153
- # @!macro count_down_latch
156
+ # @!macro semaphore
154
157
class JavaSemaphore
155
-
156
- # @!macro count_down_latch_method_initialize
158
+ # @!macro semaphore_method_initialize
157
159
def initialize ( count )
158
160
unless count . is_a? ( Fixnum ) && count >= 0
159
- raise ArgumentError . new ( 'count must be in integer greater than or equal zero' )
161
+ fail ( ArgumentError ,
162
+ 'count must be in integer greater than or equal zero' )
160
163
end
161
164
@semaphore = java . util . concurrent . Semaphore . new ( count )
162
165
end
163
166
167
+ # @!macro semaphore_method_acquire
164
168
def acquire ( permits = 1 )
165
169
unless permits . is_a? ( Fixnum ) && permits > 0
166
- raise ArgumentError . new ( 'permits must be an integer greater than zero' )
170
+ fail ArgumentError , 'permits must be an integer greater than zero'
167
171
end
168
- @semaphore . acquire ( permits ) ;
172
+ @semaphore . acquire ( permits )
169
173
end
170
174
171
-
172
- # @!macro [attach] semaphore_method_available_permits
173
- #
174
- # Returns the current number of permits available in this semaphore.
175
- #
176
- # @return [Integer]
177
- def available_permits
178
- @semaphore . availablePermits
179
- end
180
-
181
- # @!macro [attach] semaphore_method_drain_permits
182
- #
183
- # Acquires and returns all permits that are immediately available.
184
- #
185
- # @return [Integer]
186
- def drain_permits
187
- @semaphore . drainPermits
188
- end
189
-
190
- # @!macro [attach] semaphore_method_try_acquire
191
- #
192
- # Acquires the given number of permits from this semaphore, only if all are available at the time of invocation.
193
- #
194
- # @param [Fixnum] permits the number of permits to acquire
195
- #
196
- # @param [Fixnum] timeout the number of seconds to wait for the counter or `nil`
197
- # to return immediately
198
- #
199
- # @raise [ArgumentError] if `permits` is not an integer or is less than one
200
- #
201
- # @return [Boolean] `false` if no permits are available, `true` when acquired a permit
202
- def try_acquire ( permits = 1 , timeout = nil )
203
- unless permits . is_a? ( Fixnum ) && permits > 0
204
- raise ArgumentError . new ( 'permits must be an integer greater than zero' )
175
+ # @!macro semaphore_method_available_permits
176
+ def available_permits
177
+ @semaphore . availablePermits
205
178
end
206
- if timeout . nil?
207
- @semaphore . try_acquire ( permits )
208
- else
209
- @semaphore . try_acquire ( permits , timeout , java . util . concurrent . TimeUnit ::SECONDS )
210
- end
211
- end
212
179
213
- # @!macro [attach] semaphore_method_release
214
- #
215
- # Releases the given number of permits, returning them to the semaphore.
216
- #
217
- # @param [Fixnum] permits Number of permits to return to the semaphore.
218
- #
219
- # @raise [ArgumentError] if `permits` is not a number or is less than one
220
- #
221
- # @raise [ArgumentError] if `permits` + `@free` is larger than `@count`
222
- #
223
- # @return [True]
224
- def release ( permits = 1 )
225
- unless permits . is_a? ( Fixnum ) && permits > 0
226
- raise ArgumentError . new ( 'permits must be an integer greater than zero' )
180
+ # @!macro semaphore_method_drain_permits
181
+ def drain_permits
182
+ @semaphore . drainPermits
227
183
end
228
- @semaphore . release ( permits )
229
- true
230
- end
231
184
232
- # @!macro [attach] semaphore_method_reduce_permits
233
- #
234
- # Shrinks the number of available permits by the indicated reduction.
235
- #
236
- # @param [Fixnum] reduction Number of permits to remove.
237
- #
238
- # @raise [ArgumentError] if `reduction` is not an integer or is negative
239
- #
240
- # @raise [ArgumentError] if the operation would bring `@free` below zero
241
- #
242
- # @return [True]
243
- def reduce_permits ( reduction )
244
- unless reduction . is_a? ( Fixnum ) && reduction >= 0
245
- raise ArgumentError . new ( 'reduction must be an non-negative integer' )
246
- end
247
- unless @free - reduction >= 0
248
- raise ArgumentError . new ( 'cannot reduce number of available_permits below zero' )
185
+ # @!macro semaphore_method_try_acquire
186
+ def try_acquire ( permits = 1 , timeout = nil )
187
+ unless permits . is_a? ( Fixnum ) && permits > 0
188
+ fail ArgumentError , 'permits must be an integer greater than zero'
189
+ end
190
+ if timeout . nil?
191
+ @semaphore . try_acquire ( permits )
192
+ else
193
+ @semaphore . try_acquire ( permits ,
194
+ timeout ,
195
+ java . util . concurrent . TimeUnit ::SECONDS )
196
+ end
249
197
end
250
- @semaphore . reducePermits ( void )
251
- end
252
198
199
+ # @!macro semaphore_method_release
200
+ def release ( permits = 1 )
201
+ unless permits . is_a? ( Fixnum ) && permits > 0
202
+ fail ArgumentError , 'permits must be an integer greater than zero'
203
+ end
204
+ @semaphore . release ( permits )
205
+ true
206
+ end
253
207
208
+ # @!macro semaphore_method_reduce_permits
209
+ def reduce_permits ( reduction )
210
+ unless reduction . is_a? ( Fixnum ) && reduction >= 0
211
+ fail ArgumentError , 'reduction must be an non-negative integer'
212
+ end
213
+ unless @free - reduction >= 0
214
+ fail ( ArgumentError ,
215
+ 'cannot reduce number of available_permits below zero' )
216
+ end
217
+ @semaphore . reducePermits ( void )
218
+ end
254
219
end
255
220
256
- # @!macro count_down_latch
221
+ # @!macro semaphore
257
222
class Semaphore < JavaSemaphore
258
223
end
259
224
260
225
else
261
226
262
- # @!macro count_down_latch
227
+ # @!macro semaphore
263
228
class Semaphore < MutexSemaphore
264
229
end
265
230
end
0 commit comments