Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 2 additions & 9 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,6 @@ var targets: [Target] = [
swiftSettings: globalSwiftSettings
),

// MARK: ToolsProtocolsCAtomics

.target(
name: "ToolsProtocolsCAtomics",
dependencies: []
),

// MARK: LanguageServerProtocol

.target(
Expand Down Expand Up @@ -153,15 +146,15 @@ var targets: [Target] = [

.target(
name: "ToolsProtocolsSwiftExtensions",
dependencies: ["ToolsProtocolsCAtomics"],
dependencies: [],
exclude: ["CMakeLists.txt"],
swiftSettings: globalSwiftSettings
),

// SourceKit-LSP SPI target. Builds ToolsProtocolsSwiftExtensions with an alternate module name to avoid runtime type collisions.
.target(
name: "_ToolsProtocolsSwiftExtensionsForPlugin",
dependencies: ["ToolsProtocolsCAtomics"],
dependencies: [],
exclude: ["CMakeLists.txt"],
swiftSettings: globalSwiftSettings
),
Expand Down
1 change: 0 additions & 1 deletion Sources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ add_compile_options("$<$<COMPILE_LANGUAGE:Swift>:SHELL:-package-name swift_langu
add_compile_options("$<$<COMPILE_LANGUAGE:Swift>:SHELL:-DRESILIENT_LIBRARIES>")
add_compile_options("$<$<COMPILE_LANGUAGE:Swift>:SHELL:-swift-version 6>")
add_subdirectory(BuildServerProtocol)
add_subdirectory(ToolsProtocolsCAtomics)
add_subdirectory(LanguageServerProtocol)
add_subdirectory(LanguageServerProtocolTransport)
add_subdirectory(SKLogging)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
public import Foundation
public import LanguageServerProtocol
@_spi(SourceKitLSP) import SKLogging
import Synchronization
@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions

#if canImport(Android)
Expand Down Expand Up @@ -85,7 +86,7 @@ public final class JSONRPCConnection: Connection {
private nonisolated(unsafe) var state: State = .created

/// An integer that hasn't been used for a request ID yet.
let nextRequestIDStorage = AtomicUInt32(initialValue: 0)
let nextRequestIDStorage = Atomic<UInt32>(0)

struct OutstandingRequest: Sendable {
var responseType: ResponseType.Type
Expand Down Expand Up @@ -597,7 +598,7 @@ public final class JSONRPCConnection: Connection {

/// Request id for the next outgoing request.
public func nextRequestID() -> RequestID {
return .string("sk-\(nextRequestIDStorage.fetchAndIncrement())")
return .string("sk-\(nextRequestIDStorage.wrappingAdd(1, ordering: .relaxed).oldValue)")
}

// MARK: Connection interface
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Dispatch
import Foundation
public import LanguageServerProtocol
@_spi(SourceKitLSP) import SKLogging
import Synchronization
@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions

/// A connection between two message handlers in the same process.
Expand All @@ -39,7 +40,7 @@ public final class LocalConnection: Connection, Sendable {
/// The queue guarding `_nextRequestID`.
private let queue: DispatchQueue = DispatchQueue(label: "local-connection-queue")

private let _nextRequestID = AtomicUInt32(initialValue: 0)
private let _nextRequestID = Atomic<UInt32>(0)

/// - Important: Must only be accessed from `queue`
nonisolated(unsafe) private var state: State = .ready
Expand Down Expand Up @@ -87,7 +88,7 @@ public final class LocalConnection: Connection, Sendable {
}

public func nextRequestID() -> RequestID {
return .string("sk-\(_nextRequestID.fetchAndIncrement())")
return .string("sk-\(_nextRequestID.wrappingAdd(1, ordering: .relaxed).oldValue)")
}

public func send<Notification: NotificationType>(_ notification: Notification) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import Foundation
public import LanguageServerProtocol
@_spi(SourceKitLSP) import SKLogging
import Synchronization
@_spi(SourceKitLSP) public import ToolsProtocolsSwiftExtensions

/// Side structure in which `QueueBasedMessageHandler` can keep track of active requests etc.
Expand Down Expand Up @@ -42,7 +43,7 @@ public final class QueueBasedMessageHandlerHelper: Sendable {
private let createLoggingScope: Bool

/// Notifications don't have an ID. This represents the next ID we can use to identify a notification.
private let notificationIDForLogging = AtomicUInt32(initialValue: 1)
private let notificationIDForLogging = Atomic<UInt32>(1)

private let state = ThreadSafeBox(initialValue: State())

Expand Down Expand Up @@ -107,7 +108,7 @@ public final class QueueBasedMessageHandlerHelper: Sendable {
// Only use the last two digits of the notification ID for the logging scope to avoid creating too many scopes.
// See comment in `withLoggingScope`.
// The last 2 digits should be sufficient to differentiate between multiple concurrently running notifications.
let notificationID = notificationIDForLogging.fetchAndIncrement()
let notificationID = notificationIDForLogging.wrappingAdd(1, ordering: .relaxed).oldValue
withLoggingScope("notification-\(notificationID % 100)") {
body()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//

public import LanguageServerProtocol
import Synchronization
@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions

/// A request and a callback that returns the request's reply
Expand All @@ -22,20 +23,20 @@ public final class RequestAndReply<Params: RequestType>: Sendable {
private let reply: @Sendable (Result<Params.Response, any Error>) -> Void

/// Whether a reply has been made. Every request must reply exactly once.
private let replied: AtomicBool = AtomicBool(initialValue: false)
private let replied = Atomic<Bool>(false)

public init(_ request: Params, reply: @escaping @Sendable (Result<Params.Response, any Error>) -> Void) {
self.params = request
self.reply = reply
}

deinit {
precondition(replied.value, "request never received a reply")
precondition(replied.load(ordering: .acquiring), "request never received a reply")
}

/// Call the `replyBlock` with the result produced by the given closure.
public func reply(_ body: () async throws -> Params.Response) async {
let didReply = replied.setAndGet(newValue: true)
let didReply = replied.exchange(true, ordering: .acquiringAndReleasing)
precondition(!didReply, "replied to request more than once")
do {
reply(.success(try await body()))
Expand Down
5 changes: 3 additions & 2 deletions Sources/SKLogging/LoggingScope.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//

import Foundation
import Synchronization
@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions

public final class LoggingScope {
Expand All @@ -20,7 +21,7 @@ public final class LoggingScope {

/// Whether we have logged a fault that `subsystem` has been accessed without calling
/// `configureDefaultLoggingSubsystem` first.
private static let hasLoggedNoSubsystemConfiguredFault = AtomicBool(initialValue: false)
private static let hasLoggedNoSubsystemConfiguredFault = Atomic<Bool>(false)

/// The name of the current logging subsystem or `nil` if no logging scope is set.
@TaskLocal fileprivate static var _subsystem: String?
Expand All @@ -35,7 +36,7 @@ public final class LoggingScope {
} else if let defaultSubsystem = defaultSubsystem.value {
return defaultSubsystem
} else {
if !hasLoggedNoSubsystemConfiguredFault.setAndGet(newValue: true) {
if !hasLoggedNoSubsystemConfiguredFault.exchange(true, ordering: .relaxed) {
Logger(subsystem: "default", category: "sklogging")
.fault(
"""
Expand Down
5 changes: 3 additions & 2 deletions Sources/SKLogging/NonDarwinLogging.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//

import Synchronization
@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions

#if canImport(Darwin)
Expand Down Expand Up @@ -434,7 +435,7 @@ public struct NonDarwinLogger: Sendable {
fileprivate let id: NonDarwinSignpostID
}

private let nextSignpostID = AtomicUInt32(initialValue: 0)
private let nextSignpostID = Atomic<UInt32>(0)

/// A type that is API-compatible to `OSLogMessage` for all uses within sourcekit-lsp.
///
Expand All @@ -447,7 +448,7 @@ private let nextSignpostID = AtomicUInt32(initialValue: 0)
}

@_spi(SourceKitLSP) public func makeSignpostID() -> NonDarwinSignpostID {
return NonDarwinSignpostID(id: nextSignpostID.fetchAndIncrement())
return NonDarwinSignpostID(id: nextSignpostID.wrappingAdd(1, ordering: .relaxed).oldValue)
}

@_spi(SourceKitLSP) public func beginInterval(
Expand Down
11 changes: 0 additions & 11 deletions Sources/ToolsProtocolsCAtomics/CAtomics.c

This file was deleted.

4 changes: 0 additions & 4 deletions Sources/ToolsProtocolsCAtomics/CMakeLists.txt

This file was deleted.

78 changes: 0 additions & 78 deletions Sources/ToolsProtocolsCAtomics/include/ToolsProtocolsCAtomics.h

This file was deleted.

4 changes: 0 additions & 4 deletions Sources/ToolsProtocolsCAtomics/include/module.modulemap

This file was deleted.

2 changes: 1 addition & 1 deletion Sources/ToolsProtocolsSwiftExtensions/AsyncUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ package func withTimeout<T: Sendable>(
body: @escaping @Sendable () async throws -> T,
resultReceivedAfterTimeout: @escaping @Sendable (_ result: T) async -> Void
) async throws -> T? {
let didHitTimeout = AtomicBool(initialValue: false)
let didHitTimeout = ThreadSafeBox<Bool>(initialValue: false)

let stream = AsyncThrowingStream<T?, Error> { continuation in
Task {
Expand Down
Loading
Loading