Skip to content

Commit 4782650

Browse files
authored
Merge pull request #40 from glessard/consolidate
consolidate notifications and waiter deallocations
2 parents 05c22e4 + e656cdf commit 4782650

File tree

1 file changed

+51
-19
lines changed

1 file changed

+51
-19
lines changed

Source/deferred/waiter.swift

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,38 +11,55 @@ import Outcome
1111

1212
struct Waiter<T>
1313
{
14-
private let queue: DispatchQueue?
15-
private let handler: (Outcome<T>) -> Void
14+
fileprivate let queue: DispatchQueue?
15+
fileprivate let handler: (Outcome<T>) -> Void
1616
var next: UnsafeMutablePointer<Waiter<T>>? = nil
1717

1818
init(_ queue: DispatchQueue?, _ handler: @escaping (Outcome<T>) -> Void)
1919
{
2020
self.queue = queue
2121
self.handler = handler
2222
}
23-
24-
fileprivate func notify(_ queue: DispatchQueue, _ value: Outcome<T>)
25-
{
26-
let q = self.queue ?? queue
27-
q.async { [handler = self.handler] in handler(value) }
28-
}
2923
}
3024

3125
func notifyWaiters<T>(_ queue: DispatchQueue, _ tail: UnsafeMutablePointer<Waiter<T>>?, _ value: Outcome<T>)
3226
{
33-
var head = reverseList(tail)
27+
let (normal, custom) = reverseAndSplitList(tail)
28+
29+
queue.async {
30+
var head = normal
31+
while let current = head
32+
{
33+
head = current.pointee.next
34+
35+
assert(current.pointee.queue == nil)
36+
current.pointee.handler(value)
37+
38+
current.deinitialize(count: 1)
39+
#if swift(>=4.1)
40+
current.deallocate()
41+
#else
42+
current.deallocate(capacity: 1)
43+
#endif
44+
}
45+
}
46+
47+
var head = custom
3448
while let current = head
3549
{
3650
head = current.pointee.next
3751

38-
current.pointee.notify(queue, value)
52+
assert(current.pointee.queue != nil)
53+
current.pointee.queue!.async {
54+
current.pointee.handler(value)
3955

40-
current.deinitialize(count: 1)
56+
current.deinitialize(count: 1)
4157
#if swift(>=4.1)
42-
current.deallocate()
58+
current.deallocate()
4359
#else
44-
current.deallocate(capacity: 1)
60+
current.deallocate(capacity: 1)
4561
#endif
62+
}
4663
}
4764
}
4865

@@ -62,18 +79,33 @@ func deallocateWaiters<T>(_ tail: UnsafeMutablePointer<Waiter<T>>?)
6279
}
6380
}
6481

65-
private func reverseList<T>(_ tail: UnsafeMutablePointer<Waiter<T>>?) -> UnsafeMutablePointer<Waiter<T>>?
82+
private func reverseAndSplitList<T>(_ tail: UnsafeMutablePointer<Waiter<T>>?) -> (UnsafeMutablePointer<Waiter<T>>?, UnsafeMutablePointer<Waiter<T>>?)
6683
{
67-
if tail?.pointee.next == nil { return tail }
84+
if tail?.pointee.next == nil
85+
{
86+
if tail?.pointee.queue == nil
87+
{ return (tail, nil) }
88+
else
89+
{ return (nil, tail) }
90+
}
6891

69-
var head: UnsafeMutablePointer<Waiter<T>>? = nil
92+
var normal: UnsafeMutablePointer<Waiter<T>>? = nil
93+
var custom: UnsafeMutablePointer<Waiter<T>>? = nil
7094
var current = tail
7195
while let element = current
7296
{
7397
current = element.pointee.next
7498

75-
element.pointee.next = head
76-
head = element
99+
if element.pointee.queue == nil
100+
{
101+
element.pointee.next = normal
102+
normal = element
103+
}
104+
else
105+
{
106+
element.pointee.next = custom
107+
custom = element
108+
}
77109
}
78-
return head
110+
return (normal, custom)
79111
}

0 commit comments

Comments
 (0)