async 1.28.4 → 1.28.9

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
  SHA256:
3
- metadata.gz: 1cfb65b7409df962b9b4b9d2c48fda3882c6f79c29b66dce5a915d42f2db4352
4
- data.tar.gz: afec5fb15947cc6e1cccc152342dde75a8b27e0c9fb1d46cb91b5479f4cda8b6
3
+ metadata.gz: 6ca8ba4c610a65bfe25595780c26681ad5920a5423b8f065d12917df8db4144d
4
+ data.tar.gz: d5488881518a83750bf540a150e66dd63d993a88c30d5e6f839714456cd2709e
5
5
  SHA512:
6
- metadata.gz: 0ec16c8b0249146ccf7cb25b51d2c396611e7b0ea74f13c960c34e865bd6f6963371be8bf1610c47633ebdd586578f6ac47c5b4ae6cdf9da5027218c738569bf
7
- data.tar.gz: ac43cc50125a2036826d217a07f736a4dec92c82fc89ecb272814a736e3992af8a1b368ba17eb65afbdd15974842e2028c748b5b59b41dd0c0c4cf402d8184f9
6
+ metadata.gz: 33200c36d76c0af962c8573da82962e1c32d83c74c3c98486b401ba366d2417d85afb6f7e70432bb4e667c9047a0d074afc308436b8f6c50af452f2269a4d6aa
7
+ data.tar.gz: be364fa61facbaeb3879945cd137499da161646cee5ceb4da31db12173f9b6fea4bbf8754b5aa076959e8b2a59778ba929724781aa32da18b01ce44c334e1ad4
data/lib/async/node.rb CHANGED
@@ -24,6 +24,7 @@ module Async
24
24
  # A double linked list.
25
25
  class List
26
26
  def initialize
27
+ # The list behaves like a list node, so @tail points to the next item (the first one) and head points to the previous item (the last one). This may be slightly confusing but it makes the interface more natural.
27
28
  @head = nil
28
29
  @tail = nil
29
30
  @size = 0
@@ -36,21 +37,21 @@ module Async
36
37
 
37
38
  # Inserts an item at the end of the list.
38
39
  def insert(item)
39
- unless @head
40
- @head = item
40
+ unless @tail
41
41
  @tail = item
42
+ @head = item
42
43
 
43
44
  # Consistency:
44
45
  item.head = nil
45
46
  item.tail = nil
46
47
  else
47
- @tail.tail = item
48
- item.head = @tail
48
+ @head.tail = item
49
+ item.head = @head
49
50
 
50
51
  # Consistency:
51
52
  item.tail = nil
52
53
 
53
- @tail = item
54
+ @head = item
54
55
  end
55
56
 
56
57
  @size += 1
@@ -59,14 +60,14 @@ module Async
59
60
  end
60
61
 
61
62
  def delete(item)
62
- if @head.equal?(item)
63
- @head = @head.tail
63
+ if @tail.equal?(item)
64
+ @tail = @tail.tail
64
65
  else
65
66
  item.head.tail = item.tail
66
67
  end
67
68
 
68
- if @tail.equal?(item)
69
- @tail = @tail.head
69
+ if @head.equal?(item)
70
+ @head = @head.head
70
71
  else
71
72
  item.tail.head = item.head
72
73
  end
@@ -79,15 +80,17 @@ module Async
79
80
  return self
80
81
  end
81
82
 
82
- def each
83
+ def each(&block)
83
84
  return to_enum unless block_given?
84
85
 
85
- item = @head
86
- while item
87
- # We store the tail pointer so we can remove the current item from the linked list:
88
- tail = item.tail
89
- yield item
90
- item = tail
86
+ current = self
87
+ while node = current.tail
88
+ yield node
89
+
90
+ # If the node has deleted itself or any subsequent node, it will no longer be the next node, so don't use it for continued traversal:
91
+ if current.tail.equal?(node)
92
+ current = node
93
+ end
91
94
  end
92
95
  end
93
96
 
@@ -100,19 +103,19 @@ module Async
100
103
  end
101
104
 
102
105
  def first
103
- @head
106
+ @tail
104
107
  end
105
108
 
106
109
  def last
107
- @tail
110
+ @head
108
111
  end
109
112
 
110
113
  def empty?
111
- @head.nil?
114
+ @tail.nil?
112
115
  end
113
116
 
114
117
  def nil?
115
- @head.nil?
118
+ @tail.nil?
116
119
  end
117
120
  end
118
121
 
@@ -276,6 +279,8 @@ module Async
276
279
  if child.finished?
277
280
  delete_child(child)
278
281
  else
282
+ # In theory we don't need to do this... because we are throwing away the list. However, if you don't correctly update the list when moving the child to the parent, it foobars the enumeration, and subsequent nodes will be skipped, or in the worst case you might start enumerating the parents nodes.
283
+ delete_child(child)
279
284
  parent.add_child(child)
