fix
This commit is contained in:
parent
66e2877044
commit
3f5beb8410
@ -140,7 +140,7 @@ actor SDLContextActor {
|
|||||||
await self?.handleUDPHoleEvent(event)
|
await self?.handleUDPHoleEvent(event)
|
||||||
}
|
}
|
||||||
self.udpHoleService = udpHoleService
|
self.udpHoleService = udpHoleService
|
||||||
await udpHoleService.start()
|
await udpHoleService.start(includeV6: false)
|
||||||
|
|
||||||
let superService = SDLSuperService(host: self.config.serverHost) { [weak self] message in
|
let superService = SDLSuperService(host: self.config.serverHost) { [weak self] message in
|
||||||
await self?.handleSuperMessage(message: message)
|
await self?.handleSuperMessage(message: message)
|
||||||
|
|||||||
@ -8,9 +8,68 @@ actor SDLPacketReaderService {
|
|||||||
|
|
||||||
typealias EventHandler = @Sendable (Event) async -> Void
|
typealias EventHandler = @Sendable (Event) async -> Void
|
||||||
|
|
||||||
|
private final class CancellationToken: @unchecked Sendable {
|
||||||
|
private let lock = NSLock()
|
||||||
|
private var cancelled: Bool = false
|
||||||
|
|
||||||
|
var isCancelled: Bool {
|
||||||
|
lock.lock()
|
||||||
|
defer {
|
||||||
|
lock.unlock()
|
||||||
|
}
|
||||||
|
return cancelled
|
||||||
|
}
|
||||||
|
|
||||||
|
func cancel() {
|
||||||
|
lock.lock()
|
||||||
|
cancelled = true
|
||||||
|
lock.unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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>?
|
||||||
|
private var readToken: CancellationToken?
|
||||||
|
|
||||||
init(provider: NEPacketTunnelProvider, onEvent: @escaping EventHandler) {
|
init(provider: NEPacketTunnelProvider, onEvent: @escaping EventHandler) {
|
||||||
self.provider = provider
|
self.provider = provider
|
||||||
@ -24,14 +83,24 @@ actor SDLPacketReaderService {
|
|||||||
|
|
||||||
let provider = self.provider
|
let provider = self.provider
|
||||||
let onEvent = self.onEvent
|
let onEvent = self.onEvent
|
||||||
|
let readToken = CancellationToken()
|
||||||
|
self.readToken = readToken
|
||||||
|
|
||||||
self.readTask = Task(priority: .high) {
|
self.readTask = Task(priority: .high) {
|
||||||
while !Task.isCancelled {
|
while !Task.isCancelled && !readToken.isCancelled {
|
||||||
let (packets, numbers) = await provider.packetFlow.readPackets()
|
guard let batch = await Self.readPackets(from: provider) else {
|
||||||
if Task.isCancelled {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
for (data, number) in zip(packets, numbers) where number == 2 {
|
if Task.isCancelled || readToken.isCancelled {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
for (data, number) in zip(batch.packets, batch.protocols) where number.int32Value == 2 {
|
||||||
|
if Task.isCancelled || readToken.isCancelled {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
if let packet = IPPacket(data) {
|
if let packet = IPPacket(data) {
|
||||||
await onEvent(.packet(packet))
|
await onEvent(.packet(packet))
|
||||||
}
|
}
|
||||||
@ -44,6 +113,24 @@ actor SDLPacketReaderService {
|
|||||||
func stop() {
|
func stop() {
|
||||||
let readTask = self.readTask
|
let readTask = self.readTask
|
||||||
self.readTask = nil
|
self.readTask = nil
|
||||||
|
let readToken = self.readToken
|
||||||
|
self.readToken = nil
|
||||||
|
readToken?.cancel()
|
||||||
readTask?.cancel()
|
readTask?.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static func readPackets(from provider: NEPacketTunnelProvider) async -> PacketReadContinuation.Result {
|
||||||
|
let readContinuation = PacketReadContinuation()
|
||||||
|
|
||||||
|
return await withTaskCancellationHandler {
|
||||||
|
await withCheckedContinuation { continuation in
|
||||||
|
readContinuation.set(continuation)
|
||||||
|
provider.packetFlow.readPackets { packets, protocols in
|
||||||
|
readContinuation.resume(returning: (packets: packets, protocols: protocols))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} onCancel: {
|
||||||
|
readContinuation.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user