mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
75 lines
2 KiB
Swift
75 lines
2 KiB
Swift
//
|
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
// This is intended to be a drop-in replacement for DispatchQueue
|
|
// that processes its queue in reverse order.
|
|
@objc
|
|
public class ReverseDispatchQueue: NSObject {
|
|
|
|
private static let isVerbose: Bool = false
|
|
|
|
private let label: String
|
|
private let serialQueue: DispatchQueue
|
|
|
|
// TODO: We could allow creation with various QOS.
|
|
@objc
|
|
public required init(label: String) {
|
|
self.label = label
|
|
serialQueue = DispatchQueue(label: label)
|
|
|
|
super.init()
|
|
}
|
|
|
|
public typealias WorkBlock = () -> Void
|
|
|
|
private class Item {
|
|
let workBlock: WorkBlock
|
|
let index: UInt64
|
|
|
|
required init(workBlock : @escaping WorkBlock, index: UInt64) {
|
|
self.workBlock = workBlock
|
|
self.index = index
|
|
}
|
|
}
|
|
|
|
// These properties should only be accessed on serialQueue.
|
|
private var items = [Item]()
|
|
private var indexCounter: UInt64 = 0
|
|
|
|
@objc
|
|
public func async(workBlock : @escaping WorkBlock) {
|
|
serialQueue.async {
|
|
self.indexCounter = self.indexCounter + 1
|
|
let index = self.indexCounter
|
|
let item = Item(workBlock: workBlock, index: index )
|
|
self.items.append(item)
|
|
|
|
if ReverseDispatchQueue.isVerbose {
|
|
Logger.verbose("Enqueued[\(self.label)]: \(item.index)")
|
|
}
|
|
|
|
self.process()
|
|
}
|
|
}
|
|
|
|
private func process() {
|
|
serialQueue.async {
|
|
// Note that we popLast() so that we process
|
|
// the queue in the _reverse_ order from
|
|
// which it was enqueued.
|
|
guard let item = self.items.popLast() else {
|
|
// No enqueued work to do.
|
|
return
|
|
}
|
|
if ReverseDispatchQueue.isVerbose {
|
|
Logger.verbose("Processing[\(self.label)]: \(item.index)")
|
|
}
|
|
item.workBlock()
|
|
|
|
self.process()
|
|
}
|
|
}
|
|
}
|