Skip to content

Commit 9e9d056

Browse files
authored
Transition to Mutex (#364)
Due to the reduced use of the macro, we can now fully transition to `Mutex`.
1 parent 16f2630 commit 9e9d056

File tree

6 files changed

+41
-30
lines changed

6 files changed

+41
-30
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ cleancontent:
189189

190190
.PHONY: clean
191191
clean:
192-
@echo Cleaning the build files...
192+
@echo Cleaning build files...
193193
@rm -rf bin/ libexec/
194194
@rm -rf _site _serve
195195
@$(SWIFT) package clean

Package.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,7 @@ let package = Package(
361361
.target(
362362
name: "TerminalProgress",
363363
dependencies: [
364-
.product(name: "ContainerizationOS", package: "containerization"),
365-
.product(name: "SendableProperty", package: "containerization"),
364+
.product(name: "ContainerizationOS", package: "containerization")
366365
]
367366
),
368367
.testTarget(

Sources/Services/ContainerNetworkService/ReservedVmnetNetwork.swift

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,27 @@ import ContainerizationExtras
2121
import Dispatch
2222
import Foundation
2323
import Logging
24-
import SendableProperty
24+
import Synchronization
2525
import SystemConfiguration
2626
import XPC
2727
import vmnet
2828

2929
/// Creates a vmnet network with reservation APIs.
3030
@available(macOS 26, *)
3131
public final class ReservedVmnetNetwork: Network {
32-
@SendablePropertyUnchecked
33-
private var _state: NetworkState
34-
private let log: Logger
32+
private struct State {
33+
var networkState: NetworkState
34+
var network: vmnet_network_ref?
35+
}
36+
37+
private struct NetworkInfo {
38+
let network: vmnet_network_ref
39+
let subnet: CIDRAddress
40+
let gateway: IPv4Address
41+
}
3542

36-
@SendableProperty
37-
private var network: vmnet_network_ref?
38-
@SendableProperty
39-
private var interface: interface_ref?
40-
private let networkLock = NSLock()
43+
private let stateMutex: Mutex<State>
44+
private let log: Logger
4145

4246
/// Configure a bridge network that allows external system access using
4347
/// network address translation.
@@ -51,26 +55,33 @@ public final class ReservedVmnetNetwork: Network {
5155

5256
log.info("creating vmnet network")
5357
self.log = log
54-
_state = .created(configuration)
58+
let initialState = State(networkState: .created(configuration))
59+
stateMutex = Mutex(initialState)
5560
log.info("created vmnet network")
5661
}
5762

5863
public var state: NetworkState {
59-
get async { _state }
64+
stateMutex.withLock { $0.networkState }
6065
}
6166

6267
public nonisolated func withAdditionalData(_ handler: (XPCMessage?) throws -> Void) throws {
63-
try networkLock.withLock {
64-
try handler(network.map { try Self.serialize_network_ref(ref: $0) })
68+
try stateMutex.withLock { state in
69+
try handler(state.network.map { try Self.serialize_network_ref(ref: $0) })
6570
}
6671
}
6772

6873
public func start() async throws {
69-
guard case .created(let configuration) = _state else {
70-
throw ContainerizationError(.invalidArgument, message: "cannot start network that is in \(_state.state) state")
71-
}
74+
try stateMutex.withLock { state in
75+
guard case .created(let configuration) = state.networkState else {
76+
throw ContainerizationError(.invalidArgument, message: "cannot start network that is in \(state.networkState.state) state")
77+
}
78+
79+
let networkInfo = try startNetwork(configuration: configuration, log: log)
7280

73-
try startNetwork(configuration: configuration, log: log)
81+
let networkStatus = NetworkStatus(address: networkInfo.subnet.description, gateway: networkInfo.gateway.description)
82+
state.networkState = NetworkState.running(configuration, networkStatus)
83+
state.network = networkInfo.network
84+
}
7485
}
7586

7687
private static func serialize_network_ref(ref: vmnet_network_ref) throws -> XPCMessage {
@@ -81,7 +92,7 @@ public final class ReservedVmnetNetwork: Network {
8192
return XPCMessage(object: refObject)
8293
}
8394

84-
private func startNetwork(configuration: NetworkConfiguration, log: Logger) throws {
95+
private func startNetwork(configuration: NetworkConfiguration, log: Logger) throws -> NetworkInfo {
8596
log.info(
8697
"starting vmnet network",
8798
metadata: [
@@ -125,7 +136,6 @@ public final class ReservedVmnetNetwork: Network {
125136
guard let network = vmnet_network_create(vmnetConfiguration, &status), status == .VMNET_SUCCESS else {
126137
throw ContainerizationError(.unsupported, message: "failed to create vmnet network with status \(status)")
127138
}
128-
self.network = network
129139

130140
// retrieve the subnet since the caller may not have provided one
131141
var subnetAddr = in_addr()
@@ -137,7 +147,7 @@ public final class ReservedVmnetNetwork: Network {
137147
let upper = IPv4Address(fromValue: lower.value + ~maskValue)
138148
let runningSubnet = try CIDRAddress(lower: lower, upper: upper)
139149
let runningGateway = IPv4Address(fromValue: runningSubnet.lower.value + 1)
140-
self._state = .running(configuration, NetworkStatus(address: runningSubnet.description, gateway: runningGateway.description))
150+
141151
log.info(
142152
"started vmnet network",
143153
metadata: [
@@ -146,5 +156,7 @@ public final class ReservedVmnetNetwork: Network {
146156
"cidr": "\(runningSubnet)",
147157
]
148158
)
159+
160+
return NetworkInfo(network: network, subnet: runningSubnet, gateway: runningGateway)
149161
}
150162
}

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) {

Sources/TerminalProgress/ProgressBar+Terminal.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ extension ProgressBar {
6666
var text = text
6767

6868
// Clears previously printed characters if the new string is shorter.
69-
text += String(repeating: " ", count: max(printedWidth - text.count, 0))
70-
printedWidth = text.count
69+
printedWidth.withLock {
70+
text += String(repeating: " ", count: max($0 - text.count, 0))
71+
$0 = text.count
72+
}
7173
state.withLock {
7274
$0.output = text
7375
}

Sources/TerminalProgress/ProgressBar.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@
1515
//===----------------------------------------------------------------------===//
1616

1717
import Foundation
18-
import SendableProperty
1918
import Synchronization
2019

2120
/// A progress bar that updates itself as tasks are completed.
2221
public final class ProgressBar: Sendable {
2322
let config: ProgressConfig
2423
let state: Mutex<State>
25-
@SendableProperty
26-
var printedWidth = 0
24+
let printedWidth = Mutex(0)
2725
let term: FileHandle?
2826
let termQueue = DispatchQueue(label: "com.apple.container.ProgressBar")
2927
private let standardError = StandardError()

0 commit comments

Comments
 (0)