AFutureD/swift-synchronization

★ 0Forks 0SwiftGitHub ↗Compare

README

SynchronizationKit

A Swift package providing simple, cross-platform synchronization primitives.

This library offers LazyLockedValue and LazyLock types that abstract away platform-specific locking mechanisms, providing a consistent API across Apple and other platforms.

Features

  • LazyLockedValue<Value>: A type that protects a value with a lock, ensuring safe concurrent access and mutation.
  • LazyLock: A basic mutex-style lock for manual lock/unlock operations.
  • Cross-Platform: Uses os.lock (OSAllocatedUnfairLock) on Apple platforms (macOS, iOS, watchOS, tvOS) for optimal performance and falls back to a pthread-based lock (derived from SwiftNIO) on other platforms like Linux and Windows.
  • Sendable Support: Designed with Swift Concurrency in mind, with initializers that respect Sendable constraints.

Supported Platforms

  • macOS
  • iOS
  • watchOS
  • tvOS
  • Linux
  • Windows

Usage

LazyLockedValue

Use LazyLockedValue to protect a piece of mutable state that needs to be accessed from multiple concurrent contexts. All mutations are performed within a withLock closure.

import SynchronizationKit

final class Counter {
    private let _count = LazyLockedValue(0)

    func increment() {
        _count.withLock { $0 += 1 }
    }

    var value: Int {
        _count.withLock { $0 }
    }
}

let counter = Counter()
DispatchQueue.concurrentPerform(iterations: 100) { _ in
    counter.increment()
}
print(counter.value) // Prints "100"

LazyLock

Use LazyLock for more fine-grained control where you need to manually acquire and release a lock. Always use defer to ensure the lock is released.

import SynchronizationKit

let lock = LazyLock()
var sharedResource = [String]()

func addItem(_ item: String) {
    lock.lock()
    defer { lock.unlock() }
    sharedResource.append(item)
}

addItem("Hello")
addItem("World")
print(sharedResource) // Prints "["Hello", "World"]"

Installation

Add SynchronizationKit as a dependency to your Package.swift file:

// swift-tools-version:6.0
import PackageDescription

let package = Package(
    name: "MyProject",
    dependencies: [
        .package(url: "https://github.com/AFutureD/swift-synchronization.git", from: "1.0.0")
    ],
    targets: [
        .target(
            name: "MyProject",
            dependencies: [
                .product(name: "SynchronizationKit", package: "swift-synchronization")
            ]
        )
    ]
)

Acknowledgements

The pthread-based lock implementation for non-Apple platforms is derived from the excellent NIOLock and NIOLockedValueBox in the SwiftNIO project.

Contributors

AFutureD

Issues