mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			76 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Swift
		
	
			
		
		
	
	
			76 lines
		
	
	
		
			2.0 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()
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |