atomic-ruby 0.15.2 → 0.15.3
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/CHANGELOG.md +6 -0
- data/README.md +91 -33
- data/ext/atomic_ruby/atomic_ruby.c +11 -0
- data/lib/atomic-ruby/atomic_condition_variable.rb +19 -32
- data/lib/atomic-ruby/atomic_count_down_latch.rb +1 -5
- data/lib/atomic-ruby/atomic_thread_pool.rb +15 -10
- data/lib/atomic-ruby/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a50be9a8594152f8d07b2338588a01be6aecadf55f993ea6cc4c2431e80e2b76
|
|
4
|
+
data.tar.gz: eb9c45d8dff70d0697d3d62ba5a539e3d71e42c21ea7ab6b646d44fde69f39ac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: abde2bc85010be3634caeaf66d262acf1c5c70c50af5e9e420a43c87071965bd543a475b01b5d1b0d1569682802595e936a9d224e636896a681e5c3c85d98a77
|
|
7
|
+
data.tar.gz: e93d7b35c3ccdba9c82906587c24455c248655ffbe3f9d4141e4cb029705306f80c13b36f6a0ce7193a33701758ad0a9c2f77a7aa0c94ad92e49392ba899c055
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.15.2] - 2026-08-31
|
|
4
|
+
|
|
5
|
+
- Prevent enqueues from racing `AtomicThreadPool#shutdown`
|
|
6
|
+
- Remove interrupted waiters from `AtomicConditionVariable`
|
|
7
|
+
- Replace `Thread.pass` busy-wait with `sleep` in `AtomicCountDownLatch#wait`
|
|
8
|
+
|
|
3
9
|
## [0.15.2] - 2026-08-30
|
|
4
10
|
|
|
5
11
|
- Avoid thread event hook overhead for fixed thread pools
|
data/README.md
CHANGED
|
@@ -267,8 +267,8 @@ puts "Atomic Ruby Atomic Bank Account: #{results[2].real.round(6)} seconds"
|
|
|
267
267
|
> bundle exec rake clobber && bundle exec rake compile && bundle exec ruby examples/atom_benchmark.rb
|
|
268
268
|
|
|
269
269
|
ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
|
|
270
|
-
concurrent-ruby version: 1.3.
|
|
271
|
-
atomic-ruby version: 0.15.
|
|
270
|
+
concurrent-ruby version: 1.3.8
|
|
271
|
+
atomic-ruby version: 0.15.3
|
|
272
272
|
|
|
273
273
|
Balances:
|
|
274
274
|
Synchronized Bank Account Balance: 975
|
|
@@ -276,9 +276,9 @@ Concurrent Ruby Atomic Bank Account Balance: 975
|
|
|
276
276
|
Atomic Ruby Atomic Bank Account Balance: 975
|
|
277
277
|
|
|
278
278
|
Benchmark Results:
|
|
279
|
-
Synchronized Bank Account: 5.
|
|
280
|
-
Concurrent Ruby Atomic Bank Account: 5.
|
|
281
|
-
Atomic Ruby Atomic Bank Account: 5.
|
|
279
|
+
Synchronized Bank Account: 5.104959 seconds
|
|
280
|
+
Concurrent Ruby Atomic Bank Account: 5.120305 seconds
|
|
281
|
+
Atomic Ruby Atomic Bank Account: 5.102732 seconds
|
|
282
282
|
```
|
|
283
283
|
|
|
284
284
|
</details>
|
|
@@ -358,22 +358,22 @@ end
|
|
|
358
358
|
> bundle exec rake clobber && bundle exec rake compile && bundle exec ruby examples/atomic_boolean_benchmark.rb
|
|
359
359
|
|
|
360
360
|
ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
|
|
361
|
-
concurrent-ruby version: 1.3.
|
|
362
|
-
atomic-ruby version: 0.15.
|
|
361
|
+
concurrent-ruby version: 1.3.8
|
|
362
|
+
atomic-ruby version: 0.15.3
|
|
363
363
|
|
|
364
364
|
Warming up --------------------------------------
|
|
365
|
-
Synchronized Boolean Toggle
|
|
366
|
-
Concurrent Ruby Atomic Boolean Toggle
|
|
367
|
-
Atomic Ruby Atomic Boolean Toggle
|
|
365
|
+
Synchronized Boolean Toggle 165.000 i/100ms
|
|
366
|
+
Concurrent Ruby Atomic Boolean Toggle 132.000 i/100ms
|
|
367
|
+
Atomic Ruby Atomic Boolean Toggle 119.000 i/100ms
|
|
368
368
|
Calculating -------------------------------------
|
|
369
|
-
Synchronized Boolean Toggle 1.
|
|
370
|
-
Concurrent Ruby Atomic Boolean Toggle 1.
|
|
371
|
-
Atomic Ruby Atomic Boolean Toggle 1.
|
|
369
|
+
Synchronized Boolean Toggle 1.647k (± 2.1%) i/s (606.98 μs/i) - 8.250k in 5.007598s
|
|
370
|
+
Concurrent Ruby Atomic Boolean Toggle 1.343k (± 1.9%) i/s (744.55 μs/i) - 6.732k in 5.012307s
|
|
371
|
+
Atomic Ruby Atomic Boolean Toggle 1.207k (± 1.9%) i/s (828.31 μs/i) - 6.069k in 5.027033s
|
|
372
372
|
|
|
373
373
|
Comparison:
|
|
374
|
-
Synchronized Boolean Toggle:
|
|
375
|
-
Concurrent Ruby Atomic Boolean Toggle:
|
|
376
|
-
Atomic Ruby Atomic Boolean Toggle:
|
|
374
|
+
Synchronized Boolean Toggle: 1647.5 i/s
|
|
375
|
+
Concurrent Ruby Atomic Boolean Toggle: 1343.1 i/s - 1.23x slower
|
|
376
|
+
Atomic Ruby Atomic Boolean Toggle: 1207.3 i/s - 1.36x slower
|
|
377
377
|
```
|
|
378
378
|
|
|
379
379
|
</details>
|
|
@@ -442,18 +442,18 @@ end
|
|
|
442
442
|
> bundle exec rake clobber && bundle exec rake compile && bundle exec ruby examples/atomic_condition_variable_benchmark.rb
|
|
443
443
|
|
|
444
444
|
ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
|
|
445
|
-
atomic-ruby version: 0.15.
|
|
445
|
+
atomic-ruby version: 0.15.3
|
|
446
446
|
|
|
447
447
|
Warming up --------------------------------------
|
|
448
|
-
Synchronized Condition Variable Wait/Signal
|
|
449
|
-
Atomic Ruby Atomic Condition Variable Wait/Signal
|
|
448
|
+
Synchronized Condition Variable Wait/Signal 4.062k i/100ms
|
|
449
|
+
Atomic Ruby Atomic Condition Variable Wait/Signal 4.133k i/100ms
|
|
450
450
|
Calculating -------------------------------------
|
|
451
|
-
Synchronized Condition Variable Wait/Signal
|
|
452
|
-
Atomic Ruby Atomic Condition Variable Wait/Signal
|
|
451
|
+
Synchronized Condition Variable Wait/Signal 41.923k (± 3.5%) i/s (23.85 μs/i) - 211.224k in 5.038330s
|
|
452
|
+
Atomic Ruby Atomic Condition Variable Wait/Signal 40.666k (± 3.8%) i/s (24.59 μs/i) - 206.650k in 5.081595s
|
|
453
453
|
|
|
454
454
|
Comparison:
|
|
455
|
-
Synchronized Condition Variable Wait/Signal:
|
|
456
|
-
Atomic Ruby Atomic Condition Variable Wait/Signal:
|
|
455
|
+
Synchronized Condition Variable Wait/Signal: 41923.4 i/s
|
|
456
|
+
Atomic Ruby Atomic Condition Variable Wait/Signal: 40666.4 i/s - same-ish: difference falls within error
|
|
457
457
|
```
|
|
458
458
|
|
|
459
459
|
</details>
|
|
@@ -517,18 +517,18 @@ end
|
|
|
517
517
|
> bundle exec rake clobber && bundle exec rake compile && bundle exec ruby examples/atomic_queue_benchmark.rb
|
|
518
518
|
|
|
519
519
|
ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
|
|
520
|
-
atomic-ruby version: 0.15.
|
|
520
|
+
atomic-ruby version: 0.15.3
|
|
521
521
|
|
|
522
522
|
Warming up --------------------------------------
|
|
523
|
-
Synchronized Queue Push/Pop
|
|
524
|
-
Atomic Ruby Atomic Queue Push/Pop
|
|
523
|
+
Synchronized Queue Push/Pop 184.000 i/100ms
|
|
524
|
+
Atomic Ruby Atomic Queue Push/Pop 149.000 i/100ms
|
|
525
525
|
Calculating -------------------------------------
|
|
526
|
-
Synchronized Queue Push/Pop 1.
|
|
527
|
-
Atomic Ruby Atomic Queue Push/Pop 1.
|
|
526
|
+
Synchronized Queue Push/Pop 1.819k (± 2.0%) i/s (549.73 μs/i) - 9.200k in 5.057550s
|
|
527
|
+
Atomic Ruby Atomic Queue Push/Pop 1.493k (± 1.9%) i/s (669.87 μs/i) - 7.599k in 5.090319s
|
|
528
528
|
|
|
529
529
|
Comparison:
|
|
530
|
-
Synchronized Queue Push/Pop:
|
|
531
|
-
Atomic Ruby Atomic Queue Push/Pop:
|
|
530
|
+
Synchronized Queue Push/Pop: 1819.1 i/s
|
|
531
|
+
Atomic Ruby Atomic Queue Push/Pop: 1492.8 i/s - 1.22x slower
|
|
532
532
|
|
|
533
533
|
```
|
|
534
534
|
|
|
@@ -587,11 +587,69 @@ puts "Atomic Ruby Atomic Thread Pool: #{results[1].real.round(6)} seconds"
|
|
|
587
587
|
|
|
588
588
|
ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
|
|
589
589
|
concurrent-ruby version: 1.3.8
|
|
590
|
-
atomic-ruby version: 0.15.
|
|
590
|
+
atomic-ruby version: 0.15.3
|
|
591
|
+
|
|
592
|
+
Benchmark Results:
|
|
593
|
+
Concurrent Ruby Thread Pool: 5.012798 seconds
|
|
594
|
+
Atomic Ruby Atomic Thread Pool: 4.755237 seconds
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
</details>
|
|
598
|
+
|
|
599
|
+
<details>
|
|
600
|
+
|
|
601
|
+
<summary>AtomicCountDownLatch</summary>
|
|
602
|
+
|
|
603
|
+
<br>
|
|
604
|
+
|
|
605
|
+
```ruby
|
|
606
|
+
# frozen_string_literal: true
|
|
607
|
+
|
|
608
|
+
require "benchmark"
|
|
609
|
+
require "concurrent-ruby"
|
|
610
|
+
require_relative "../lib/atomic-ruby"
|
|
611
|
+
|
|
612
|
+
results = []
|
|
613
|
+
|
|
614
|
+
2.times do |idx|
|
|
615
|
+
result = Benchmark.measure do
|
|
616
|
+
latch = case idx
|
|
617
|
+
when 0 then Concurrent::CountDownLatch.new(1)
|
|
618
|
+
when 1 then AtomicCountDownLatch.new(1)
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
thread = Thread.new do
|
|
622
|
+
sleep(2)
|
|
623
|
+
latch.count_down
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
latch.wait
|
|
627
|
+
thread.join
|
|
628
|
+
end
|
|
629
|
+
|
|
630
|
+
results << result
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
puts "\n"
|
|
634
|
+
puts "ruby version: #{RUBY_DESCRIPTION}"
|
|
635
|
+
puts "concurrent-ruby version: #{Concurrent::VERSION}"
|
|
636
|
+
puts "atomic-ruby version: #{AtomicRuby::VERSION}"
|
|
637
|
+
puts "\n"
|
|
638
|
+
puts "Benchmark Results:"
|
|
639
|
+
puts "Concurrent Ruby Count Down Latch: #{results[0].total.round(6)} CPU seconds, #{results[0].real.round(6)} elapsed seconds"
|
|
640
|
+
puts "Atomic Ruby Atomic Count Down Latch: #{results[1].total.round(6)} CPU seconds, #{results[1].real.round(6)} elapsed seconds"
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
```
|
|
644
|
+
> bundle exec rake clobber && bundle exec rake compile && bundle exec ruby examples/atomic_count_down_latch_benchmark.rb
|
|
645
|
+
|
|
646
|
+
ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
|
|
647
|
+
concurrent-ruby version: 1.3.8
|
|
648
|
+
atomic-ruby version: 0.15.3
|
|
591
649
|
|
|
592
650
|
Benchmark Results:
|
|
593
|
-
Concurrent Ruby
|
|
594
|
-
Atomic Ruby Atomic
|
|
651
|
+
Concurrent Ruby Count Down Latch: 0.000511 CPU seconds, 2.001465 elapsed seconds
|
|
652
|
+
Atomic Ruby Atomic Count Down Latch: 0.023529 CPU seconds, 2.00364 elapsed seconds
|
|
595
653
|
```
|
|
596
654
|
|
|
597
655
|
</details>
|
|
@@ -172,6 +172,7 @@ typedef struct {
|
|
|
172
172
|
volatile VALUE head;
|
|
173
173
|
volatile VALUE tail;
|
|
174
174
|
volatile rb_atomic_t count;
|
|
175
|
+
bool closed;
|
|
175
176
|
} atomic_ruby_queue_t;
|
|
176
177
|
|
|
177
178
|
static void atomic_ruby_queue_mark(void *ptr) {
|
|
@@ -211,6 +212,7 @@ static VALUE rb_cAtomicQueue_allocate(VALUE klass) {
|
|
|
211
212
|
RB_OBJ_WRITE(obj, &atomic_ruby_queue->head, Qnil);
|
|
212
213
|
RB_OBJ_WRITE(obj, &atomic_ruby_queue->tail, Qnil);
|
|
213
214
|
atomic_ruby_queue->count = 0;
|
|
215
|
+
atomic_ruby_queue->closed = false;
|
|
214
216
|
return obj;
|
|
215
217
|
}
|
|
216
218
|
|
|
@@ -228,6 +230,7 @@ static VALUE rb_cAtomicQueue_initialize(VALUE self) {
|
|
|
228
230
|
static VALUE rb_cAtomicQueue_push(VALUE self, VALUE value) {
|
|
229
231
|
atomic_ruby_queue_t *atomic_ruby_queue;
|
|
230
232
|
TypedData_Get_Struct(self, atomic_ruby_queue_t, &atomic_ruby_queue_type, atomic_ruby_queue);
|
|
233
|
+
if (atomic_ruby_queue->closed) return Qfalse;
|
|
231
234
|
|
|
232
235
|
VALUE new_node = atomic_ruby_queue_node_new(value, Qnil);
|
|
233
236
|
|
|
@@ -259,6 +262,13 @@ static VALUE rb_cAtomicQueue_push(VALUE self, VALUE value) {
|
|
|
259
262
|
return self;
|
|
260
263
|
}
|
|
261
264
|
|
|
265
|
+
static VALUE rb_cAtomicQueue_close(VALUE self) {
|
|
266
|
+
atomic_ruby_queue_t *atomic_ruby_queue;
|
|
267
|
+
TypedData_Get_Struct(self, atomic_ruby_queue_t, &atomic_ruby_queue_type, atomic_ruby_queue);
|
|
268
|
+
atomic_ruby_queue->closed = true;
|
|
269
|
+
return Qnil;
|
|
270
|
+
}
|
|
271
|
+
|
|
262
272
|
static VALUE rb_cAtomicQueue_pop(VALUE self) {
|
|
263
273
|
atomic_ruby_queue_t *atomic_ruby_queue;
|
|
264
274
|
TypedData_Get_Struct(self, atomic_ruby_queue_t, &atomic_ruby_queue_type, atomic_ruby_queue);
|
|
@@ -787,6 +797,7 @@ RUBY_FUNC_EXPORTED void Init_atomic_ruby(void) {
|
|
|
787
797
|
rb_define_alloc_func(rb_cAtomicQueue, rb_cAtomicQueue_allocate);
|
|
788
798
|
rb_define_private_method(rb_cAtomicQueue, "_initialize", rb_cAtomicQueue_initialize, 0);
|
|
789
799
|
rb_define_private_method(rb_cAtomicQueue, "_push", rb_cAtomicQueue_push, 1);
|
|
800
|
+
rb_define_private_method(rb_cAtomicQueue, "_close", rb_cAtomicQueue_close, 0);
|
|
790
801
|
rb_define_private_method(rb_cAtomicQueue, "_pop", rb_cAtomicQueue_pop, 0);
|
|
791
802
|
rb_define_private_method(rb_cAtomicQueue, "_size", rb_cAtomicQueue_size, 0);
|
|
792
803
|
rb_define_private_method(rb_cAtomicQueue, "_empty_p", rb_cAtomicQueue_empty_p, 0);
|
|
@@ -8,19 +8,10 @@ module AtomicRuby
|
|
|
8
8
|
#
|
|
9
9
|
# AtomicConditionVariable lets one or more threads park until another
|
|
10
10
|
# thread signals them, without the paired `Mutex` that Ruby's
|
|
11
|
-
# `ConditionVariable` requires.
|
|
12
|
-
# in a native doubly-linked list, so registering a waiter, removing a
|
|
13
|
-
# waiter, and shifting the head off for a signal are all O(1) and
|
|
14
|
-
# allocation-light. Parking still uses `Thread.stop` and
|
|
15
|
-
# `Thread#wakeup`, which are the standard kernel-level primitives Ruby
|
|
16
|
-
# exposes for sleeping a thread.
|
|
11
|
+
# `ConditionVariable` requires.
|
|
17
12
|
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
# the predicate, so any signal that fires after the producer makes the
|
|
21
|
-
# predicate true is guaranteed to see the waiter and wake it. Ruby also
|
|
22
|
-
# remembers pending wakeups across `Thread.stop`, so a wakeup that
|
|
23
|
-
# arrives between the predicate check and the actual park is not lost.
|
|
13
|
+
# Waiters supply a predicate that is checked again after registration,
|
|
14
|
+
# preventing signals sent after a relevant state change from being lost.
|
|
24
15
|
#
|
|
25
16
|
# @example Basic usage
|
|
26
17
|
# condvar = AtomicConditionVariable.new
|
|
@@ -72,10 +63,6 @@ module AtomicRuby
|
|
|
72
63
|
|
|
73
64
|
# Wakes one parked waiter, or no-ops if none are parked.
|
|
74
65
|
#
|
|
75
|
-
# If a waiter has registered itself but is not yet inside `Thread.stop`,
|
|
76
|
-
# Ruby remembers the wakeup and the next `Thread.stop` returns
|
|
77
|
-
# immediately.
|
|
78
|
-
#
|
|
79
66
|
# @return [true, false] true if a waiter was signalled, false otherwise
|
|
80
67
|
#
|
|
81
68
|
# @example
|
|
@@ -93,8 +80,6 @@ module AtomicRuby
|
|
|
93
80
|
|
|
94
81
|
# Wakes every parked waiter.
|
|
95
82
|
#
|
|
96
|
-
# Each woken thread observes the wake the same way as with {#signal}.
|
|
97
|
-
#
|
|
98
83
|
# @return [Integer] The number of waiters signalled
|
|
99
84
|
#
|
|
100
85
|
# @example
|
|
@@ -111,12 +96,10 @@ module AtomicRuby
|
|
|
111
96
|
# Blocks until the given block returns a truthy value, then returns that
|
|
112
97
|
# value.
|
|
113
98
|
#
|
|
114
|
-
# The block
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
#
|
|
118
|
-
# wakes it. The block may run more than once and may run concurrently
|
|
119
|
-
# with a signalling thread.
|
|
99
|
+
# The block may run more than once and may run concurrently with a
|
|
100
|
+
# signalling thread. Rechecking it after registration prevents lost
|
|
101
|
+
# wakeups. Interrupted waits are unregistered before the exception is
|
|
102
|
+
# propagated.
|
|
120
103
|
#
|
|
121
104
|
# @yieldreturn [untyped] Truthy to wake, falsy to keep waiting
|
|
122
105
|
# @return [untyped] The first truthy value returned by the block
|
|
@@ -140,15 +123,19 @@ module AtomicRuby
|
|
|
140
123
|
|
|
141
124
|
self_thread = Thread.current
|
|
142
125
|
loop do
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
126
|
+
Thread.handle_interrupt(Exception => :never) do
|
|
127
|
+
waiter = _add_waiter(self_thread)
|
|
128
|
+
begin
|
|
129
|
+
Thread.handle_interrupt(Exception => :immediate) do
|
|
130
|
+
result = yield
|
|
131
|
+
return result if result
|
|
149
132
|
|
|
150
|
-
|
|
151
|
-
|
|
133
|
+
Thread.stop
|
|
134
|
+
end
|
|
135
|
+
ensure
|
|
136
|
+
_remove_waiter(waiter)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
152
139
|
end
|
|
153
140
|
end
|
|
154
141
|
end
|
|
@@ -133,10 +133,6 @@ module AtomicRuby
|
|
|
133
133
|
|
|
134
134
|
# Blocks the current thread until the count reaches zero.
|
|
135
135
|
#
|
|
136
|
-
# This method will block the calling thread until other threads have
|
|
137
|
-
# called {#count_down} enough times to reduce the count to zero.
|
|
138
|
-
# The method uses busy-waiting (Thread.pass) to check the count.
|
|
139
|
-
#
|
|
140
136
|
# @return [void]
|
|
141
137
|
#
|
|
142
138
|
# @example Simple wait
|
|
@@ -166,7 +162,7 @@ module AtomicRuby
|
|
|
166
162
|
#
|
|
167
163
|
# @rbs () -> void
|
|
168
164
|
def wait
|
|
169
|
-
|
|
165
|
+
sleep 0.001 while @count.value > 0
|
|
170
166
|
end
|
|
171
167
|
end
|
|
172
168
|
end
|
|
@@ -155,12 +155,13 @@ module AtomicRuby
|
|
|
155
155
|
#
|
|
156
156
|
# @rbs (Proc work) -> void
|
|
157
157
|
def <<(work)
|
|
158
|
-
|
|
158
|
+
Thread.handle_interrupt(Exception => :never) do
|
|
159
|
+
@trim_requested&.make_false
|
|
160
|
+
raise EnqueuedWorkAfterShutdownError unless @queue.push(work)
|
|
159
161
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
@autoscale_available&.signal
|
|
162
|
+
@work_available.signal
|
|
163
|
+
@autoscale_available&.signal
|
|
164
|
+
end
|
|
164
165
|
end
|
|
165
166
|
|
|
166
167
|
# Returns the number of currently alive worker threads.
|
|
@@ -242,6 +243,9 @@ module AtomicRuby
|
|
|
242
243
|
# 2. Waits for all currently queued work to complete
|
|
243
244
|
# 3. Waits for all worker threads to terminate
|
|
244
245
|
#
|
|
246
|
+
# Enqueues accepted before shutdown are processed before the workers
|
|
247
|
+
# terminate.
|
|
248
|
+
#
|
|
245
249
|
# After shutdown, all worker threads will be terminated and the pool
|
|
246
250
|
# cannot be restarted. Attempting to enqueue work after shutdown
|
|
247
251
|
# will raise an exception.
|
|
@@ -258,11 +262,12 @@ module AtomicRuby
|
|
|
258
262
|
#
|
|
259
263
|
# @rbs () -> void
|
|
260
264
|
def shutdown
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
265
|
+
Thread.handle_interrupt(Exception => :never) do
|
|
266
|
+
@queue.send(:_close)
|
|
267
|
+
@shutdown.make_true
|
|
268
|
+
@autoscale_available&.broadcast
|
|
269
|
+
@work_available.broadcast
|
|
270
|
+
end
|
|
266
271
|
@autoscaler&.join
|
|
267
272
|
@threads.each(&:join)
|
|
268
273
|
@thread_pool_monitor&.stop
|
data/lib/atomic-ruby/version.rb
CHANGED