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.
		
		
		
		
		
			
		
			
				
	
	
		
			75 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Swift
		
	
			
		
		
	
	
			75 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Swift
		
	
| //  Copyright (c) 2018 Open Whisper Systems. All rights reserved.
 | |
| 
 | |
| import Foundation
 | |
| import SignalCoreKit
 | |
| 
 | |
| // 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()
 | |
|         }
 | |
|     }
 | |
| }
 |