fix
This commit is contained in:
parent
c63734960b
commit
37042fb3c1
@ -7,6 +7,7 @@ actor SDLPacketReaderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
typealias EventHandler = @Sendable (Event) async -> Void
|
typealias EventHandler = @Sendable (Event) async -> Void
|
||||||
|
private typealias PacketReadResult = (packets: [Data], protocols: [NSNumber])?
|
||||||
|
|
||||||
private final class CancellationToken: @unchecked Sendable {
|
private final class CancellationToken: @unchecked Sendable {
|
||||||
private let lock = NSLock()
|
private let lock = NSLock()
|
||||||
@ -27,45 +28,6 @@ actor SDLPacketReaderService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class PacketReadContinuation: @unchecked Sendable {
|
|
||||||
typealias Result = (packets: [Data], protocols: [NSNumber])?
|
|
||||||
|
|
||||||
private let lock = NSLock()
|
|
||||||
private var continuation: CheckedContinuation<Result, Never>?
|
|
||||||
private var finished: Bool = false
|
|
||||||
|
|
||||||
func set(_ continuation: CheckedContinuation<Result, Never>) {
|
|
||||||
lock.lock()
|
|
||||||
if finished {
|
|
||||||
lock.unlock()
|
|
||||||
continuation.resume(returning: nil)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.continuation = continuation
|
|
||||||
lock.unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func resume(returning result: Result) {
|
|
||||||
lock.lock()
|
|
||||||
guard !finished else {
|
|
||||||
lock.unlock()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
finished = true
|
|
||||||
let continuation = self.continuation
|
|
||||||
self.continuation = nil
|
|
||||||
lock.unlock()
|
|
||||||
|
|
||||||
continuation?.resume(returning: result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func cancel() {
|
|
||||||
resume(returning: nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private let provider: NEPacketTunnelProvider
|
private let provider: NEPacketTunnelProvider
|
||||||
private let onEvent: EventHandler
|
private let onEvent: EventHandler
|
||||||
private var readTask: Task<Void, Never>?
|
private var readTask: Task<Void, Never>?
|
||||||
@ -119,8 +81,8 @@ actor SDLPacketReaderService {
|
|||||||
readTask?.cancel()
|
readTask?.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func readPackets(from provider: NEPacketTunnelProvider) async -> PacketReadContinuation.Result {
|
private static func readPackets(from provider: NEPacketTunnelProvider) async -> PacketReadResult {
|
||||||
let readContinuation = PacketReadContinuation()
|
let readContinuation = OnceContinuation<PacketReadResult, Never>()
|
||||||
|
|
||||||
return await withTaskCancellationHandler {
|
return await withTaskCancellationHandler {
|
||||||
await withCheckedContinuation { continuation in
|
await withCheckedContinuation { continuation in
|
||||||
@ -130,7 +92,7 @@ actor SDLPacketReaderService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} onCancel: {
|
} onCancel: {
|
||||||
readContinuation.cancel()
|
readContinuation.resume(returning: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
56
Tun/Punchnet/OnceContinuation.swift
Normal file
56
Tun/Punchnet/OnceContinuation.swift
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//
|
||||||
|
// OnceContinuation.swift
|
||||||
|
// Tun
|
||||||
|
//
|
||||||
|
// Created by Codex on 2026/5/7.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
final class OnceContinuation<Value, Failure: Error>: @unchecked Sendable {
|
||||||
|
private let lock = NSLock()
|
||||||
|
private var continuation: CheckedContinuation<Value, Failure>?
|
||||||
|
private var result: Result<Value, Failure>?
|
||||||
|
|
||||||
|
func set(_ continuation: CheckedContinuation<Value, Failure>) {
|
||||||
|
lock.lock()
|
||||||
|
if let result {
|
||||||
|
lock.unlock()
|
||||||
|
continuation.resume(with: result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let hasPendingContinuation = self.continuation != nil
|
||||||
|
if !hasPendingContinuation {
|
||||||
|
self.continuation = continuation
|
||||||
|
}
|
||||||
|
lock.unlock()
|
||||||
|
|
||||||
|
if hasPendingContinuation {
|
||||||
|
preconditionFailure("OnceContinuation can only store one pending continuation")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resume(returning value: Value) {
|
||||||
|
resume(with: .success(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
func resume(throwing error: Failure) {
|
||||||
|
resume(with: .failure(error))
|
||||||
|
}
|
||||||
|
|
||||||
|
func resume(with result: Result<Value, Failure>) {
|
||||||
|
lock.lock()
|
||||||
|
guard self.result == nil else {
|
||||||
|
lock.unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.result = result
|
||||||
|
let continuation = self.continuation
|
||||||
|
self.continuation = nil
|
||||||
|
lock.unlock()
|
||||||
|
|
||||||
|
continuation?.resume(with: result)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user