Skip to content

Commit e77bf5e

Browse files
committed
Foundation: restructure FoundationNetworking
1 parent 4a3fe0d commit e77bf5e

35 files changed

+465
-206
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ target_include_directories(CoreFoundation PRIVATE
4646

4747
add_subdirectory(uuid)
4848
add_subdirectory(Foundation)
49+
add_subdirectory(Sources)
4950
add_subdirectory(Tools)
5051
if(ENABLE_TESTING)
5152
find_package(XCTest CONFIG REQUIRED)

Foundation.xcodeproj/project.pbxproj

Lines changed: 171 additions & 154 deletions
Large diffs are not rendered by default.

Foundation/CMakeLists.txt

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -175,54 +175,6 @@ set_target_properties(Foundation PROPERTIES
175175
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/swift)
176176

177177

178-
add_library(FoundationNetworking
179-
Boxing.swift
180-
NSURLRequest.swift
181-
HTTPCookie.swift
182-
HTTPCookieStorage.swift
183-
URLAuthenticationChallenge.swift
184-
URLCache.swift
185-
URLCredential.swift
186-
URLCredentialStorage.swift
187-
URLProtectionSpace.swift
188-
URLProtocol.swift
189-
URLRequest.swift
190-
URLResponse.swift
191-
URLSession/BodySource.swift
192-
URLSession/Configuration.swift
193-
URLSession/http/HTTPMessage.swift
194-
URLSession/http/HTTPURLProtocol.swift
195-
URLSession/libcurl/EasyHandle.swift
196-
URLSession/libcurl/libcurlHelpers.swift
197-
URLSession/libcurl/MultiHandle.swift
198-
URLSession/Message.swift
199-
URLSession/NativeProtocol.swift
200-
URLSession/NetworkingSpecific.swift
201-
URLSession/ftp/FTPURLProtocol.swift
202-
URLSession/TaskRegistry.swift
203-
URLSession/TransferState.swift
204-
URLSession/URLSession.swift
205-
URLSession/URLSessionConfiguration.swift
206-
URLSession/URLSessionDelegate.swift
207-
URLSession/URLSessionTask.swift)
208-
target_compile_definitions(FoundationNetworking PRIVATE
209-
DEPLOYMENT_RUNTIME_SWIFT
210-
NS_BUILDING_FOUNDATION_NETWORKING)
211-
target_compile_options(FoundationNetworking PUBLIC
212-
"SHELL:-Xcc -F${CMAKE_BINARY_DIR}")
213-
if(ENABLE_TESTING)
214-
target_compile_options(FoundationNetworking PRIVATE
215-
-enable-testing)
216-
endif()
217-
target_link_libraries(FoundationNetworking PRIVATE
218-
Foundation
219-
CFURLSessionInterface)
220-
set_target_properties(FoundationNetworking PROPERTIES
221-
INSTALL_RPATH "$ORIGIN"
222-
Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift
223-
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/swift)
224-
225-
226178
add_library(FoundationXML
227179
XMLDocument.swift
228180
XMLDTD.swift
@@ -248,17 +200,15 @@ set_target_properties(FoundationXML PROPERTIES
248200

249201

250202
set_property(GLOBAL APPEND PROPERTY Foundation_EXPORTS
251-
Foundation FoundationNetworking FoundationXML)
203+
Foundation FoundationXML)
252204
get_swift_host_arch(swift_arch)
253-
install(TARGETS Foundation FoundationNetworking FoundationXML
205+
install(TARGETS Foundation FoundationXML
254206
ARCHIVE DESTINATION lib/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>/$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>
255207
LIBRARY DESTINATION lib/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>/$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>
256208
RUNTIME DESTINATION bin)
257209
install(FILES
258210
${CMAKE_BINARY_DIR}/swift/Foundation.swiftdoc
259211
${CMAKE_BINARY_DIR}/swift/Foundation.swiftmodule
260-
${CMAKE_BINARY_DIR}/swift/FoundationNetworking.swiftdoc
261-
${CMAKE_BINARY_DIR}/swift/FoundationNetworking.swiftmodule
262212
${CMAKE_BINARY_DIR}/swift/FoundationXML.swiftdoc
263213
${CMAKE_BINARY_DIR}/swift/FoundationXML.swiftmodule
264214
DESTINATION lib/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>/$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>/${swift_arch})

Sources/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_subdirectory(FoundationNetworking)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
add_library(FoundationNetworking
2+
../Foundation/Boxing.swift
3+
NSURLRequest.swift
4+
HTTPCookie.swift
5+
HTTPCookieStorage.swift
6+
URLAuthenticationChallenge.swift
7+
URLCache.swift
8+
URLCredential.swift
9+
URLCredentialStorage.swift
10+
URLProtectionSpace.swift
11+
URLProtocol.swift
12+
URLRequest.swift
13+
URLResponse.swift
14+
URLSession/BodySource.swift
15+
URLSession/Configuration.swift
16+
URLSession/http/HTTPMessage.swift
17+
URLSession/http/HTTPURLProtocol.swift
18+
URLSession/libcurl/EasyHandle.swift
19+
URLSession/libcurl/libcurlHelpers.swift
20+
URLSession/libcurl/MultiHandle.swift
21+
URLSession/Message.swift
22+
URLSession/NativeProtocol.swift
23+
URLSession/NetworkingSpecific.swift
24+
URLSession/ftp/FTPURLProtocol.swift
25+
URLSession/TaskRegistry.swift
26+
URLSession/TransferState.swift
27+
URLSession/URLSession.swift
28+
URLSession/URLSessionConfiguration.swift
29+
URLSession/URLSessionDelegate.swift
30+
URLSession/URLSessionTask.swift)
31+
target_compile_definitions(FoundationNetworking PRIVATE
32+
DEPLOYMENT_RUNTIME_SWIFT
33+
NS_BUILDING_FOUNDATION_NETWORKING)
34+
target_compile_options(FoundationNetworking PUBLIC
35+
"SHELL:-Xcc -F${CMAKE_BINARY_DIR}"
36+
$<$<BOOL:${ENABLE_TESTING}>:-enable-testing>)
37+
target_link_libraries(FoundationNetworking PRIVATE
38+
Foundation
39+
CFURLSessionInterface)
40+
set_target_properties(FoundationNetworking PROPERTIES
41+
INSTALL_RPATH "$ORIGIN"
42+
Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift
43+
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/swift)
44+
45+
46+
set_property(GLOBAL APPEND PROPERTY Foundation_EXPORTS FoundationNetworking)
47+
install(TARGETS FoundationNetworking
48+
ARCHIVE DESTINATION lib/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>/$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>
49+
LIBRARY DESTINATION lib/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>/$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>
50+
RUNTIME DESTINATION bin)
51+
get_swift_host_arch(swift_arch)
52+
install(FILES
53+
$<TARGET_PROPERTY:FoundationNetworking,Swift_MODULE_DIRECTORY>/FoundationNetworking.swiftdoc
54+
$<TARGET_PROPERTY:FoundationNetworking,Swift_MODULE_DIRECTORY>/FoundationNetworking.swiftmodule
55+
DESTINATION lib/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>/$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>/${swift_arch})
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#if NS_BUILDING_FOUNDATION_NETWORKING
14+
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
15+
import SwiftFoundation
16+
#else
17+
import Foundation
18+
#endif
19+
#endif
20+
21+
/// A class type which acts as a handle (pointer-to-pointer) to a Foundation reference type which has only a mutable class (e.g., NSURLComponents).
22+
///
23+
/// Note: This assumes that the result of calling copy() is mutable. The documentation says that classes which do not have a mutable/immutable distinction should just adopt NSCopying instead of NSMutableCopying.
24+
internal final class _MutableHandle<MutableType : NSObject> where MutableType : NSCopying {
25+
@usableFromInline internal var _pointer : MutableType
26+
27+
init(reference : MutableType) {
28+
_pointer = reference.copy() as! MutableType
29+
}
30+
31+
init(adoptingReference reference: MutableType) {
32+
_pointer = reference
33+
}
34+
35+
/// Apply a closure to the reference type.
36+
func map<ReturnType>(_ whatToDo : (MutableType) throws -> ReturnType) rethrows -> ReturnType {
37+
return try whatToDo(_pointer)
38+
}
39+
40+
func _copiedReference() -> MutableType {
41+
return _pointer.copy() as! MutableType
42+
}
43+
44+
func _uncopiedReference() -> MutableType {
45+
return _pointer
46+
}
47+
}
48+
49+
/// Describes common operations for Foundation struct types that are bridged to a mutable object (e.g. NSURLComponents).
50+
internal protocol _MutableBoxing : ReferenceConvertible {
51+
var _handle : _MutableHandle<ReferenceType> { get set }
52+
53+
/// Apply a mutating closure to the reference type, regardless if it is mutable or immutable.
54+
///
55+
/// This function performs the correct copy-on-write check for efficient mutation.
56+
mutating func _applyMutation<ReturnType>(_ whatToDo : (ReferenceType) -> ReturnType) -> ReturnType
57+
}
58+
59+
extension _MutableBoxing {
60+
@inline(__always)
61+
mutating func _applyMutation<ReturnType>(_ whatToDo : (ReferenceType) -> ReturnType) -> ReturnType {
62+
// Only create a new box if we are not uniquely referenced
63+
if !isKnownUniquelyReferenced(&_handle) {
64+
let ref = _handle._pointer
65+
_handle = _MutableHandle(reference: ref)
66+
}
67+
return whatToDo(_handle._pointer)
68+
}
69+
}
70+
71+
internal enum _MutableUnmanagedWrapper<ImmutableType : NSObject, MutableType : NSObject> where MutableType : NSMutableCopying {
72+
case Immutable(Unmanaged<ImmutableType>)
73+
case Mutable(Unmanaged<MutableType>)
74+
}
75+
76+
internal protocol _SwiftNativeFoundationType : class {
77+
associatedtype ImmutableType : NSObject
78+
associatedtype MutableType : NSObject, NSMutableCopying
79+
var __wrapped : _MutableUnmanagedWrapper<ImmutableType, MutableType> { get }
80+
81+
init(unmanagedImmutableObject: Unmanaged<ImmutableType>)
82+
init(unmanagedMutableObject: Unmanaged<MutableType>)
83+
84+
func mutableCopy(with zone : NSZone) -> Any
85+
86+
func hash(into hasher: inout Hasher)
87+
var hashValue: Int { get }
88+
89+
var description: String { get }
90+
var debugDescription: String { get }
91+
92+
func releaseWrappedObject()
93+
}
94+
95+
extension _SwiftNativeFoundationType {
96+
97+
@inline(__always)
98+
func _mapUnmanaged<ReturnType>(_ whatToDo : (ImmutableType) throws -> ReturnType) rethrows -> ReturnType {
99+
defer { _fixLifetime(self) }
100+
101+
switch __wrapped {
102+
case .Immutable(let i):
103+
return try i._withUnsafeGuaranteedRef {
104+
_onFastPath()
105+
return try whatToDo($0)
106+
}
107+
case .Mutable(let m):
108+
return try m._withUnsafeGuaranteedRef {
109+
_onFastPath()
110+
return try whatToDo(_unsafeReferenceCast($0, to: ImmutableType.self))
111+
}
112+
}
113+
}
114+
115+
func releaseWrappedObject() {
116+
switch __wrapped {
117+
case .Immutable(let i):
118+
i.release()
119+
case .Mutable(let m):
120+
m.release()
121+
}
122+
}
123+
124+
func mutableCopy(with zone : NSZone) -> Any {
125+
return _mapUnmanaged { ($0 as NSObject).mutableCopy() }
126+
}
127+
128+
func hash(into hasher: inout Hasher) {
129+
_mapUnmanaged { hasher.combine($0) }
130+
}
131+
132+
var hashValue: Int {
133+
return _mapUnmanaged { return $0.hashValue }
134+
}
135+
136+
var description: String {
137+
return _mapUnmanaged { return $0.description }
138+
}
139+
140+
var debugDescription: String {
141+
return _mapUnmanaged { return $0.debugDescription }
142+
}
143+
144+
func isEqual(_ other: AnyObject) -> Bool {
145+
return _mapUnmanaged { return $0.isEqual(other) }
146+
}
147+
}
148+
149+
internal protocol _MutablePairBoxing {
150+
associatedtype WrappedSwiftNSType : _SwiftNativeFoundationType
151+
var _wrapped : WrappedSwiftNSType { get set }
152+
}
153+
154+
extension _MutablePairBoxing {
155+
@inline(__always)
156+
func _mapUnmanaged<ReturnType>(_ whatToDo : (WrappedSwiftNSType.ImmutableType) throws -> ReturnType) rethrows -> ReturnType {
157+
// We are using Unmanaged. Make sure that the owning container class
158+
// 'self' is guaranteed to be alive by extending the lifetime of 'self'
159+
// to the end of the scope of this function.
160+
// Note: At the time of this writing using withExtendedLifetime here
161+
// instead of _fixLifetime causes different ARC pair matching behavior
162+
// foiling optimization. This is why we explicitly use _fixLifetime here
163+
// instead.
164+
defer { _fixLifetime(self) }
165+
166+
let unmanagedHandle = Unmanaged.passUnretained(_wrapped)
167+
let wrapper = unmanagedHandle._withUnsafeGuaranteedRef { $0.__wrapped }
168+
switch (wrapper) {
169+
case .Immutable(let i):
170+
return try i._withUnsafeGuaranteedRef {
171+
return try whatToDo($0)
172+
}
173+
case .Mutable(let m):
174+
return try m._withUnsafeGuaranteedRef {
175+
return try whatToDo(_unsafeReferenceCast($0, to: WrappedSwiftNSType.ImmutableType.self))
176+
}
177+
}
178+
}
179+
180+
@inline(__always)
181+
mutating func _applyUnmanagedMutation<ReturnType>(_ whatToDo : (WrappedSwiftNSType.MutableType) throws -> ReturnType) rethrows -> ReturnType {
182+
// We are using Unmanaged. Make sure that the owning container class
183+
// 'self' is guaranteed to be alive by extending the lifetime of 'self'
184+
// to the end of the scope of this function.
185+
// Note: At the time of this writing using withExtendedLifetime here
186+
// instead of _fixLifetime causes different ARC pair matching behavior
187+
// foiling optimization. This is why we explicitly use _fixLifetime here
188+
// instead.
189+
defer { _fixLifetime(self) }
190+
191+
var unique = true
192+
let _unmanagedHandle = Unmanaged.passUnretained(_wrapped)
193+
let wrapper = _unmanagedHandle._withUnsafeGuaranteedRef { $0.__wrapped }
194+
195+
// This check is done twice because: <rdar://problem/24939065> Value kept live for too long causing uniqueness check to fail
196+
switch (wrapper) {
197+
case .Immutable:
198+
break
199+
case .Mutable:
200+
unique = isKnownUniquelyReferenced(&_wrapped)
201+
}
202+
203+
switch (wrapper) {
204+
case .Immutable(let i):
205+
// We need to become mutable; by creating a new instance we also become unique
206+
let copy = Unmanaged.passRetained(i._withUnsafeGuaranteedRef {
207+
return _unsafeReferenceCast($0.mutableCopy(), to: WrappedSwiftNSType.MutableType.self) }
208+
)
209+
210+
// Be sure to set the var before calling out; otherwise references to the struct in the closure may be looking at the old value
211+
_wrapped = WrappedSwiftNSType(unmanagedMutableObject: copy)
212+
return try copy._withUnsafeGuaranteedRef {
213+
_onFastPath()
214+
return try whatToDo($0)
215+
}
216+
case .Mutable(let m):
217+
// Only create a new box if we are not uniquely referenced
218+
if !unique {
219+
let copy = Unmanaged.passRetained(m._withUnsafeGuaranteedRef {
220+
return _unsafeReferenceCast($0.mutableCopy(), to: WrappedSwiftNSType.MutableType.self)
221+
})
222+
_wrapped = WrappedSwiftNSType(unmanagedMutableObject: copy)
223+
return try copy._withUnsafeGuaranteedRef {
224+
_onFastPath()
225+
return try whatToDo($0)
226+
}
227+
} else {
228+
return try m._withUnsafeGuaranteedRef {
229+
_onFastPath()
230+
return try whatToDo($0)
231+
}
232+
}
233+
}
234+
}
235+
}

0 commit comments

Comments
 (0)