Skip to content
Merged
Show file tree
Hide file tree
Changes from 62 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
56fc64e
Unchecked sendable everywhere but builds with a change in C and a lot…
waahm7 Dec 27, 2024
2e659ac
some docs
waahm7 Dec 28, 2024
16c705b
warning fix plus tests in progress
waahm7 Dec 30, 2024
149abc4
non working
waahm7 Dec 30, 2024
853fa9e
More fixes
waahm7 Dec 30, 2024
b12eebd
more fixes
waahm7 Jan 6, 2025
5b3f624
more fixes
waahm7 Jan 6, 2025
2f3aac0
update comment
waahm7 Jan 6, 2025
703b650
fix test
waahm7 Jan 6, 2025
2478627
more fixes
waahm7 Jan 6, 2025
2aa220f
reset package.swift
waahm7 Jan 6, 2025
75aea3f
fix stuff
waahm7 Jan 6, 2025
e35ed11
unchecked
waahm7 Jan 6, 2025
015d98c
Some ifdef
waahm7 Jan 7, 2025
54d17c3
try swift 6
waahm7 Jan 7, 2025
82f02db
try ci
waahm7 Jan 7, 2025
28d5c83
sed mac
waahm7 Jan 7, 2025
2c7b1e3
remove it
waahm7 Jan 7, 2025
45cf8d8
Merge branch 'main' into swift6-support
waahm7 Apr 3, 2025
b179c0a
MQTT changes for Swift 6
waahm7 Apr 3, 2025
3322408
unchecked sendable for FileBasedConfiguration
waahm7 Apr 3, 2025
054f55b
manager sendable
waahm7 Apr 3, 2025
ddb7601
gen ai stop adding unnecassary code
waahm7 Apr 3, 2025
8ed9511
Use argument parser for ElasticCurl
waahm7 Apr 4, 2025
dbeeb11
red code is best code
waahm7 Apr 4, 2025
35827ab
huh?
waahm7 Apr 4, 2025
851e492
lint
waahm7 Apr 4, 2025
b047034
try swift 6 CI
waahm7 Apr 4, 2025
a62b69e
checkout
waahm7 Apr 4, 2025
2a50b11
15?15?15?15?15?15?15?15?15?15?15?15?15?15?15?
waahm7 Apr 4, 2025
d708dd7
submodules
waahm7 Apr 4, 2025
6928a56
remove mqtt test for now, too many changes required
waahm7 Apr 4, 2025
62cbbab
disable warning
waahm7 Apr 7, 2025
451d671
request option sendable
waahm7 Apr 8, 2025
f9d294e
place hold for request responds client
xiazhvera Apr 8, 2025
dbcda29
rename struct
xiazhvera Apr 8, 2025
ee67970
Expose Endpoint Property directly?
waahm7 Apr 8, 2025
9b16f05
Update signing config
waahm7 Apr 14, 2025
e736583
update testsemaphore
xiazhvera Apr 14, 2025
7058122
use expectation instead of semaphore
xiazhvera Apr 14, 2025
3459187
clean up test
xiazhvera Apr 14, 2025
3435f04
fix test waiting options
xiazhvera Apr 14, 2025
3fe043e
fix retain test
xiazhvera Apr 14, 2025
e9c738f
add help function to return expecation waiter result
xiazhvera Apr 14, 2025
287edee
format fix
xiazhvera Apr 14, 2025
d5adf13
rename handler&initial tests
xiazhvera Apr 15, 2025
24f2f4b
clean up mqtt5 tests
xiazhvera Apr 15, 2025
580affa
Merge branch 'swift6-support-mqtt' of https://github.com/awslabs/aws-…
xiazhvera Apr 15, 2025
cd365bc
add help functions for connection
xiazhvera Apr 15, 2025
b606679
enable dispatch queue on apple platforms
xiazhvera Apr 15, 2025
4697c66
implement rr client creation/destruction
xiazhvera Apr 15, 2025
0b97e87
clean up documentation
xiazhvera Apr 15, 2025
f98f86a
fix class name
xiazhvera Apr 15, 2025
6410712
validate conversion to native
xiazhvera Apr 15, 2025
f7ea06a
Merge remote-tracking branch 'origin/default_eventloop' into swift6-s…
waahm7 Apr 16, 2025
2738602
Merge branch 'swift6-support' of https://github.com/awslabs/aws-crt-s…
xiazhvera Apr 16, 2025
c514649
more comments and Senable enums
xiazhvera Apr 16, 2025
503c260
Merge branch 'swift6-support-mqtt' of https://github.com/awslabs/aws-…
xiazhvera Apr 16, 2025
cd7aabe
more justification on sendable classes
xiazhvera Apr 16, 2025
7a2cfff
fix merge
xiazhvera Apr 16, 2025
44848dd
Merge branch 'swift6-support-mqtt' of https://github.com/awslabs/aws-…
xiazhvera Apr 16, 2025
f637923
set default value for client options
xiazhvera Apr 16, 2025
590263f
update code review & sendable objects
xiazhvera Apr 17, 2025
14c5bd7
lint
xiazhvera Apr 17, 2025
1734af0
update cr
xiazhvera Apr 21, 2025
c2d5f08
Merge branch 'main' of https://github.com/awslabs/aws-crt-swift into …
xiazhvera Apr 28, 2025
28688ec
Merge branch 'main' into rr_workspace
xiazhvera Apr 30, 2025
050382c
fix merge changes
xiazhvera May 8, 2025
c3c53c5
Merge branch 'main' into rr_workspace
xiazhvera May 14, 2025
99e9beb
Merge branch 'main' of https://github.com/awslabs/aws-crt-swift into …
xiazhvera May 19, 2025
32a0bb3
fix format on files
xiazhvera May 19, 2025
f9ed271
rename MqttRequestResponse
xiazhvera May 19, 2025
97e9b47
remove default value for request response client options
xiazhvera Jun 4, 2025
2679225
Merge branch 'main' into rr_workspace
xiazhvera Jun 4, 2025
d3df57c
update code review changes
xiazhvera Jun 5, 2025
60d557c
remove newFromMqtt5Client
xiazhvera Jun 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,34 @@ jobs:
chmod a+x builder
./builder build -p ${{ env.PACKAGE_NAME }}

