1212//
1313//===----------------------------------------------------------------------===//
1414
15+ #if canImport(Synchronization)
16+ import Synchronization
17+ #endif // canImport(Synchronization)
18+
1519/// A collection of HTTP fields. It is used in `HTTPRequest` and `HTTPResponse`, and can also be
1620/// used as HTTP trailer fields.
1721///
2125/// `HTTPFields` adheres to modern HTTP semantics. In particular, the "Cookie" request header field
2226/// is split into separate header fields by default.
2327public struct HTTPFields : Sendable , Hashable {
24- private final class _Storage : @unchecked Sendable , Hashable {
28+ private class _Storage : @unchecked Sendable , Hashable {
2529 var fields : [ ( field: HTTPField , next: UInt16 ) ] = [ ]
2630 var index : [ String : ( first: UInt16 , last: UInt16 ) ] ? = [ : ]
27- let lock = LockStorage . create ( value: ( ) )
31+
32+ required init ( ) {
33+ }
34+
35+ func withLock< Result> ( _ body: ( ) throws -> Result ) rethrows -> Result {
36+ fatalError ( )
37+ }
2838
2939 var ensureIndex : [ String : ( first: UInt16 , last: UInt16 ) ] {
30- self . lock . withLockedValue { _ in
40+ self . withLock {
3141 if let index = self . index {
3242 return index
3343 }
@@ -45,10 +55,10 @@ public struct HTTPFields: Sendable, Hashable {
4555 }
4656 }
4757
48- func copy( ) -> _Storage {
49- let newStorage = _Storage ( )
58+ func copy( ) -> Self {
59+ let newStorage = Self ( )
5060 newStorage. fields = self . fields
51- self . lock . withLockedValue { _ in
61+ self . withLock {
5262 newStorage. index = self . index
5363 }
5464 return newStorage
@@ -99,7 +109,40 @@ public struct HTTPFields: Sendable, Hashable {
99109 }
100110 }
101111
102- private var _storage = _Storage ( )
112+ #if canImport(Synchronization)
113+ @available ( macOS 15 . 0 , iOS 18 . 0 , watchOS 11 . 0 , tvOS 18 . 0 , visionOS 2 . 0 , * )
114+ private final class _StorageWithMutex : _Storage , @unchecked Sendable {
115+ let mutex = Mutex < Void > ( ( ) )
116+
117+ override func withLock< Result> ( _ body: ( ) throws -> Result ) rethrows -> Result {
118+ try self . mutex. withLock { _ in
119+ try body ( )
120+ }
121+ }
122+ }
123+ #endif // canImport(Synchronization)
124+
125+ private final class _StorageWithNIOLock : _Storage , @unchecked Sendable {
126+ let lock = LockStorage . create ( value: ( ) )
127+
128+ override func withLock< Result> ( _ body: ( ) throws -> Result ) rethrows -> Result {
129+ try self . lock. withLockedValue { _ in
130+ try body ( )
131+ }
132+ }
133+ }
134+
135+ private var _storage = {
136+ #if canImport(Synchronization)
137+ if #available( macOS 15 . 0 , iOS 18 . 0 , watchOS 11 . 0 , tvOS 18 . 0 , visionOS 2 . 0 , * ) {
138+ _StorageWithMutex ( )
139+ } else {
140+ _StorageWithNIOLock ( )
141+ }
142+ #else // canImport(Synchronization)
143+ _StorageWithNIOLock ( )
144+ #endif // canImport(Synchronization)
145+ } ( )
103146
104147 /// Create an empty list of HTTP fields
105148 public init ( ) { }
0 commit comments