Skip to content

Commit 2446ab4

Browse files
committed
Require ThreadSafeBox.T to be Sendable
Otherwise, I think `ThreadSafeBox` might still have data races. This also requires us to make `TestSourceKitLSPClient.RequestHandler` sendable. rdar://128572489
1 parent 98718d4 commit 2446ab4

File tree

4 files changed

+16
-6
lines changed

4 files changed

+16
-6
lines changed

Sources/SKSupport/AsyncUtils.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public extension Task where Failure == Never {
9898
///
9999
/// If the task executing `withCancellableCheckedThrowingContinuation` gets
100100
/// cancelled, `cancel` is invoked with the handle that `operation` provided.
101-
public func withCancellableCheckedThrowingContinuation<Handle, Result>(
101+
public func withCancellableCheckedThrowingContinuation<Handle: Sendable, Result>(
102102
_ operation: (_ continuation: CheckedContinuation<Result, any Error>) -> Handle,
103103
cancel: @Sendable (Handle) -> Void
104104
) async throws -> Result {

Sources/SKSupport/ThreadSafeBox.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ extension NSLock {
2424
/// A thread safe container that contains a value of type `T`.
2525
///
2626
/// - Note: Unchecked sendable conformance because value is guarded by a lock.
27-
public class ThreadSafeBox<T>: @unchecked Sendable {
27+
public class ThreadSafeBox<T: Sendable>: @unchecked Sendable {
2828
/// Lock guarding `_value`.
2929
private let lock = NSLock()
3030

Sources/SKTestSupport/TestSourceKitLSPClient.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ extension SourceKitLSPServer.Options {
3434
/// that the server sends to the client.
3535
public final class TestSourceKitLSPClient: MessageHandler {
3636
/// A function that takes a request and returns the request's response.
37-
public typealias RequestHandler<Request: RequestType> = (Request) -> Request.Response
37+
public typealias RequestHandler<Request: RequestType> = @Sendable (Request) -> Request.Response
3838

3939
/// The ID that should be assigned to the next request sent to the `server`.
4040
/// `nonisolated(unsafe)` is fine because `nextRequestID` is atomic.
@@ -72,7 +72,7 @@ public final class TestSourceKitLSPClient: MessageHandler {
7272
///
7373
/// `isOneShort` if the request handler should only serve a single request and should be removed from
7474
/// `requestHandlers` after it has been called.
75-
private nonisolated(unsafe) var requestHandlers: ThreadSafeBox<[(requestHandler: Any, isOneShot: Bool)]> =
75+
private nonisolated(unsafe) var requestHandlers: ThreadSafeBox<[(requestHandler: Sendable, isOneShot: Bool)]> =
7676
ThreadSafeBox(initialValue: [])
7777

7878
/// A closure that is called when the `TestSourceKitLSPClient` is destructed.
@@ -287,12 +287,16 @@ public final class TestSourceKitLSPClient: MessageHandler {
287287
/// The request handler will only handle a single request. If the request is called again, the request handler won't
288288
/// call again
289289
public func handleSingleRequest<R: RequestType>(_ requestHandler: @escaping RequestHandler<R>) {
290-
requestHandlers.value.append((requestHandler: requestHandler, isOneShot: true))
290+
requestHandlers.withLock { requestHandlers in
291+
requestHandlers.append((requestHandler: requestHandler, isOneShot: true))
292+
}
291293
}
292294

293295
/// Handle all requests of the given type that are sent to the client.
294296
public func handleMultipleRequests<R: RequestType>(_ requestHandler: @escaping RequestHandler<R>) {
295-
requestHandlers.value.append((requestHandler: requestHandler, isOneShot: false))
297+
requestHandlers.withLock { requestHandlers in
298+
requestHandlers.append((requestHandler: requestHandler, isOneShot: false))
299+
}
296300
}
297301

298302
// MARK: - Conformance to MessageHandler

Sources/SourceKitD/SourceKitD.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ import Dispatch
1515
import Foundation
1616
import SKSupport
1717

18+
#if compiler(>=6)
19+
extension sourcekitd_api_request_handle_t: @retroactive @unchecked Sendable {}
20+
#else
21+
extension sourcekitd_api_request_handle_t: @unchecked Sendable {}
22+
#endif
23+
1824
/// Access to sourcekitd API, taking care of initialization, shutdown, and notification handler
1925
/// multiplexing.
2026
///

0 commit comments

Comments
 (0)