@@ -29,11 +29,13 @@ import vmnet
2929/// Creates a vmnet network with reservation APIs.
3030@available ( macOS 26 , * )
3131public 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: [
0 commit comments