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
5 changes: 3 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var PlatformLinkerSettings: [LinkerSetting] = []
PlatformPackageDependencies = [
.package(
url: "https://github.com/PADL/IORingSwift",
from: "0.1.2"
from: "0.9.9"
),
.package(
url: "https://github.com/PADL/NetLinkSwift",
Expand Down Expand Up @@ -112,6 +112,7 @@ let CommonPackageDependencies: [Package.Dependency] = [
.package(url: "https://github.com/swhitty/FlyingFoxMacros", from: "0.2.0"),
.package(url: "https://github.com/Flight-School/AnyCodable", from: "0.6.7"),
.package(url: "https://github.com/apple/swift-binary-parsing", from: "0.0.1"),
.package(url: "https://github.com/dfed/swift-async-queue", from: "1.0.0"),
]

let CommonProducts: [Product] = [
Expand Down Expand Up @@ -157,7 +158,7 @@ let CommonTargets: [Target] = [
.product(name: "SystemPackage", package: "swift-system"),
.product(name: "FlyingFox", package: "FlyingFox"),
.product(name: "FlyingFoxMacros", package: "FlyingFoxMacros"),

.product(name: "AsyncQueue", package: "swift-async-queue"),
] + PlatformTargetDependencies,
cSettings: PlatformCSettings,
swiftSettings: PlatformSwiftSettings,
Expand Down
15 changes: 6 additions & 9 deletions Sources/MRP/Model/Participant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
// identifies the set of Bridge Ports that form the applicable active topology
// (8.4).

import AsyncQueue
import IEEE802
import Logging
import Synchronization
Expand Down Expand Up @@ -128,6 +129,7 @@ public final class Participant<A: Application>: Equatable, Hashable, CustomStrin

fileprivate let _logger: Logger
fileprivate let _type: ParticipantType
fileprivate let _queue = ActorQueue<A>()
fileprivate nonisolated var controller: MRPController<A.P>? { _controller.object }

nonisolated var application: A? { _application.object }
Expand All @@ -143,6 +145,7 @@ public final class Participant<A: Application>: Equatable, Hashable, CustomStrin
) {
_controller = Weak(controller)
_application = Weak(application)
_queue.adoptExecutionContext(of: application)
self.contextIdentifier = contextIdentifier

self.port = port
Expand Down Expand Up @@ -1073,7 +1076,8 @@ private final class _AttributeValue<A: Application>: Sendable, Hashable, Equatab
attributeType: attributeType,
attributeSubtype: attributeSubtype,
attributeValue: unwrappedValue,
smFlags: participant._getSmFlags(for: attributeType).union(isReplacingSubtype ? .isReplacingSubtype : []),
smFlags: participant._getSmFlags(for: attributeType)
.union(isReplacingSubtype ? .isReplacingSubtype : []),
applicant: applicant,
registrar: registrar
)
Expand Down Expand Up @@ -1196,14 +1200,7 @@ private final class _AttributeValue<A: Application>: Sendable, Hashable, Equatab
// the subsequent join
guard !context.smFlags.contains(.isReplacingSubtype) else { return }

// running application indications in unstructured tasks is a trade-off; it
// allows us to make the participant API as consumed by the application
// synchronous, thereby avoiding reentrancy issues; but it does not
// completely eliminate the possibility of race conditions as different
// values of the same attribute, or related attributes, are processed (as
// Tasks are not necessarily scheduled in order). If this proves to be
// problematic, we should look at using a queue of tasks instead.
Task { @Sendable in
Task(on: context.participant._queue) { @Sendable _ in
switch registrarAction {
case .New:
fallthrough
Expand Down