-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathSequenceManager.swift
61 lines (52 loc) · 1.55 KB
/
SequenceManager.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//
// SequenceManager.swift
//
import Foundation
public class SequenceManager: NSObject {
public static let share = SequenceManager()
public typealias Transaction = () -> Void
private var lock = NSLock()
private var isGenesis = true
private var transactionCount = 0
private lazy var sequenceQueue: DispatchQueue = DispatchQueue(label: "sequence_queue")
private lazy var sema: DispatchSemaphore = DispatchSemaphore(value: 0)
/// 使用时,每个事务必须对应一个free
public func commitTransaction(transaction: @escaping Transaction) {
lock.lock()
transactionCount += 1
lock.unlock()
sequenceQueue.async {
self.lock.lock()
if !self.isGenesis {
self.isGenesis = false
self.lock.unlock()
self.sema.wait()
}
self.isGenesis = false
if self.transactionCount > 0 {
self.transactionCount -= 1
if self.transactionCount == 0 {
self.isGenesis = true
}
}
self.lock.unlock()
DispatchQueue.main.async {
transaction()
}
}
}
public func free() {
guard transactionCount > 0 else {
return
}
sema.signal()
}
public func reset() {
guard transactionCount > 0 else {
return
}
for _ in 0..<transactionCount {
sema.signal()
}
}
}