Skip to content

Commit

Permalink
Swift 6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
NikSativa committed Sep 25, 2024
1 parent 13eb2e1 commit 02018cb
Show file tree
Hide file tree
Showing 25 changed files with 409 additions and 272 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Pods/*
Carthage/*
Packages/*
.swiftpm/*
Package.resolved

## Bundler
.bundle/
Expand Down
8 changes: 8 additions & 0 deletions .spi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This is manifest file for the Swift Package Index for it to
# auto-generate and host DocC documentation.
# For reference see https://swiftpackageindex.com/swiftpackageindex/spimanifest/documentation/spimanifest/commonusecases#Host-DocC-documentation-in-the-Swift-Package-Index.

version: 1
builder:
configs:
- documentation_targets: [Threading]
32 changes: 0 additions & 32 deletions Package.resolved

This file was deleted.

17 changes: 3 additions & 14 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.9
// swift-tools-version:6.0
// swiftformat:disable all
import PackageDescription

Expand All @@ -13,11 +13,10 @@ let package = Package(
.watchOS(.v6)
],
products: [
.library(name: "Threading", targets: ["Threading"]),
.library(name: "ThreadingTestHelpers", targets: ["ThreadingTestHelpers"])
.library(name: "Threading", targets: ["Threading"])
],
dependencies: [
.package(url: "https://github.com/NikSativa/SpryKit.git", .upToNextMajor(from: "2.2.3"))
.package(url: "https://github.com/NikSativa/SpryKit.git", .upToNextMajor(from: "2.3.9"))
],
targets: [
.target(name: "Threading",
Expand All @@ -27,19 +26,9 @@ let package = Package(
resources: [
.copy("../PrivacyInfo.xcprivacy")
]),
.target(name: "ThreadingTestHelpers",
dependencies: [
"Threading",
"SpryKit"
],
path: "TestHelpers",
resources: [
.copy("../PrivacyInfo.xcprivacy")
]),
.testTarget(name: "ThreadingTests",
dependencies: [
"Threading",
"ThreadingTestHelpers",
"SpryKit"
],
path: "Tests")
Expand Down
13 changes: 1 addition & 12 deletions [email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ let package = Package(
],
products: [
.library(name: "Threading", targets: ["Threading"]),
.library(name: "ThreadingTestHelpers", targets: ["ThreadingTestHelpers"])
],
dependencies: [
.package(url: "https://github.com/NikSativa/SpryKit.git", .upToNextMajor(from: "2.2.3"))
.package(url: "https://github.com/NikSativa/SpryKit.git", .upToNextMajor(from: "2.3.7"))
],
targets: [
.target(name: "Threading",
Expand All @@ -26,19 +25,9 @@ let package = Package(
resources: [
.copy("../PrivacyInfo.xcprivacy")
]),
.target(name: "ThreadingTestHelpers",
dependencies: [
"Threading",
"SpryKit"
],
path: "TestHelpers",
resources: [
.copy("../PrivacyInfo.xcprivacy")
]),
.testTarget(name: "ThreadingTests",
dependencies: [
"Threading",
"ThreadingTestHelpers",
"SpryKit"
],
path: "Tests")
Expand Down
13 changes: 1 addition & 12 deletions [email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ let package = Package(
],
products: [
.library(name: "Threading", targets: ["Threading"]),
.library(name: "ThreadingTestHelpers", targets: ["ThreadingTestHelpers"])
],
dependencies: [
.package(url: "https://github.com/NikSativa/SpryKit.git", .upToNextMajor(from: "2.2.3"))
.package(url: "https://github.com/NikSativa/SpryKit.git", .upToNextMajor(from: "2.3.7"))
],
targets: [
.target(name: "Threading",
Expand All @@ -26,19 +25,9 @@ let package = Package(
resources: [
.copy("../PrivacyInfo.xcprivacy")
]),
.target(name: "ThreadingTestHelpers",
dependencies: [
"Threading",
"SpryKit"
],
path: "TestHelpers",
resources: [
.copy("../PrivacyInfo.xcprivacy")
]),
.testTarget(name: "ThreadingTests",
dependencies: [
"Threading",
"ThreadingTestHelpers",
"SpryKit"
],
path: "Tests")
Expand Down
13 changes: 1 addition & 12 deletions [email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ let package = Package(
],
products: [
.library(name: "Threading", targets: ["Threading"]),
.library(name: "ThreadingTestHelpers", targets: ["ThreadingTestHelpers"])
],
dependencies: [
.package(url: "https://github.com/NikSativa/SpryKit.git", .upToNextMajor(from: "2.2.3"))
.package(url: "https://github.com/NikSativa/SpryKit.git", .upToNextMajor(from: "2.3.7"))
],
targets: [
.target(name: "Threading",
Expand All @@ -26,19 +25,9 @@ let package = Package(
resources: [
.copy("../PrivacyInfo.xcprivacy")
]),
.target(name: "ThreadingTestHelpers",
dependencies: [
"Threading",
"SpryKit"
],
path: "TestHelpers",
resources: [
.copy("../PrivacyInfo.xcprivacy")
]),
.testTarget(name: "ThreadingTests",
dependencies: [
"Threading",
"ThreadingTestHelpers",
"SpryKit"
],
path: "Tests")
Expand Down
13 changes: 1 addition & 12 deletions [email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ let package = Package(
],
products: [
.library(name: "Threading", targets: ["Threading"]),
.library(name: "ThreadingTestHelpers", targets: ["ThreadingTestHelpers"])
],
dependencies: [
.package(url: "https://github.com/NikSativa/SpryKit.git", .upToNextMajor(from: "2.2.3"))
.package(url: "https://github.com/NikSativa/SpryKit.git", .upToNextMajor(from: "2.3.7"))
],
targets: [
.target(name: "Threading",
Expand All @@ -26,19 +25,9 @@ let package = Package(
resources: [
.copy("../PrivacyInfo.xcprivacy")
]),
.target(name: "ThreadingTestHelpers",
dependencies: [
"Threading",
"SpryKit"
],
path: "TestHelpers",
resources: [
.copy("../PrivacyInfo.xcprivacy")
]),
.testTarget(name: "ThreadingTests",
dependencies: [
"Threading",
"ThreadingTestHelpers",
"SpryKit"
],
path: "Tests")
Expand Down
36 changes: 36 additions & 0 deletions [email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// swift-tools-version:5.9
// swiftformat:disable all
import PackageDescription

let package = Package(
name: "Threading",
platforms: [
.iOS(.v13),
.macOS(.v11),
.macCatalyst(.v13),
.tvOS(.v13),
.watchOS(.v6),
.visionOS(.v1)
],
products: [
.library(name: "Threading", targets: ["Threading"]),
],
dependencies: [
.package(url: "https://github.com/NikSativa/SpryKit.git", .upToNextMajor(from: "2.3.7"))
],
targets: [
.target(name: "Threading",
dependencies: [
],
path: "Source",
resources: [
.copy("../PrivacyInfo.xcprivacy")
]),
.testTarget(name: "ThreadingTests",
dependencies: [
"Threading",
"SpryKit"
],
path: "Tests")
]
)
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Queue.main.sync {

### Queueable
Protocol can help you test your code without threading by overriding real implementation via your own mock or existing Fake from SpryKit framework.

### DelayedQueue
Make it simple to manage task execution as parameter at your discretion. You can manage not only in what Queue to execute but also how - sync or async.

Expand All @@ -38,3 +39,35 @@ you can never go wrong with creating a queue due to explicit parameters
```swift
Queue.custom(label: “my line”, attributes: .serial).async
```

### Concurrency workarounds

Some times very difficult to avoid concurrency isolation issues. This is a simple solution to avoid it. Just use isolatedMain queue to execute your task on the main thread without any side effects.

```swift
Queue.isolatedMain.sync {
// your task on main thread
}

Queue.isolatedMain.sync {
// or return value from main thread
return 42
}

Queue.isolatedMain.sync {
// or throw error from main thread
return try someThrowingFunction()
}
```

UnSendable - is a struct that helps you to avoid concurrency check of non-Sendable objects (ex. using UI elements). It is not a silver bullet, but it can help you to avoid some issues.
> [!WARNING]
> **Use at your own risk.**
```swift
let unsafe = UnSendable(ImageView())
Queue.main.async {
let view = unsafe.value
// make your magic
}
```
22 changes: 11 additions & 11 deletions Source/Atomic.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import Foundation

public protocol Mutexing {
public protocol Mutexing: Sendable {
@discardableResult
func sync<R>(execute work: () throws -> R) rethrows -> R

@discardableResult
func trySync<R>(execute work: () throws -> R) rethrows -> R
}

public enum Mutex {
public enum Kind {
public enum Mutex: Sendable {
public enum Kind: Sendable {
case normal
case recursive

Expand Down Expand Up @@ -41,14 +41,14 @@ public enum Mutex {
}
}

public enum AtomicOption: Equatable {
public enum AtomicOption: Equatable, Sendable {
case async
case sync
case trySync
}

@propertyWrapper
public final class Atomic<Value> {
public final class Atomic<Value>: @unchecked Sendable {
private let mutex: Mutexing
private var value: Value
private let read: AtomicOption
Expand Down Expand Up @@ -136,7 +136,7 @@ public extension Atomic where Value: ExpressibleByNilLiteral {
}
}

private protocol Locking {
private protocol Locking: Sendable {
func lock()
func tryLock() -> Bool
func unlock()
Expand Down Expand Up @@ -183,7 +183,7 @@ extension NSRecursiveLock: Locking {
}

private enum Impl {
final class Unfair: SimpleMutexing {
final class Unfair: SimpleMutexing, @unchecked Sendable {
private var _lock = os_unfair_lock()

func lock() {
Expand All @@ -199,7 +199,7 @@ private enum Impl {
}
}

struct NSLock: SimpleMutexing {
struct NSLock: SimpleMutexing, @unchecked Sendable {
private let _lock: Locking

public init(kind: Mutex.Kind) {
Expand All @@ -224,7 +224,7 @@ private enum Impl {
}
}

final class PThread: SimpleMutexing {
final class PThread: SimpleMutexing, @unchecked Sendable {
private var _lock: pthread_mutex_t = .init()

public init(kind: Mutex.Kind) {
Expand Down Expand Up @@ -265,7 +265,7 @@ private enum Impl {
}
}

struct Semaphore: Mutexing {
struct Semaphore: Mutexing, @unchecked Sendable {
private var _lock = DispatchSemaphore(value: 1)

func sync<R>(execute work: () throws -> R) rethrows -> R {
Expand All @@ -285,7 +285,7 @@ private enum Impl {
}
}

struct Barrier: Mutexing {
struct Barrier: Mutexing, @unchecked Sendable {
private let queue: Queueable

init(_ queue: Queueable) {
Expand Down
Loading

0 comments on commit 02018cb

Please sign in to comment.