apple_kit

Apple-native services for Radroots iOS and macOS apps
git clone https://radroots.dev/git/apple_kit.git
Log | Files | Refs | README | LICENSE

RadrootsTransferCallbackQueue.swift (1409B)


      1 import Foundation
      2 
      3 /// Delegate callbacks arrive on a serial OS queue. Preserve that order across
      4 /// Swift suspension so finished events cannot overtake receipt persistence.
      5 final class RadrootsTransferCallbackQueue: @unchecked Sendable {
      6     private let lock = NSLock()
      7     private var tail: Task<Void, Never>?
      8     private var receipts: [RadrootsBackgroundTransferIdentifier: Int] = [:]
      9 
     10     var pendingIdentifiers: Set<RadrootsBackgroundTransferIdentifier> {
     11         lock.withLock { Set(receipts.keys) }
     12     }
     13 
     14     func enqueue(
     15         receipt identifier: RadrootsBackgroundTransferIdentifier? = nil,
     16         operation: @escaping @Sendable () async -> Void
     17     ) {
     18         lock.withLock {
     19             if let identifier {
     20                 receipts[identifier, default: 0] += 1
     21             }
     22             let previous = tail
     23             tail = Task {
     24                 await previous?.value
     25                 await operation()
     26                 if let identifier {
     27                     self.finished(identifier)
     28                 }
     29             }
     30         }
     31     }
     32 
     33     private func finished(_ identifier: RadrootsBackgroundTransferIdentifier) {
     34         lock.withLock {
     35             let remaining = (receipts[identifier] ?? 1) - 1
     36             if remaining == 0 {
     37                 receipts.removeValue(forKey: identifier)
     38             } else {
     39                 receipts[identifier] = remaining
     40             }
     41         }
     42     }
     43 }