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
		
	
| 
											5 years ago
										 | // | ||
|  | //  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() | ||
|  |         } | ||
|  |     } | ||
|  | } |