Skip to content

Commit 88d6989

Browse files
committed
Use a single Mutex per type
1 parent ae26dfb commit 88d6989

File tree

2 files changed

+24
-21
lines changed

2 files changed

+24
-21
lines changed

Sources/Services/ContainerNetworkService/ReservedVmnetNetwork.swift

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ import vmnet
2929
/// Creates a vmnet network with reservation APIs.
3030
@available(macOS 26, *)
3131
public final class ReservedVmnetNetwork: Network {
32-
private let _state: Mutex<NetworkState>
33-
private let log: Logger
32+
private struct State {
33+
var networkState: NetworkState
34+
var network: vmnet_network_ref?
35+
}
3436

35-
private let network = Mutex<vmnet_network_ref?>(nil)
36-
private let networkLock = NSLock()
37+
private let stateMutex: Mutex<State>
38+
private let log: Logger
3739

3840
/// Configure a bridge network that allows external system access using
3941
/// network address translation.
@@ -47,25 +49,25 @@ public final class ReservedVmnetNetwork: Network {
4749

4850
log.info("creating vmnet network")
4951
self.log = log
50-
_state = Mutex(.created(configuration))
52+
let initialState = State(networkState: .created(configuration))
53+
stateMutex = Mutex(initialState)
5154
log.info("created vmnet network")
5255
}
5356

5457
public var state: NetworkState {
55-
get async { _state.withLock { $0 } }
58+
stateMutex.withLock { $0.networkState }
5659
}
5760

5861
public nonisolated func withAdditionalData(_ handler: (XPCMessage?) throws -> Void) throws {
59-
try networkLock.withLock {
60-
let network = self.network.withLock { $0 }
61-
try handler(network.map { try Self.serialize_network_ref(ref: $0) })
62+
try stateMutex.withLock { state in
63+
try handler(state.network.map { try Self.serialize_network_ref(ref: $0) })
6264
}
6365
}
6466

6567
public func start() async throws {
66-
let state = _state.withLock { $0 }
67-
guard case .created(let configuration) = state else {
68-
throw ContainerizationError(.invalidArgument, message: "cannot start network that is in \(state.state) state")
68+
let networkState = stateMutex.withLock { $0.networkState }
69+
guard case .created(let configuration) = networkState else {
70+
throw ContainerizationError(.invalidArgument, message: "cannot start network that is in \(networkState.state) state")
6971
}
7072

7173
try startNetwork(configuration: configuration, log: log)
@@ -124,11 +126,6 @@ public final class ReservedVmnetNetwork: Network {
124126
throw ContainerizationError(.unsupported, message: "failed to create vmnet network with status \(status)")
125127
}
126128

127-
let newNetwork = { network } // A workaround for "'inout sending' parameter '$0' cannot be task-isolated at end of function".
128-
self.network.withLock {
129-
$0 = newNetwork()
130-
}
131-
132129
// retrieve the subnet since the caller may not have provided one
133130
var subnetAddr = in_addr()
134131
var maskAddr = in_addr()
@@ -139,8 +136,14 @@ public final class ReservedVmnetNetwork: Network {
139136
let upper = IPv4Address(fromValue: lower.value + ~maskValue)
140137
let runningSubnet = try CIDRAddress(lower: lower, upper: upper)
141138
let runningGateway = IPv4Address(fromValue: runningSubnet.lower.value + 1)
142-
let newState = NetworkState.running(configuration, NetworkStatus(address: runningSubnet.description, gateway: runningGateway.description))
143-
self._state.withLock { $0 = newState }
139+
let networkState = NetworkState.running(configuration, NetworkStatus(address: runningSubnet.description, gateway: runningGateway.description))
140+
141+
let newNetwork = { network } // A workaround for "'inout sending' parameter '$0' cannot be task-isolated at end of function".
142+
stateMutex.withLock { state in
143+
state.network = newNetwork()
144+
state.networkState = networkState
145+
}
146+
144147
log.info(
145148
"started vmnet network",
146149
metadata: [

Sources/SocketForwarder/UDPForwarder.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ private final class UDPProxyBackend: ChannelInboundHandler, Sendable {
4242
self.serverAddress = serverAddress
4343
self.frontendChannel = frontendChannel
4444
self.log = log
45-
let state = State(queuedPayloads: Deque(), channel: nil)
46-
self.state = Mutex(state)
45+
let initialState = State(queuedPayloads: Deque(), channel: nil)
46+
self.state = Mutex(initialState)
4747
}
4848

4949
func channelRead(context: ChannelHandlerContext, data: NIOAny) {

0 commit comments

Comments
 (0)