Skip to content

Commit

Permalink
Whitespace
Browse files Browse the repository at this point in the history
  • Loading branch information
acb-mv committed Mar 14, 2024
1 parent cee4843 commit 2be241f
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 36 deletions.
50 changes: 25 additions & 25 deletions ios/PacketTunnelCore/Actor/CommandChannel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,114 +53,114 @@ extension PacketTunnelActor {
private enum State {
/// Channel is active and running.
case active

/// Channel is awaiting for the buffer to be exhausted before ending all async iterations.
/// Publishing new values in this state is impossible.
case pendingEnd

/// Channel finished its work.
/// Publishing new values in this state is impossible.
/// An attempt to iterate over the channel in this state is equivalent to iterating over an empty array.
case finished
}

/// A buffer of commands received but not consumed yet.
private var buffer: [Command] = []

/// Async continuations awaiting to receive the new value.
/// Continuations are stored here when there is no new value available for immediate delivery.
private var pendingContinuations: [CheckedContinuation<Command?, Never>] = []

private var state: State = .active
private var stateLock = NSLock()

init() {}

deinit {
// Resume all continuations
finish()
}

/// Send command to consumer.
///
/// - Parameter value: a new command.
func send(_ value: Command) {
stateLock.withLock {
guard case .active = state else { return }

buffer.append(value)

if !pendingContinuations.isEmpty, let nextValue = consumeFirst() {
let continuation = pendingContinuations.removeFirst()
continuation.resume(returning: nextValue)
}
}
}

/// Mark the end of channel but let consumers exchaust the buffer before declaring the end of iteration.
/// If the buffer is empty then it should resume all pending continuations and send them `nil` to mark the end of iteration.
func sendEnd() {
stateLock.withLock {
if case .active = state {
state = .pendingEnd

if buffer.isEmpty {
state = .finished
sendEndToPendingContinuations()
}
}
}
}

/// Flush buffered commands and resume all pending continuations sending them `nil` to mark the end of iteration.
func finish() {
stateLock.withLock {
switch state {
case .active, .pendingEnd:
state = .finished
buffer.removeAll()

sendEndToPendingContinuations()

case .finished:
break
}
}
}

/// Send `nil` to mark the end of iteration to all pending continuations.
private func sendEndToPendingContinuations() {
for continuation in pendingContinuations {
continuation.resume(returning: nil)
}
pendingContinuations.removeAll()
}

/// Consume first message in the buffer.
/// Returns `nil` if the buffer is empty, otherwise if attempts to coalesce buffered commands before consuming the first comand in the list.
private func consumeFirst() -> Command? {
guard !buffer.isEmpty else { return nil }

coalesce()
return buffer.removeFirst()
}

/// Coalesce buffered commands to prevent future execution when the outcome is considered to be similar.
/// Mutates internal `buffer`.
private func coalesce() {
var i = buffer.count - 1
while i > 0 {
defer { i -= 1 }

assert(i < buffer.count)
let current = buffer[i]

// Remove all preceding commands when encountered "stop".
if case .stop = current {
buffer.removeFirst(i)
return
}

// Coalesce earlier reconnection attempts into the most recent.
// This will rearrange the command buffer but hopefully should have no side effects.
if case .reconnect = current {
Expand All @@ -176,7 +176,7 @@ extension PacketTunnelActor {
}
}
}

private func next() async -> Command? {
return await withCheckedContinuation { continuation in
stateLock.withLock {
Expand All @@ -189,14 +189,14 @@ extension PacketTunnelActor {
// Keep consuming until the buffer is exhausted.
fallthrough
}

case .active:
if let value = consumeFirst() {
continuation.resume(returning: value)
} else {
pendingContinuations.append(continuation)
}

case .finished:
continuation.resume(returning: nil)
}
Expand Down
4 changes: 2 additions & 2 deletions ios/PacketTunnelCore/Actor/PacketTunnelActor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ public actor PacketTunnelActor {

case let .networkReachability(defaultPath):
await handleDefaultPathChange(defaultPath)
case let .replaceDevicePrivateKey(_):

case .replaceDevicePrivateKey:
self.logger.warning("Not yet implemented")
}
}
Expand Down
18 changes: 9 additions & 9 deletions ios/PacketTunnelCore/Actor/PacketTunnelActorCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,31 @@ extension PacketTunnelActor {
enum Command {
/// Start tunnel.
case start(StartOptions)

/// Stop tunnel.
case stop

/// Reconnect tunnel.
case reconnect(NextRelay, reason: ReconnectReason = .userInitiated)

/// Enter blocked state.
case error(BlockedStateReason)

/// Notify that key rotation took place
case notifyKeyRotated(Date?)

/// Switch to using the recently pushed WG key.
case switchKey

/// Monitor events.
case monitorEvent(_ event: TunnelMonitorEvent)

/// Network reachability events.
case networkReachability(NetworkPath)

/// Update the device private key, as per post-quantum protocols
case replaceDevicePrivateKey(PrivateKey)

/// Format command for log output.
func logFormat() -> String {
switch self {
Expand Down

0 comments on commit 2be241f

Please sign in to comment.