# Test that everything works with Swift 6 strict concurrency. We can remove this CI in the future once we raise our minimum Swift version to Swift 6.
macos-swift6:
runs-on: macos-15
env:
DEVELOPER_DIR: /Applications/Xcode.app
XCODE_DESTINATION: 'OS X'
NSUnbufferedIO: YES
strategy:
fail-fast: false
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.CRT_CI_ROLE }}
aws-region: ${{ env.AWS_DEFAULT_REGION }}
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Set Swift version to 6
run: |
sed -i '' 's/swift-tools-version:5\.7/swift-tools-version:6\.0/' Package.swift
cat Package.swift | head -3
- name: Build ${{ env.PACKAGE_NAME }} + consumers
run: |
swift build
swift test

devices:
runs-on: ${{ matrix.runner }}
env:
Expand Down
13 changes: 10 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ var package = Package(name: "aws-crt-swift",
products: [
.library(name: "AwsCommonRuntimeKit", targets: ["AwsCommonRuntimeKit"]),
.executable(name: "Elasticurl", targets: ["Elasticurl"])
],
dependencies: [
// Arugment Parser Dependency for ElasticCurl
.package(url: "https://github.com/apple/swift-argument-parser.git", .upToNextMajor(from: "1.5.0"))
]
)

Expand Down Expand Up @@ -151,11 +155,11 @@ awsCIoPlatformExcludes.append("source/windows")
awsCIoPlatformExcludes.append("source/linux")
awsCIoPlatformExcludes.append("source/s2n")
cSettingsIO.append(.define("__APPLE__"))
cSettingsIO.append(.define("AWS_ENABLE_DISPATCH_QUEUE", .when(platforms: [.iOS, .tvOS, .macOS])))
cSettingsIO.append(.define("AWS_ENABLE_DISPATCH_QUEUE"))
cSettingsIO.append(.define("AWS_USE_SECITEM", .when(platforms: [.iOS, .tvOS])))
cSettingsIO.append(.define("AWS_ENABLE_KQUEUE", .when(platforms: [.macOS])))
swiftTestSettings.append(.define("__APPLE__"))
swiftTestSettings.append(.define("AWS_ENABLE_DISPATCH_QUEUE", .when(platforms: [.iOS, .tvOS, .macOS])))
swiftTestSettings.append(.define("AWS_ENABLE_DISPATCH_QUEUE"))
swiftTestSettings.append(.define("AWS_USE_SECITEM", .when(platforms: [.iOS, .tvOS])))
swiftTestSettings.append(.define("AWS_ENABLE_KQUEUE", .when(platforms: [.macOS])))
#endif
Expand Down Expand Up @@ -332,7 +336,10 @@ packageTargets.append(contentsOf: [
),
.executableTarget(
name: "Elasticurl",
dependencies: ["AwsCommonRuntimeKit"],
dependencies: [
"AwsCommonRuntimeKit",
.product(name: "ArgumentParser", package: "swift-argument-parser"),
],
path: "Source/Elasticurl"
)
] )
Expand Down
19 changes: 10 additions & 9 deletions Source/AwsCommonRuntimeKit/CommonRuntimeKit.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import AwsCEventStream
import AwsCAuth
import AwsCEventStream
import AwsCMqtt
import LibNative

