Centralize UnsafeTransfer in NIOCore (#3492)

We have a number of copies of `UnsafeTransfer` and two copies of
`UnsafeMutableTransferBox` in our code base. Before introducing more of
those, lets centralize to just one using a `package` access modifier.
This commit is contained in:
Fabian Fett
2026-02-03 11:27:30 +01:00
committed by GitHub
parent c90e69406b
commit 6a6f7d7c33
14 changed files with 95 additions and 222 deletions
@@ -22,7 +22,7 @@ function make_package() {
fi
cat > "$tmpdir/syscallwrapper/Package.swift" <<"EOF"
// swift-tools-version:5.7
// swift-tools-version:6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
@@ -1,16 +1,17 @@
{
"1_reqs_1000_conn": 375050,
"1000_addHandlers_sync": 39050,
"10000000_asyncsequenceproducer": 19,
"1000000_asyncwriter": 1000050,
"1000_addHandlers": 46050,
"1000_addHandlers_sync": 39050,
"1000_addRemoveHandlers_handlercontext": 8050,
"1000_addRemoveHandlers_handlername": 8050,
"1000_addRemoveHandlers_handlertype": 8050,
"1000_autoReadGetAndSet_sync": 0,
"1000_autoReadGetAndSet": 18050,
"1000_autoReadGetAndSet_sync": 0,
"1000_copying_bytebufferview_to_array": 1050,
"1000_copying_circularbuffer_to_array": 1050,
"1000_getHandlers_sync": 37,
"1000_getHandlers": 8050,
"1000_getHandlers_sync": 37,
"1000_reqs_1_conn": 26350,
"1000_rst_connections": 138050,
"1000_tcpbootstraps": 3050,
@@ -18,30 +19,29 @@
"1000_udp_reqs": 6050,
"1000_udpbootstraps": 2050,
"1000_udpconnections": 75050,
"1000000_asyncwriter": 1000050,
"10000000_asyncsequenceproducer": 19,
"1_reqs_1000_conn": 375050,
"assume_isolated_scheduling_10000_executions": 89,
"bytebuffer_lots_of_rw": 2050,
"creating_10000_headers": 0,
"decode_1000_ws_frames": 2050,
"encode_1000_ws_frames_holding_buffer_with_mask": 2050,
"encode_1000_ws_frames_holding_buffer_with_space_with_mask": 2050,
"encode_1000_ws_frames_holding_buffer_with_space": 3,
"encode_1000_ws_frames_holding_buffer": 3,
"encode_1000_ws_frames_new_buffer_with_mask": 5050,
"encode_1000_ws_frames_new_buffer_with_space_with_mask": 5050,
"encode_1000_ws_frames_new_buffer_with_space": 3050,
"encode_1000_ws_frames_holding_buffer_with_mask": 2050,
"encode_1000_ws_frames_holding_buffer_with_space": 3,
"encode_1000_ws_frames_holding_buffer_with_space_with_mask": 2050,
"encode_1000_ws_frames_new_buffer": 3050,
"encode_1000_ws_frames_new_buffer_with_mask": 5050,
"encode_1000_ws_frames_new_buffer_with_space": 3050,
"encode_1000_ws_frames_new_buffer_with_space_with_mask": 5050,
"execute_hop_10000_tasks": 0,
"flat_schedule_10000_tasks": 100100,
"flat_schedule_assume_isolated_10000_tasks": 90100,
"future_assume_isolated_lots_of_callbacks": 68050,
"future_erase_result": 4050,
"future_lots_of_callbacks": 68050,
"get_100000_headers_canonical_form": 700050,
"get_100000_headers_canonical_form_trimming_whitespace": 700050,
"get_100000_headers_canonical_form_trimming_whitespace_from_long_string": 700050,
"get_100000_headers_canonical_form_trimming_whitespace_from_short_string": 700050,
"get_100000_headers_canonical_form_trimming_whitespace": 700050,
"get_100000_headers_canonical_form": 700050,
"modifying_1000_circular_buffer_elements": 0,
"modifying_byte_buffer_view": 6050,
"ping_pong_1000_reqs_1_conn": 305,
@@ -54,6 +54,6 @@
"scheduling_10000_executions": 89,
"submit_10000_tasks": 20100,
"submit_assume_isolated_10000_tasks": 20100,
"udp_1_reqs_1000_conn": 162050,
"udp_1000_reqs_1_conn": 6200
"udp_1000_reqs_1_conn": 6200,
"udp_1_reqs_1000_conn": 162050
}
@@ -1,16 +1,17 @@
{
"1_reqs_1000_conn": 375050,
"1000_addHandlers_sync": 39050,
"10000000_asyncsequenceproducer": 19,
"1000000_asyncwriter": 1000050,
"1000_addHandlers": 46050,
"1000_addHandlers_sync": 39050,
"1000_addRemoveHandlers_handlercontext": 8050,
"1000_addRemoveHandlers_handlername": 8050,
"1000_addRemoveHandlers_handlertype": 8050,
"1000_autoReadGetAndSet_sync": 0,
"1000_autoReadGetAndSet": 18050,
"1000_autoReadGetAndSet_sync": 0,
"1000_copying_bytebufferview_to_array": 1050,
"1000_copying_circularbuffer_to_array": 1050,
"1000_getHandlers_sync": 37,
"1000_getHandlers": 8050,
"1000_getHandlers_sync": 37,
"1000_reqs_1_conn": 26350,
"1000_rst_connections": 138050,
"1000_tcpbootstraps": 3050,
@@ -18,30 +19,29 @@
"1000_udp_reqs": 6050,
"1000_udpbootstraps": 2050,
"1000_udpconnections": 75050,
"1000000_asyncwriter": 1000050,
"10000000_asyncsequenceproducer": 19,
"1_reqs_1000_conn": 375050,
"assume_isolated_scheduling_10000_executions": 89,
"bytebuffer_lots_of_rw": 2050,
"creating_10000_headers": 0,
"decode_1000_ws_frames": 2050,
"encode_1000_ws_frames_holding_buffer_with_mask": 2050,
"encode_1000_ws_frames_holding_buffer_with_space_with_mask": 2050,
"encode_1000_ws_frames_holding_buffer_with_space": 3,
"encode_1000_ws_frames_holding_buffer": 3,
"encode_1000_ws_frames_new_buffer_with_mask": 5050,
"encode_1000_ws_frames_new_buffer_with_space_with_mask": 5050,
"encode_1000_ws_frames_new_buffer_with_space": 3050,
"encode_1000_ws_frames_holding_buffer_with_mask": 2050,
"encode_1000_ws_frames_holding_buffer_with_space": 3,
"encode_1000_ws_frames_holding_buffer_with_space_with_mask": 2050,
"encode_1000_ws_frames_new_buffer": 3050,
"encode_1000_ws_frames_new_buffer_with_mask": 5050,
"encode_1000_ws_frames_new_buffer_with_space": 3050,
"encode_1000_ws_frames_new_buffer_with_space_with_mask": 5050,
"execute_hop_10000_tasks": 0,
"flat_schedule_10000_tasks": 100100,
"flat_schedule_assume_isolated_10000_tasks": 90100,
"future_assume_isolated_lots_of_callbacks": 68050,
"future_erase_result": 4050,
"future_lots_of_callbacks": 68050,
"get_100000_headers_canonical_form": 700050,
"get_100000_headers_canonical_form_trimming_whitespace": 700050,
"get_100000_headers_canonical_form_trimming_whitespace_from_long_string": 700050,
"get_100000_headers_canonical_form_trimming_whitespace_from_short_string": 700050,
"get_100000_headers_canonical_form_trimming_whitespace": 700050,
"get_100000_headers_canonical_form": 700050,
"modifying_1000_circular_buffer_elements": 0,
"modifying_byte_buffer_view": 6050,
"ping_pong_1000_reqs_1_conn": 305,
@@ -54,6 +54,6 @@
"scheduling_10000_executions": 89,
"submit_10000_tasks": 20100,
"submit_assume_isolated_10000_tasks": 20100,
"udp_1_reqs_1000_conn": 162050,
"udp_1000_reqs_1_conn": 6200
"udp_1000_reqs_1_conn": 6200,
"udp_1_reqs_1000_conn": 162050
}
@@ -1,16 +1,17 @@
{
"1_reqs_1000_conn": 375050,
"1000_addHandlers_sync": 39050,
"10000000_asyncsequenceproducer": 20,
"1000000_asyncwriter": 1000050,
"1000_addHandlers": 46050,
"1000_addHandlers_sync": 39050,
"1000_addRemoveHandlers_handlercontext": 8050,
"1000_addRemoveHandlers_handlername": 8050,
"1000_addRemoveHandlers_handlertype": 8050,
"1000_autoReadGetAndSet_sync": 0,
"1000_autoReadGetAndSet": 18050,
"1000_autoReadGetAndSet_sync": 0,
"1000_copying_bytebufferview_to_array": 1050,
"1000_copying_circularbuffer_to_array": 1050,
"1000_getHandlers_sync": 37,
"1000_getHandlers": 8050,
"1000_getHandlers_sync": 37,
"1000_reqs_1_conn": 26350,
"1000_rst_connections": 138050,
"1000_tcpbootstraps": 3050,
@@ -18,30 +19,29 @@
"1000_udp_reqs": 6050,
"1000_udpbootstraps": 2050,
"1000_udpconnections": 75050,
"1000000_asyncwriter": 1000050,
"10000000_asyncsequenceproducer": 20,
"1_reqs_1000_conn": 375050,
"assume_isolated_scheduling_10000_executions": 89,
"bytebuffer_lots_of_rw": 2050,
"creating_10000_headers": 0,
"decode_1000_ws_frames": 2050,
"encode_1000_ws_frames_holding_buffer_with_mask": 2050,
"encode_1000_ws_frames_holding_buffer_with_space_with_mask": 2050,
"encode_1000_ws_frames_holding_buffer_with_space": 3,
"encode_1000_ws_frames_holding_buffer": 3,
"encode_1000_ws_frames_new_buffer_with_mask": 5050,
"encode_1000_ws_frames_new_buffer_with_space_with_mask": 5050,
"encode_1000_ws_frames_new_buffer_with_space": 3050,
"encode_1000_ws_frames_holding_buffer_with_mask": 2050,
"encode_1000_ws_frames_holding_buffer_with_space": 3,
"encode_1000_ws_frames_holding_buffer_with_space_with_mask": 2050,
"encode_1000_ws_frames_new_buffer": 3050,
"encode_1000_ws_frames_new_buffer_with_mask": 5050,
"encode_1000_ws_frames_new_buffer_with_space": 3050,
"encode_1000_ws_frames_new_buffer_with_space_with_mask": 5050,
"execute_hop_10000_tasks": 0,
"flat_schedule_10000_tasks": 100100,
"flat_schedule_assume_isolated_10000_tasks": 80100,
"future_assume_isolated_lots_of_callbacks": 68050,
"future_erase_result": 4050,
"future_lots_of_callbacks": 68050,
"get_100000_headers_canonical_form": 500050,
"get_100000_headers_canonical_form_trimming_whitespace": 500050,
"get_100000_headers_canonical_form_trimming_whitespace_from_long_string": 500050,
"get_100000_headers_canonical_form_trimming_whitespace_from_short_string": 500050,
"get_100000_headers_canonical_form_trimming_whitespace": 500050,
"get_100000_headers_canonical_form": 500050,
"modifying_1000_circular_buffer_elements": 0,
"modifying_byte_buffer_view": 6050,
"ping_pong_1000_reqs_1_conn": 305,
@@ -54,6 +54,6 @@
"scheduling_10000_executions": 89,
"submit_10000_tasks": 20100,
"submit_assume_isolated_10000_tasks": 20100,
"udp_1_reqs_1000_conn": 162050,
"udp_1000_reqs_1_conn": 6200
"udp_1000_reqs_1_conn": 6200,
"udp_1_reqs_1000_conn": 162050
}
@@ -1,16 +1,17 @@
{
"1_reqs_1000_conn": 372050,
"1000_addHandlers_sync": 39050,
"10000000_asyncsequenceproducer": 23,
"1000000_asyncwriter": 1000050,
"1000_addHandlers": 46050,
"1000_addHandlers_sync": 39050,
"1000_addRemoveHandlers_handlercontext": 8050,
"1000_addRemoveHandlers_handlername": 8050,
"1000_addRemoveHandlers_handlertype": 8050,
"1000_autoReadGetAndSet_sync": 0,
"1000_autoReadGetAndSet": 18050,
"1000_autoReadGetAndSet_sync": 0,
"1000_copying_bytebufferview_to_array": 1050,
"1000_copying_circularbuffer_to_array": 1050,
"1000_getHandlers_sync": 37,
"1000_getHandlers": 8050,
"1000_getHandlers_sync": 37,
"1000_reqs_1_conn": 26350,
"1000_rst_connections": 136050,
"1000_tcpbootstraps": 3050,
@@ -18,32 +19,31 @@
"1000_udp_reqs": 6050,
"1000_udpbootstraps": 2050,
"1000_udpconnections": 74050,
"1000000_asyncwriter": 1000050,
"10000000_asyncsequenceproducer": 23,
"1_reqs_1000_conn": 372050,
"assume_isolated_scheduling_10000_executions": 89,
"bytebuffer_lots_of_rw": 2050,
"creating_10000_headers": 0,
"decode_1000_ws_frames": 2050,
"encode_1000_ws_frames_holding_buffer_with_mask": 2050,
"encode_1000_ws_frames_holding_buffer_with_space_with_mask": 2050,
"encode_1000_ws_frames_holding_buffer_with_space": 3,
"encode_1000_ws_frames_holding_buffer": 3,
"encode_1000_ws_frames_new_buffer_with_mask": 5050,
"encode_1000_ws_frames_new_buffer_with_space_with_mask": 5050,
"encode_1000_ws_frames_new_buffer_with_space": 3050,
"encode_1000_ws_frames_holding_buffer_with_mask": 2050,
"encode_1000_ws_frames_holding_buffer_with_space": 3,
"encode_1000_ws_frames_holding_buffer_with_space_with_mask": 2050,
"encode_1000_ws_frames_new_buffer": 3050,
"encode_1000_ws_frames_new_buffer_with_mask": 5050,
"encode_1000_ws_frames_new_buffer_with_space": 3050,
"encode_1000_ws_frames_new_buffer_with_space_with_mask": 5050,
"execute_hop_10000_tasks": 0,
"flat_schedule_10000_tasks": 100100,
"flat_schedule_assume_isolated_10000_tasks": 80100,
"future_assume_isolated_lots_of_callbacks": 68050,
"future_erase_result": 4050,
"future_lots_of_callbacks": 68050,
"get_100000_headers_canonical_form": 500050,
"get_100000_headers_canonical_form_trimming_whitespace": 500050,
"get_100000_headers_canonical_form_trimming_whitespace_from_long_string": 500050,
"get_100000_headers_canonical_form_trimming_whitespace_from_short_string": 500050,
"get_100000_headers_canonical_form_trimming_whitespace": 500050,
"get_100000_headers_canonical_form": 500050,
"modifying_1000_circular_buffer_elements": 0,
"modifying_byte_buffer_view": 4050,
"modifying_byte_buffer_view": 6050,
"ping_pong_1000_reqs_1_conn": 302,
"read_10000_chunks_from_file": 110050,
"schedule_10000_tasks": 40100,
@@ -54,6 +54,6 @@
"scheduling_10000_executions": 89,
"submit_10000_tasks": 20100,
"submit_assume_isolated_10000_tasks": 20100,
"udp_1_reqs_1000_conn": 160050,
"udp_1000_reqs_1_conn": 6200
"udp_1000_reqs_1_conn": 6200,
"udp_1_reqs_1000_conn": 160050
}
@@ -1,16 +1,17 @@
{
"1_reqs_1000_conn": 375050,
"1000_addHandlers_sync": 39050,
"10000000_asyncsequenceproducer": 23,
"1000000_asyncwriter": 1000050,
"1000_addHandlers": 46050,
"1000_addHandlers_sync": 39050,
"1000_addRemoveHandlers_handlercontext": 8050,
"1000_addRemoveHandlers_handlername": 8050,
"1000_addRemoveHandlers_handlertype": 8050,
"1000_autoReadGetAndSet_sync": 0,
"1000_autoReadGetAndSet": 18050,
"1000_autoReadGetAndSet_sync": 0,
"1000_copying_bytebufferview_to_array": 1050,
"1000_copying_circularbuffer_to_array": 1050,
"1000_getHandlers_sync": 37,
"1000_getHandlers": 8050,
"1000_getHandlers_sync": 37,
"1000_reqs_1_conn": 26350,
"1000_rst_connections": 138050,
"1000_tcpbootstraps": 3050,
@@ -18,30 +19,29 @@
"1000_udp_reqs": 6050,
"1000_udpbootstraps": 2050,
"1000_udpconnections": 75050,
"1000000_asyncwriter": 1000050,
"10000000_asyncsequenceproducer": 20,
"1_reqs_1000_conn": 375050,
"assume_isolated_scheduling_10000_executions": 89,
"bytebuffer_lots_of_rw": 2050,
"creating_10000_headers": 0,
"decode_1000_ws_frames": 2050,
"encode_1000_ws_frames_holding_buffer_with_mask": 2050,
"encode_1000_ws_frames_holding_buffer_with_space_with_mask": 2050,
"encode_1000_ws_frames_holding_buffer_with_space": 3,
"encode_1000_ws_frames_holding_buffer": 3,
"encode_1000_ws_frames_new_buffer_with_mask": 5050,
"encode_1000_ws_frames_new_buffer_with_space_with_mask": 5050,
"encode_1000_ws_frames_new_buffer_with_space": 3050,
"encode_1000_ws_frames_holding_buffer_with_mask": 2050,
"encode_1000_ws_frames_holding_buffer_with_space": 3,
"encode_1000_ws_frames_holding_buffer_with_space_with_mask": 2050,
"encode_1000_ws_frames_new_buffer": 3050,
"encode_1000_ws_frames_new_buffer_with_mask": 5050,
"encode_1000_ws_frames_new_buffer_with_space": 3050,
"encode_1000_ws_frames_new_buffer_with_space_with_mask": 5050,
"execute_hop_10000_tasks": 0,
"flat_schedule_10000_tasks": 100100,
"flat_schedule_assume_isolated_10000_tasks": 80100,
"future_assume_isolated_lots_of_callbacks": 68050,
"future_erase_result": 4050,
"future_lots_of_callbacks": 68050,
"get_100000_headers_canonical_form": 500050,
"get_100000_headers_canonical_form_trimming_whitespace": 500050,
"get_100000_headers_canonical_form_trimming_whitespace_from_long_string": 500050,
"get_100000_headers_canonical_form_trimming_whitespace_from_short_string": 500050,
"get_100000_headers_canonical_form_trimming_whitespace": 500050,
"get_100000_headers_canonical_form": 500050,
"modifying_1000_circular_buffer_elements": 0,
"modifying_byte_buffer_view": 6050,
"ping_pong_1000_reqs_1_conn": 305,
@@ -54,6 +54,6 @@
"scheduling_10000_executions": 89,
"submit_10000_tasks": 20100,
"submit_assume_isolated_10000_tasks": 20100,
"udp_1_reqs_1000_conn": 162050,
"udp_1000_reqs_1_conn": 6200
"udp_1000_reqs_1_conn": 6200,
"udp_1_reqs_1000_conn": 162050
}
+6 -6
View File
@@ -24,12 +24,12 @@ public typealias NIOPreconcurrencySendable = _NIOPreconcurrencySendable
/// As the name implies, the usage of this is unsafe because it disables the sendable checking of the compiler.
/// It can be used similar to `@unsafe Sendable` but for values instead of types.
@usableFromInline
struct UnsafeTransfer<Wrapped> {
package struct UnsafeTransfer<Wrapped> {
@usableFromInline
var wrappedValue: Wrapped
package var wrappedValue: Wrapped
@inlinable
init(_ wrappedValue: Wrapped) {
package init(_ wrappedValue: Wrapped) {
self.wrappedValue = wrappedValue
}
}
@@ -43,12 +43,12 @@ extension UnsafeTransfer: Hashable where Wrapped: Hashable {}
/// It can be used to capture local mutable values in a `@Sendable` closure and mutate them from within the closure.
/// As the name implies, the usage of this is unsafe because it disables the sendable checking of the compiler and does not add any synchronisation.
@usableFromInline
final class UnsafeMutableTransferBox<Wrapped> {
package final class UnsafeMutableTransferBox<Wrapped> {
@usableFromInline
var wrappedValue: Wrapped
package var wrappedValue: Wrapped
@inlinable
init(_ wrappedValue: Wrapped) {
package init(_ wrappedValue: Wrapped) {
self.wrappedValue = wrappedValue
}
}
@@ -12,6 +12,8 @@
//
//===----------------------------------------------------------------------===//
import NIOCore
/// Executes the closure and masks cancellation.
@_spi(Testing)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
@@ -1,24 +0,0 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2023 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
@usableFromInline
struct UnsafeTransfer<Value>: @unchecked Sendable {
@usableFromInline
var wrappedValue: Value
@inlinable
init(_ wrappedValue: Value) {
self.wrappedValue = wrappedValue
}
}
-35
View File
@@ -1,35 +0,0 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2021-2022 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
#if !os(WASI)
/// ``UnsafeTransfer`` can be used to make non-`Sendable` values `Sendable`.
/// As the name implies, the usage of this is unsafe because it disables the sendable checking of the compiler.
/// It can be used similar to `@unsafe Sendable` but for values instead of types.
@usableFromInline
struct UnsafeTransfer<Wrapped> {
@usableFromInline
var wrappedValue: Wrapped
@inlinable
init(_ wrappedValue: Wrapped) {
self.wrappedValue = wrappedValue
}
}
extension UnsafeTransfer: @unchecked Sendable {}
extension UnsafeTransfer: Equatable where Wrapped: Equatable {}
extension UnsafeTransfer: Hashable where Wrapped: Hashable {}
#endif // !os(WASI)
@@ -12,6 +12,8 @@
//
//===----------------------------------------------------------------------===//
import NIOCore
/// Executes the closure and masks cancellation.
@_spi(Testing)
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
@@ -1,24 +0,0 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2023 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
@usableFromInline
struct UnsafeTransfer<Value>: @unchecked Sendable {
@usableFromInline
var wrappedValue: Value
@inlinable
init(_ wrappedValue: Value) {
self.wrappedValue = wrappedValue
}
}
-48
View File
@@ -1,48 +0,0 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2021-2022 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
/// ``UnsafeTransfer`` can be used to make non-`Sendable` values `Sendable`.
/// As the name implies, the usage of this is unsafe because it disables the sendable checking of the compiler.
/// It can be used similar to `@unsafe Sendable` but for values instead of types.
@usableFromInline
struct UnsafeTransfer<Wrapped> {
@usableFromInline
var wrappedValue: Wrapped
@inlinable
init(_ wrappedValue: Wrapped) {
self.wrappedValue = wrappedValue
}
}
extension UnsafeTransfer: @unchecked Sendable {}
extension UnsafeTransfer: Equatable where Wrapped: Equatable {}
extension UnsafeTransfer: Hashable where Wrapped: Hashable {}
/// ``UnsafeMutableTransferBox`` can be used to make non-`Sendable` values `Sendable` and mutable.
/// It can be used to capture local mutable values in a `@Sendable` closure and mutate them from within the closure.
/// As the name implies, the usage of this is unsafe because it disables the sendable checking of the compiler and does not add any synchronisation.
@usableFromInline
final class UnsafeMutableTransferBox<Wrapped> {
@usableFromInline
var wrappedValue: Wrapped
@inlinable
init(_ wrappedValue: Wrapped) {
self.wrappedValue = wrappedValue
}
}
extension UnsafeMutableTransferBox: @unchecked Sendable {}
+3 -3
View File
@@ -206,8 +206,8 @@ update_threshold_file() {
# Compare old and new files (both sorted with jq) and only overwrite if there are substantive differences
if [ -f "$threshold_file" ]; then
old_normalized=$("$JQ_BIN" -S . "$threshold_file" 2>/dev/null || echo "")
new_normalized=$(echo "$new_thresholds" | "$JQ_BIN" -S . 2>/dev/null || echo "")
old_normalized=$("$JQ_BIN" -S --indent 4 . "$threshold_file" 2>/dev/null || echo "")
new_normalized=$(echo "$new_thresholds" | "$JQ_BIN" -S --indent 4 . 2>/dev/null || echo "")
if [ "$old_normalized" = "$new_normalized" ]; then
log "No changes for $threshold_file_relative (skipping)"
@@ -215,7 +215,7 @@ update_threshold_file() {
fi
fi
echo "$new_thresholds" > "$threshold_file"
echo "$new_thresholds" | "$JQ_BIN" -S --indent 4 . > "$threshold_file"
log "Updated $threshold_file_relative"
updated_count=$((updated_count + 1))
}