280
285
  end
281
286
  end
data/lib/async/reactor.rb CHANGED
@@ -102,7 +102,7 @@ module Async
102
102
  fiber = Fiber.current
103
103
 
104
104
  if timeout
105
- timer = self.after(timeout) do
105
+ timer = @timers.after(timeout) do
106
106
  if fiber.alive?
107
107
  fiber.resume(false)
108
108
  end
@@ -111,7 +111,7 @@ module Async
111
111
 
112
112
  begin
113
113
  @blocked += 1
114
- Fiber.yield
114
+ Task.yield
115
115
  ensure
116
116
  @blocked -= 1
117
117
  end
@@ -198,7 +198,7 @@ module Async
198
198
  def yield(fiber = Fiber.current)
199
199
  @ready << fiber
200
200
 
201
- Fiber.yield
201
+ Task.yield
202
202
  end
203
203
 
204
204
  def finished?
@@ -223,7 +223,7 @@ module Async
223
223
  @running.clear
224
224
  end
225
225
 
226
- unless @blocked.zero?
226
+ if @unblocked.any?
227
227
  unblocked = Array.new
228
228
 
229
229
  @guard.synchronize do
@@ -347,7 +347,7 @@ module Async
347
347
  timer = @timers.after(timeout) do
348
348
  if fiber.alive?
349
349
  error = exception.new("execution expired")
350
- fiber.resume error
350
+ fiber.resume(error)
351
351
  end
352
352
  end
353
353
 
@@ -34,24 +34,20 @@ module Async
34
34
 
35
35
  def initialize(reactor)
36
36
  @reactor = reactor
37
- @wrappers = nil
38
37
  end
39
38
 
39
+ attr :wrappers
40
+
40
41
  def set!
41
- @wrappers = {}
42
42
  Fiber.set_scheduler(self)
43
43
  end
44
44
 
45
45
  def clear!
46
- # Because these instances are created with `autoclose: false`, this does not close the underlying file descriptor:
47
- # @ios&.each_value(&:close)
48
-
49
- @wrappers = nil
50
46
  Fiber.set_scheduler(nil)
51
47
  end
52
48
 
53
49
  private def from_io(io)
54
- @wrappers[io] ||= Wrapper.new(io, @reactor)
50
+ Wrapper.new(io, @reactor)
55
51
  end
56
52
 
57
53
  def io_wait(io, events, timeout = nil)
@@ -72,6 +68,8 @@ module Async
72
68
  end
73
69
 
74
70
  return false
71
+ rescue TimeoutError
72
+ return nil
75
73
  ensure
76
74
  wrapper.reactor = nil
77
75
  end
@@ -87,7 +85,7 @@ module Async
87
85
  end
88
86
 
89
87
  def kernel_sleep(duration)
90
- @reactor.sleep(duration)
88
+ self.block(nil, duration)
91
89
  end
92
90
 
93
91
  def block(blocker, timeout)
data/lib/async/task.rb CHANGED
@@ -72,14 +72,14 @@ module Async
72
72
  # Create a new task.
73
73
  # @param reactor [Async::Reactor] the reactor this task will run within.
74
74
  # @param parent [Async::Task] the parent task.
75
- def initialize(reactor, parent = Task.current?, logger: nil, **options, &block)
75
+ def initialize(reactor, parent = Task.current?, logger: nil, finished: nil, **options, &block)
76
76
  super(parent || reactor, **options)
77
77
 
78
78
  @reactor = reactor
79
79
 
80
80
  @status = :initialized
81
81
  @result = nil
82
- @finished = nil
82
+ @finished = finished
83
83
 
84
84
  @logger = logger
85
85
 
data/lib/async/version.rb CHANGED
@@ -21,5 +21,5 @@
21
21
  # THE SOFTWARE.
22
22
 
23
23
  module Async
24
- VERSION = "1.28.4"
24
+ VERSION = "1.28.9"
25
25
  end
data/lib/kernel/sync.rb CHANGED
@@ -28,7 +28,10 @@ module Kernel
28
28
  if task = ::Async::Task.current?
29
29
  yield task
30
30
  else
31
- ::Async::Reactor.run(&block).wait
31
+ ::Async::Reactor.run(
32
+ finished: ::Async::Condition.new,
33
+ &block
34
+ ).wait
32
35
  end
33
36
  end
34
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.28.4
4
+ version: 1.28.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-27 00:00:00.000000000 Z
11
+ date: 2021-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: console
@@ -179,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
181
  requirements: []
182
- rubygems_version: 3.1.2
182
+ rubygems_version: 3.2.3
183
183
  signing_key:
184
184
  specification_version: 4
185
185
  summary: A concurrency framework for Ruby.