/**
* Initializes the library.
* `CommonRuntimeKit.initialize` must be called before using any other functionality.
*/
/// Initializes the library.
/// `CommonRuntimeKit.initialize` must be called before using any other functionality.
public struct CommonRuntimeKit {

/// Initializes the library.
Expand All @@ -15,20 +13,23 @@ public struct CommonRuntimeKit {
aws_auth_library_init(allocator.rawValue)
aws_event_stream_library_init(allocator.rawValue)
aws_mqtt_library_init(allocator.rawValue)
aws_register_error_info(&s_crt_swift_error_list)
withUnsafePointer(to: s_crt_swift_error_list) { ptr in
aws_register_error_info(ptr)
}
}

/**
* This is an optional cleanup function which will block until all the CRT resources have cleaned up.
* Use this function only if you want to make sure that there are no memory leaks at the end of the application.
* Warning: It will hang if you are still holding references to any CRT objects such as HostResolver.
*/
public static func cleanUp() {
aws_unregister_error_info(&s_crt_swift_error_list)
public static nonisolated func cleanUp() {
withUnsafePointer(to: s_crt_swift_error_list) { ptr in
aws_unregister_error_info(ptr)
}
aws_mqtt_library_clean_up()
aws_event_stream_library_clean_up()
aws_auth_library_clean_up()

}

private init() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import AwsCAuth
import Foundation

public final class Credentials {
// We can't mutate this class after initialization. Swift can not verify the sendability due to OpaquePointer,
// So mark it unchecked Sendable
public final class Credentials: @unchecked Sendable {

let rawValue: OpaquePointer

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ public struct CognitoLoginPair: CStruct {
}
}

public class CredentialsProvider: CredentialsProviding {

// We can't mutate this class after initialization. Swift can not verify the sendability due to pointer,
// So mark it unchecked Sendable
public class CredentialsProvider: CredentialsProviding, @unchecked Sendable {
let rawValue: UnsafeMutablePointer<aws_credentials_provider>

init(credentialsProvider: UnsafeMutablePointer<aws_credentials_provider>) {
Expand Down Expand Up @@ -667,25 +668,19 @@ private func onGetCredentials(credentials: OpaquePointer?,
continuationCore.continuation.resume(returning: Credentials(rawValue: credentials!))
}

// We need to share this pointer to C in a task block but Swift compiler complains
// that Pointer does not conform to Sendable. Wrap the pointer in a @unchecked Sendable block
// for Swift compiler to stop complaining.
struct SendablePointer: @unchecked Sendable {
let pointer: UnsafeMutableRawPointer
}

private func getCredentialsDelegateFn(_ delegatePtr: UnsafeMutableRawPointer!,
_ callbackFn: (@convention(c) (
OpaquePointer?,
Int32,
UnsafeMutableRawPointer?) -> Void)!,
_ userData: UnsafeMutableRawPointer!) -> Int32 {
let delegate = Unmanaged<Box<CredentialsProviding>>
.fromOpaque(delegatePtr)
.takeUnretainedValue().contents
let userData = SendablePointer(pointer: userData)
let userData = SendableRawPointer(pointer: userData)
let delegatePtr = SendableRawPointer(pointer: delegatePtr)
Task {
do {
let delegate = Unmanaged<Box<CredentialsProviding>>
.fromOpaque(delegatePtr.pointer!)
.takeUnretainedValue().contents
let credentials = try await delegate.getCredentials()
callbackFn(credentials.rawValue, AWS_OP_SUCCESS, userData.pointer)
} catch CommonRunTimeError.crtError(let crtError) {
Expand Down
2 changes: 1 addition & 1 deletion Source/AwsCommonRuntimeKit/auth/imds/IAMProfile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import AwsCAuth
import Foundation

public struct IAMProfile {
public struct IAMProfile: Sendable {
public let lastUpdated: Date
public let profileArn: String
public let profileId: String
Expand Down
4 changes: 3 additions & 1 deletion Source/AwsCommonRuntimeKit/auth/imds/IMDSClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import AwsCAuth

// swiftlint:disable type_body_length
public class IMDSClient {
// We can't mutate this class after initialization. Swift can not verify the sendability due to OpaquePointer,
// So mark it unchecked Sendable
public class IMDSClient: @unchecked Sendable {
let rawValue: OpaquePointer

/// Creates an IMDSClient that always uses IMDSv2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import AwsCAuth
import Foundation

public struct IMDSInstanceInfo {
public struct IMDSInstanceInfo: Sendable {
public let marketPlaceProductCodes: [String]
public let availabilityZone: String
public let privateIp: String
Expand Down
10 changes: 7 additions & 3 deletions Source/AwsCommonRuntimeKit/auth/signing/Signer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,11 @@ public class Signer {
}
}

class SignRequestCore {
// After signing, we mutate the request and resume the continuation, which may result in a thread change.
// We won't modify it after continuation.resume is called. So we can mark it @unchecked Sendable
class SignRequestCore: @unchecked Sendable {
let request: HTTPRequestBase
var continuation: CheckedContinuation<HTTPRequestBase, Error>
let continuation: CheckedContinuation<HTTPRequestBase, Error>
let shouldSignHeader: ((String) -> Bool)?
init(request: HTTPRequestBase,
continuation: CheckedContinuation<HTTPRequestBase, Error>,
Expand Down Expand Up @@ -207,6 +209,7 @@ private func onRequestSigningComplete(signingResult: UnsafeMutablePointer<aws_si
} else {
signRequestCore.continuation.resume(throwing: CommonRunTimeError.crtError(.makeFromLastError()))
}
// It's not thread-safe to modify `signingRequestCore.request` after continuation.resume
}

private func onSigningComplete(signingResult: UnsafeMutablePointer<aws_signing_result>?,
Expand All @@ -220,9 +223,10 @@ private func onSigningComplete(signingResult: UnsafeMutablePointer<aws_signing_r

// Success
var awsStringPointer: UnsafeMutablePointer<aws_string>!
let signature = AWSString("signature")
guard aws_signing_result_get_property(
signingResult!,
g_aws_signature_property_name,
signature.rawValue,
&awsStringPointer) == AWS_OP_SUCCESS else {
chunkSignerCore.continuation.resume(throwing: CommonRunTimeError.crtError(.makeFromLastError()))
return
Expand Down
10 changes: 5 additions & 5 deletions Source/AwsCommonRuntimeKit/auth/signing/SigningConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import AwsCAuth
import Foundation

public struct SigningConfig: CStructWithUserData {
public struct SigningConfig: CStructWithUserData, @unchecked Sendable {

/// What signing algorithm to use.
public var algorithm: SigningAlgorithmType
Expand Down Expand Up @@ -136,7 +136,7 @@ private func onShouldSignHeader(nameCursor: UnsafePointer<aws_byte_cursor>!,
return signRequestCore.shouldSignHeader!(name)
}

public enum SignatureType {
public enum SignatureType: Sendable {

/// A signature for a full http request should be computed, with header updates applied to the signing result.
case requestHeaders
Expand All @@ -162,7 +162,7 @@ public enum SignatureType {
case requestEvent
}

public enum SignedBodyHeaderType {
public enum SignedBodyHeaderType: Sendable {

/// Do not add a header
case none
Expand All @@ -174,7 +174,7 @@ public enum SignedBodyHeaderType {
/// Optional string to use as the canonical request's body value.
/// Typically, this is the SHA-256 of the (request/chunk/event) payload, written as lowercase hex.
/// If this has been precalculated, it can be set here. Special values used by certain services can also be set.
public enum SignedBodyValue: CustomStringConvertible, Equatable {
public enum SignedBodyValue: CustomStringConvertible, Equatable, Sendable {
/// if empty, a public value will be calculated from the payload during signing
case empty
/// For empty sha256
Expand Down Expand Up @@ -226,7 +226,7 @@ public enum SignedBodyValue: CustomStringConvertible, Equatable {
}
}

public enum SigningAlgorithmType {
public enum SigningAlgorithmType: Sendable {
case signingV4
case signingV4Asymmetric
case signingV4S3Express
Expand Down
12 changes: 9 additions & 3 deletions Source/AwsCommonRuntimeKit/crt/Allocator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@
// SPDX-License-Identifier: Apache-2.0.
import AwsCCommon

/**
The default allocator.
You are probably looking to use `allocator` instead.
/*
* The default allocator.
* We need to declare `allocator` as mutable (`var`) instead of `let` because we override it with a tracing allocator in tests. This is not mutated anywhere else apart from the start of tests.
* Swift compiler doesn't let us compile this code in Swift 6 due to global shared mutable state without locks, and complains that this is not safe. Disable the safety here since we won't modify it.
* Remove the Ifdef once our minimum supported Swift version reaches 5.10
*/
#if swift(>=5.10)
nonisolated(unsafe) var allocator = aws_default_allocator()!
#else
var allocator = aws_default_allocator()!
#endif

/// An allocator is used to allocate memory on the heap.
protocol Allocator {
Expand Down
2 changes: 1 addition & 1 deletion Source/AwsCommonRuntimeKit/crt/CommonRuntimeError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public enum CommonRunTimeError: Error {
case crtError(CRTError)
}

public struct CRTError: Equatable {
public struct CRTError: Equatable, Sendable {
public let code: Int32
public let message: String
public let name: String
Expand Down
4 changes: 2 additions & 2 deletions Source/AwsCommonRuntimeKit/crt/Logger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public enum LogTarget {
case filePath(String)
}

public struct Logger {
public actor Logger {
private static var logger: aws_logger?
private static let lock = NSLock()

Expand Down Expand Up @@ -55,7 +55,7 @@ public struct Logger {
}
}

public enum LogLevel {
public enum LogLevel: Sendable {
case none
case fatal
case error
Expand Down
10 changes: 10 additions & 0 deletions Source/AwsCommonRuntimeKit/crt/Utilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ class Box<T> {
}
}

// We need to share this pointer to C in a task block but Swift compiler complains
// that Pointer does not conform to Sendable. Wrap the pointer in a @unchecked Sendable block
// for Swift compiler to stop complaining.
struct SendableRawPointer: @unchecked Sendable {
let pointer: UnsafeMutableRawPointer?
}

extension String {

func withByteCursor<Result>(_ body: (aws_byte_cursor) -> Result
Expand Down Expand Up @@ -194,6 +201,9 @@ extension aws_byte_cursor {
}

let data = Data(bytesNoCopy: self.ptr, count: self.len, deallocator: .none)
// Using non-failable String(decoding:as:) to handle invalid UTF-8 with replacement characters.
// Disable warning as it's a false positive.
// swiftlint:disable:next optional_data_string_conversion
return String(decoding: data, as: UTF8.self)
}

Expand Down
4 changes: 3 additions & 1 deletion Source/AwsCommonRuntimeKit/http/HTTP1Stream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import AwsCHttp
import Foundation

// Swift cannot verify the sendability due to a pointer, and thread safety is handled in the C layer.
// So mark it as unchecked Sendable.
/// An HTTP1Stream represents a single HTTP/1.1 specific Http Request/Response.
public class HTTP1Stream: HTTPStream {
public class HTTP1Stream: HTTPStream, @unchecked Sendable {
/// Stream keeps a reference to HttpConnection to keep it alive
private let httpConnection: HTTPClientConnection

Expand Down
4 changes: 3 additions & 1 deletion Source/AwsCommonRuntimeKit/http/HTTP2ClientConnection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import AwsCHttp
import AwsCIo
import Foundation

public class HTTP2ClientConnection: HTTPClientConnection {
// Swift cannot verify the sendability due to a pointer, and thread safety is handled in the C layer.
// So mark it as unchecked Sendable.
public class HTTP2ClientConnection: HTTPClientConnection, @unchecked Sendable {

/// Creates a new http2 stream from the `HTTPRequestOptions` given.
/// - Parameter requestOptions: An `HTTPRequestOptions` struct containing callbacks on
Expand Down
4 changes: 3 additions & 1 deletion Source/AwsCommonRuntimeKit/http/HTTP2Stream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import AwsCHttp
import Foundation

// Swift cannot verify the sendability due to a pointer, and thread safety is handled in the C layer.
// So mark it as unchecked Sendable.
/// An HTTP2Stream represents a single HTTP/2 specific HTTP Request/Response.
public class HTTP2Stream: HTTPStream {
public class HTTP2Stream: HTTPStream, @unchecked Sendable {
private let httpConnection: HTTPClientConnection?

// Called by Connection Manager
Expand Down
4 changes: 3 additions & 1 deletion Source/AwsCommonRuntimeKit/http/HTTP2StreamManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
// SPDX-License-Identifier: Apache-2.0.
import AwsCHttp

// Swift cannot verify the sendability due to a pointer, and thread safety is handled in the C layer.
// So mark it as unchecked Sendable.
/// Manages a Pool of HTTP/2 Streams. Creates and manages HTTP/2 connections under the hood.
public class HTTP2StreamManager {
public class HTTP2StreamManager: @unchecked Sendable {
let rawValue: UnsafeMutablePointer<aws_http2_stream_manager>

public init(options: HTTP2StreamManagerOptions) throws {
Expand Down
Loading
Loading