field_ios

In-the-field app for Radroots on iOS
git clone https://radroots.dev/git/field_ios.git
Log | Files | Refs | README | LICENSE

TeraLifecycleBridge.swift (1416B)


      1 import Foundation
      2 
      3 final class TeraCompletionOnce: @unchecked Sendable {
      4   private let lock = NSLock()
      5   private var completion: (() -> Void)?
      6 
      7   init(_ completion: @escaping () -> Void) {
      8     self.completion = completion
      9   }
     10 
     11   func complete() {
     12     let action = lock.withLock {
     13       let action = completion
     14       completion = nil
     15       return action
     16     }
     17     action?()
     18   }
     19 }
     20 
     21 actor TeraLifecycleBridge {
     22   static let shared = TeraLifecycleBridge()
     23 
     24   private var registration = UUID()
     25   private var shutdown: (@Sendable () async -> Bool)?
     26   private struct Attempt {
     27     let id: UUID
     28     let registration: UUID
     29     let task: Task<Bool, Never>
     30   }
     31 
     32   private var active: Attempt?
     33 
     34   func register(shutdown: @escaping @Sendable () async -> Bool) {
     35     registration = UUID()
     36     self.shutdown = shutdown
     37   }
     38 
     39   func requestShutdown() async {
     40     let id = registration
     41     let attempt: Attempt
     42     if let active, active.registration == id {
     43       attempt = active
     44     } else if let shutdown {
     45       attempt = Attempt(id: UUID(), registration: id, task: Task { await shutdown() })
     46       active = attempt
     47     } else {
     48       return
     49     }
     50     let completed = await attempt.task.value
     51     if active?.id == attempt.id {
     52       active = nil
     53     }
     54     if registration == id, completed {
     55       shutdown = nil
     56     }
     57     if registration == id {
     58       await TeraBackgroundEventRouter.shared.detachAndCompletePending()
     59     }
     60   }
     61 }