Skip to content

Commit 2255ee0

Browse files
committed
[skip ci] WIP
1 parent efb2f0a commit 2255ee0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+266
-248
lines changed

Sources/Action.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ public final class Action<Input, Output, Error: Swift.Error> {
116116
let isEnabled = MutableProperty(actionState.value.isEnabled)
117117
self.isEnabled = Property(capturing: isEnabled)
118118

119-
func modifyActionState<Result>(_ action: (inout ActionState<State.Value>) throws -> Result) rethrows -> Result {
119+
@Sendable
120+
func modifyActionState<Result>(_ action: @Sendable (inout ActionState<State.Value>) throws -> Result) rethrows -> Result {
120121
return try actionState.begin { storage in
121122
let oldState = storage.value
122123
defer {

Sources/Atomic.swift

+6-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import MachO
1414
/// A simple, generic lock-free finite state machine.
1515
///
1616
/// - warning: `deinitialize` must be called to dispose of the consumed memory.
17-
internal struct UnsafeAtomicState<State: RawRepresentable> where State.RawValue == Int32 {
17+
internal struct UnsafeAtomicState<State: RawRepresentable>: Sendable where State.RawValue == Int32 {
1818
internal typealias Transition = (expected: State, next: State)
1919
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
2020
private let value: UnsafeMutablePointer<Int32>
@@ -29,6 +29,7 @@ internal struct UnsafeAtomicState<State: RawRepresentable> where State.RawValue
2929
}
3030

3131
/// Deinitialize the finite state machine.
32+
@Sendable
3233
internal func deinitialize() {
3334
value.deinitialize(count: 1)
3435
value.deallocate()
@@ -104,7 +105,8 @@ internal struct UnsafeAtomicState<State: RawRepresentable> where State.RawValue
104105

105106
/// `Lock` exposes `os_unfair_lock` on supported platforms, with pthread mutex as the
106107
/// fallback.
107-
internal class Lock: LockProtocol {
108+
// TODO: unckecked? subclass?
109+
internal class Lock: LockProtocol, @unchecked Sendable {
108110
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
109111
@available(iOS 10.0, *)
110112
@available(macOS 10.12, *)
@@ -212,7 +214,7 @@ internal class Lock: LockProtocol {
212214
func `try`() -> Bool { fatalError() }
213215
}
214216

215-
internal protocol LockProtocol {
217+
internal protocol LockProtocol: Sendable {
216218
static func make() -> Self
217219

218220
func lock()
@@ -229,7 +231,7 @@ internal struct NoLock: LockProtocol {
229231
}
230232

231233
/// An atomic variable.
232-
public final class Atomic<Value> {
234+
public final class Atomic<Value>: @unchecked Sendable {
233235
private let lock: Lock
234236
private var _value: Value
235237

Sources/Bag.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
public struct Bag<Element> {
1111
/// A uniquely identifying token for removing a value that was inserted into a
1212
/// Bag.
13-
public struct Token {
13+
public struct Token: Sendable {
1414
fileprivate let value: UInt64
1515
}
1616

@@ -97,3 +97,5 @@ extension Bag: RandomAccessCollection {
9797
}
9898
}
9999
}
100+
101+
extension Bag: Sendable where Element: Sendable {}

Sources/Disposable.swift

+12-11
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88

99
/// Represents something that can be “disposed”, usually associated with freeing
1010
/// resources or canceling work.
11-
public protocol Disposable: AnyObject {
11+
public protocol Disposable: AnyObject, Sendable {
1212
/// Whether this disposable has been disposed already.
1313
var isDisposed: Bool { get }
1414

1515
/// Disposing of the resources represented by `self`. If `self` has already
1616
/// been disposed of, it does nothing.
1717
///
1818
/// - note: Implementations must issue a memory barrier.
19+
@Sendable
1920
func dispose()
2021
}
2122

@@ -58,22 +59,22 @@ internal final class _SimpleDisposable: Disposable {
5859
/// A disposable that has already been disposed.
5960
internal final class NopDisposable: Disposable {
6061
static let shared = NopDisposable()
61-
var isDisposed = true
62+
let isDisposed = true
6263
func dispose() {}
6364
private init() {}
6465
}
6566

6667
/// A type-erased disposable that forwards operations to an underlying disposable.
6768
public final class AnyDisposable: Disposable {
68-
private final class ActionDisposable: Disposable {
69+
private final class ActionDisposable: Disposable, @unchecked Sendable {
6970
let state: UnsafeAtomicState<DisposableState>
70-
var action: (() -> Void)?
71+
var action: (@Sendable () -> Void)?
7172

7273
var isDisposed: Bool {
7374
return state.is(.disposed)
7475
}
7576

76-
init(_ action: (() -> Void)?) {
77+
init(_ action: (@Sendable () -> Void)?) {
7778
self.state = UnsafeAtomicState(.active)
7879
self.action = action
7980
}
@@ -100,7 +101,7 @@ public final class AnyDisposable: Disposable {
100101
///
101102
/// - parameters:
102103
/// - action: A closure to run when calling `dispose()`.
103-
public init(_ action: @escaping () -> Void) {
104+
public init(_ action: @escaping @Sendable () -> Void) {
104105
base = ActionDisposable(action)
105106
}
106107

@@ -123,7 +124,7 @@ public final class AnyDisposable: Disposable {
123124
}
124125

125126
/// A disposable that will dispose of any number of other disposables.
126-
public final class CompositeDisposable: Disposable {
127+
public final class CompositeDisposable: Disposable, @unchecked Sendable {
127128
private let disposables: Atomic<Bag<Disposable>?>
128129
private var state: UnsafeAtomicState<DisposableState>
129130

@@ -203,7 +204,7 @@ public final class CompositeDisposable: Disposable {
203204
/// composite has been disposed of, `disposable` has been disposed of, or
204205
/// `disposable` is `nil`.
205206
@discardableResult
206-
public func add(_ action: @escaping () -> Void) -> Disposable? {
207+
public func add(_ action: @escaping @Sendable () -> Void) -> Disposable? {
207208
return add(AnyDisposable(action))
208209
}
209210

@@ -246,7 +247,7 @@ public final class CompositeDisposable: Disposable {
246247
/// - returns: An instance of `DisposableHandle` that can be used to opaquely
247248
/// remove the disposable later (if desired).
248249
@discardableResult
249-
public static func += (lhs: CompositeDisposable, rhs: @escaping () -> Void) -> Disposable? {
250+
public static func += (lhs: CompositeDisposable, rhs: @escaping @Sendable () -> Void) -> Disposable? {
250251
return lhs.add(rhs)
251252
}
252253
}
@@ -325,7 +326,7 @@ extension ScopedDisposable where Inner == CompositeDisposable {
325326
/// - returns: An instance of `DisposableHandle` that can be used to opaquely
326327
/// remove the disposable later (if desired).
327328
@discardableResult
328-
public static func += (lhs: ScopedDisposable<CompositeDisposable>, rhs: @escaping () -> Void) -> Disposable? {
329+
public static func += (lhs: ScopedDisposable<CompositeDisposable>, rhs: @escaping @Sendable () -> Void) -> Disposable? {
329330
return lhs.inner.add(rhs)
330331
}
331332
}
@@ -334,7 +335,7 @@ extension ScopedDisposable where Inner == CompositeDisposable {
334335
/// wrapped disposable to be replaced.
335336
public final class SerialDisposable: Disposable {
336337
private let _inner: Atomic<Disposable?>
337-
private var state: UnsafeAtomicState<DisposableState>
338+
private let state: UnsafeAtomicState<DisposableState>
338339

339340
public var isDisposed: Bool {
340341
return state.is(.disposed)

Sources/Event.swift

+10-10
Original file line numberDiff line numberDiff line change
@@ -206,27 +206,27 @@ extension Signal.Event: EventProtocol {
206206
// This operator performs side effect upon interruption.
207207

208208
extension Signal.Event {
209-
internal typealias Transformation<U, E: Swift.Error> = (ReactiveSwift.Observer<U, E>, Lifetime) -> ReactiveSwift.Observer<Value, Error>
209+
internal typealias Transformation<U, E: Swift.Error> = (any ReactiveSwift.Observer<U, E>, Lifetime) -> (any ReactiveSwift.Observer<Value, Error>)
210210

211-
internal static func filter(_ isIncluded: @escaping (Value) -> Bool) -> Transformation<Value, Error> {
211+
internal static func filter(_ isIncluded: @escaping @Sendable (Value) -> Bool) -> Transformation<Value, Error> {
212212
return { downstream, _ in
213213
Operators.Filter(downstream: downstream, predicate: isIncluded)
214214
}
215215
}
216216

217-
internal static func compactMap<U>(_ transform: @escaping (Value) -> U?) -> Transformation<U, Error> {
217+
internal static func compactMap<U>(_ transform: @escaping @Sendable (Value) -> U?) -> Transformation<U, Error> {
218218
return { downstream, _ in
219219
Operators.CompactMap(downstream: downstream, transform: transform)
220220
}
221221
}
222222

223-
internal static func map<U>(_ transform: @escaping (Value) -> U) -> Transformation<U, Error> {
223+
internal static func map<U>(_ transform: @escaping @Sendable (Value) -> U) -> Transformation<U, Error> {
224224
return { downstream, _ in
225225
Operators.Map(downstream: downstream, transform: transform)
226226
}
227227
}
228228

229-
internal static func mapError<E>(_ transform: @escaping (Error) -> E) -> Transformation<Value, E> {
229+
internal static func mapError<E>(_ transform: @escaping @Sendable (Error) -> E) -> Transformation<Value, E> {
230230
return { downstream, _ in
231231
Operators.MapError(downstream: downstream, transform: transform)
232232
}
@@ -244,13 +244,13 @@ extension Signal.Event {
244244
}
245245
}
246246

247-
internal static func attemptMap<U>(_ transform: @escaping (Value) -> Result<U, Error>) -> Transformation<U, Error> {
247+
internal static func attemptMap<U>(_ transform: @escaping @Sendable (Value) -> Result<U, Error>) -> Transformation<U, Error> {
248248
return { downstream, _ in
249249
Operators.AttemptMap(downstream: downstream, transform: transform)
250250
}
251251
}
252252

253-
internal static func attempt(_ action: @escaping (Value) -> Result<(), Error>) -> Transformation<Value, Error> {
253+
internal static func attempt(_ action: @escaping @Sendable (Value) -> Result<(), Error>) -> Transformation<Value, Error> {
254254
return attemptMap { value -> Result<Value, Error> in
255255
return action(value).map { _ in value }
256256
}
@@ -285,13 +285,13 @@ extension Signal.Event {
285285
}
286286
}
287287

288-
internal static func take(while shouldContinue: @escaping (Value) -> Bool) -> Transformation<Value, Error> {
288+
internal static func take(while shouldContinue: @escaping @Sendable (Value) -> Bool) -> Transformation<Value, Error> {
289289
return { downstream, _ in
290290
Operators.TakeWhile(downstream: downstream, shouldContinue: shouldContinue)
291291
}
292292
}
293293

294-
internal static func take(until shouldContinue: @escaping (Value) -> Bool) -> Transformation<Value, Error> {
294+
internal static func take(until shouldContinue: @escaping @Sendable (Value) -> Bool) -> Transformation<Value, Error> {
295295
return { downstream, _ in
296296
Operators.TakeUntil(downstream: downstream, shouldContinue: shouldContinue)
297297
}
@@ -397,7 +397,7 @@ extension Signal.Event {
397397
return scan(into: initialResult) { $0 = nextPartialResult($0, $1) }
398398
}
399399

400-
internal static func scanMap<State, U>(into initialState: State, _ next: @escaping (inout State, Value) -> U) -> Transformation<U, Error> {
400+
internal static func scanMap<State, U>(into initialState: State, _ next: @escaping @Sendable (inout State, Value) -> U) -> Transformation<U, Error> {
401401
return { downstream, _ in
402402
Operators.ScanMap(downstream: downstream, initial: initialState, next: next)
403403
}

Sources/EventLogger.swift

+20-13
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public func defaultEventLog(identifier: String, event: String, fileName: String,
3131

3232
/// A type that represents an event logging function.
3333
/// Signature is:
34-
/// - identifier
34+
/// - identifier
3535
/// - event
3636
/// - fileName
3737
/// - functionName
@@ -52,22 +52,22 @@ fileprivate struct LogContext<Event: LoggingEventProtocol> {
5252
let functionName: String
5353
let lineNumber: Int
5454
let logger: EventLogger
55-
56-
func log<T>(_ event: Event) -> ((T) -> Void)? {
55+
56+
func log<T>(_ event: Event) -> (@Sendable (T) -> Void)? {
5757
return event.logIfNeeded(events: self.events) { event in
5858
self.logger(self.identifier, event, self.fileName, self.functionName, self.lineNumber)
5959
}
6060
}
61-
62-
func log(_ event: Event) -> (() -> Void)? {
61+
62+
func log(_ event: Event) -> (@Sendable () -> Void)? {
6363
return event.logIfNeededNoArg(events: self.events) { event in
6464
self.logger(self.identifier, event, self.fileName, self.functionName, self.lineNumber)
6565
}
6666
}
6767
}
6868

6969
extension Signal {
70-
/// Logs all events that the receiver sends. By default, it will print to
70+
/// Logs all events that the receiver sends. By default, it will print to
7171
/// the standard output.
7272
///
7373
/// - parameters:
@@ -80,14 +80,21 @@ extension Signal {
8080
/// - logger: Logger that logs the events.
8181
///
8282
/// - returns: Signal that, when observed, logs the fired events.
83-
public func logEvents(identifier: String = "", events: Set<LoggingEvent.Signal> = Set(LoggingEvent.Signal.allCases), fileName: String = #file, functionName: String = #function, lineNumber: Int = #line, logger: @escaping EventLogger = defaultEventLog) -> Signal<Value, Error> {
83+
public func logEvents(
84+
identifier: String = "",
85+
events: Set<LoggingEvent.Signal> = Set(LoggingEvent.Signal.allCases),
86+
fileName: String = #file,
87+
functionName: String = #function,
88+
lineNumber: Int = #line,
89+
logger: @escaping EventLogger = defaultEventLog
90+
) -> Signal<Value, Error> {
8491
let logContext = LogContext(events: events,
8592
identifier: identifier,
8693
fileName: fileName,
8794
functionName: functionName,
8895
lineNumber: lineNumber,
8996
logger: logger)
90-
97+
9198
return self.on(
9299
failed: logContext.log(.failed),
93100
completed: logContext.log(.completed),
@@ -100,7 +107,7 @@ extension Signal {
100107
}
101108

102109
extension SignalProducer {
103-
/// Logs all events that the receiver sends. By default, it will print to
110+
/// Logs all events that the receiver sends. By default, it will print to
104111
/// the standard output.
105112
///
106113
/// - parameters:
@@ -149,14 +156,14 @@ private extension LoggingEventProtocol {
149156
// Due to differences in the type checker, this method cannot
150157
// overload the generic `logIfNeeded`, or otherwise it would lead to
151158
// infinite recursion with Swift 4.0.x.
152-
func logIfNeededNoArg(events: Set<Self>, logger: @escaping (String) -> Void) -> (() -> Void)? {
159+
func logIfNeededNoArg(events: Set<Self>, logger: @escaping (String) -> Void) -> (@Sendable () -> Void)? {
153160
return (self.logIfNeeded(events: events, logger: logger) as ((()) -> Void)?)
154161
.map { closure in
155-
{ closure(()) }
162+
{ @Sendable in closure(()) }
156163
}
157164
}
158-
159-
func logIfNeeded<T>(events: Set<Self>, logger: @escaping (String) -> Void) -> ((T) -> Void)? {
165+
166+
func logIfNeeded<T>(events: Set<Self>, logger: @escaping (String) -> Void) -> (@Sendable (T) -> Void)? {
160167
guard events.contains(self) else {
161168
return nil
162169
}

0 commit comments

Comments
 (0)