12
12
//
13
13
//===----------------------------------------------------------------------===//
14
14
15
+ #if compiler(>=6.0)
16
+ import Synchronization
17
+ #endif // compiler(>=6.0)
18
+
15
19
/// A collection of HTTP fields. It is used in `HTTPRequest` and `HTTPResponse`, and can also be
16
20
/// used as HTTP trailer fields.
17
21
///
21
25
/// `HTTPFields` adheres to modern HTTP semantics. In particular, the "Cookie" request header field
22
26
/// is split into separate header fields by default.
23
27
public struct HTTPFields : Sendable , Hashable {
24
- private final class _Storage : @unchecked Sendable , Hashable {
28
+ private class _Storage : @unchecked Sendable , Hashable {
25
29
var fields : [ ( field: HTTPField , next: UInt16 ) ] = [ ]
26
30
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
+ }
28
38
29
39
var ensureIndex : [ String : ( first: UInt16 , last: UInt16 ) ] {
30
- self . lock . withLockedValue { _ in
40
+ self . withLock {
31
41
if let index = self . index {
32
42
return index
33
43
}
@@ -45,10 +55,10 @@ public struct HTTPFields: Sendable, Hashable {
45
55
}
46
56
}
47
57
48
- func copy( ) -> _Storage {
49
- let newStorage = _Storage ( )
58
+ func copy( ) -> Self {
59
+ let newStorage = Self ( )
50
60
newStorage. fields = self . fields
51
- self . lock . withLockedValue { _ in
61
+ self . withLock {
52
62
newStorage. index = self . index
53
63
}
54
64
return newStorage
@@ -99,7 +109,40 @@ public struct HTTPFields: Sendable, Hashable {
99
109
}
100
110
}
101
111
102
- private var _storage = _Storage ( )
112
+ #if compiler(>=6.0)
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 // compiler(>=6.0)
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 compiler(>=6.0)
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 // compiler(>=6.0)
143
+ _StorageWithNIOLock ( )
144
+ #endif // compiler(>=6.0)
145
+ } ( )
103
146
104
147
/// Create an empty list of HTTP fields
105
148
public init ( ) { }
0 commit comments