Skip to content

Commit

Permalink
make send/receive public and inline all select functions
Browse files Browse the repository at this point in the history
  • Loading branch information
gh123man committed May 12, 2024
1 parent 4fffbe8 commit 679ee7d
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 11 deletions.
8 changes: 4 additions & 4 deletions Sources/AsyncChannels/Channel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ public final class Channel<T: Sendable>: @unchecked Sendable {
return false
}

@usableFromInline
func send(_ value: T) async {
@inline(__always)
public func send(_ value: T) async {
mutex.lock()

if nonBlockingSend(value) {
Expand Down Expand Up @@ -143,8 +143,8 @@ public final class Channel<T: Sendable>: @unchecked Sendable {
return val
}

@usableFromInline
func receive() async -> T? {
@inline(__always)
public func receive() async -> T? {
mutex.lock()

if let val = nonBlockingReceive() {
Expand Down
4 changes: 0 additions & 4 deletions Sources/AsyncChannels/FastLock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ struct FastLock {
}()


@inlinable
@inline(__always)
func lock() {
os_unfair_lock_lock(unfairLock)
}

@inlinable
@inline(__always)
func unlock() {
os_unfair_lock_unlock(unfairLock)
Expand All @@ -33,13 +31,11 @@ class FastLock {
return m
}()

@inlinable
@inline(__always)
func lock() {
pthread_mutex_lock(&m)
}

@inlinable
@inline(__always)
func unlock() {
pthread_mutex_unlock(&m)
Expand Down
2 changes: 0 additions & 2 deletions Sources/AsyncChannels/LinkedList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ struct LinkedList<T> {
private var tail: Node?
private(set) var count: Int = 0

@inlinable
@inline(__always)
mutating func push(_ value: T) {
let node = Node(value: value)
Expand All @@ -30,7 +29,6 @@ struct LinkedList<T> {
isEmpty = false
}

@inlinable
@inline(__always)
mutating func pop() -> T? {
let value = head?.value
Expand Down
28 changes: 27 additions & 1 deletion Sources/AsyncChannels/Select.swift
Original file line number Diff line number Diff line change
@@ -1,27 +1,34 @@
import Foundation

public struct SelectHandler {

@usableFromInline
internal let inner: SelectProtocol

@inlinable
init(inner: SelectProtocol) {
self.inner = inner
}
}

@usableFromInline
protocol SelectProtocol {
func handle(_ sm: SelectSignal) async -> Bool
}

@usableFromInline
struct ReceiveHandler<T>: SelectProtocol {

private var chan: Channel<T>
private let outFunc: (T?) async -> ()

@usableFromInline
init(chan: Channel<T>, outFunc: @escaping (T?) async -> ()) {
self.chan = chan
self.outFunc = outFunc
}

@usableFromInline
func handle(_ sm: SelectSignal) async -> Bool {
if let val = chan.receiveOrListen(sm) {
await outFunc(val)
Expand All @@ -35,30 +42,36 @@ struct ReceiveHandler<T>: SelectProtocol {
}
}

@usableFromInline
struct NoneHandler: SelectProtocol {
private let handler: () async -> ()

@usableFromInline
init(handler: @escaping () async -> ()) {
self.handler = handler
}

@usableFromInline
func handle(_ sm: SelectSignal) async -> Bool {
await handler()
return true
}
}

@usableFromInline
struct SendHandler<T>: SelectProtocol {
private var chan: Channel<T>
private let val: T
private let onSend: () async -> ()

@usableFromInline
init(chan: Channel<T>, val: T, onSend: @escaping () async -> ()) {
self.chan = chan
self.val = val
self.onSend = onSend
}

@usableFromInline
func handle(_ sm: SelectSignal) async -> Bool {
if chan.sendOrListen(sm, value: val) {
await onSend()
Expand All @@ -75,7 +88,8 @@ public struct SelectCollector {
}
}

@usableFromInline
@inlinable
@inline(__always)
func handle(_ sm: SelectSignal, handlers: [SelectHandler]) async -> Bool {
var defaultCase: NoneHandler?

Expand All @@ -102,26 +116,38 @@ public func select(@SelectCollector cases: () -> ([SelectHandler])) async {
}
}

@inlinable
@inline(__always)
public func receive<T>(_ chan: Channel<T>, _ outFunc: @escaping (T?) async -> ()) -> SelectHandler {
return SelectHandler(inner: ReceiveHandler(chan: chan, outFunc: outFunc))
}

@inlinable
@inline(__always)
public func receive<T>(_ chan: Channel<T>, _ outFunc: @escaping () async -> ()) -> SelectHandler {
return SelectHandler(inner: ReceiveHandler(chan: chan, outFunc: { _ in await outFunc() }))
}

@inlinable
@inline(__always)
public func receive<T>(_ chan: Channel<T>) -> SelectHandler {
return SelectHandler(inner: ReceiveHandler(chan: chan, outFunc: { _ in }))
}

@inlinable
@inline(__always)
public func send<T>(_ val: T, to chan: Channel<T>) -> SelectHandler {
return SelectHandler(inner: SendHandler(chan: chan, val: val, onSend: {}))
}

@inlinable
@inline(__always)
public func send<T>(_ val: T, to chan: Channel<T>, _ onSend: @escaping () async -> ()) -> SelectHandler {
return SelectHandler(inner: SendHandler(chan: chan, val: val, onSend: onSend))
}

@inlinable
@inline(__always)
public func none(handler: @escaping () async -> ()) -> SelectHandler {
return SelectHandler(inner: NoneHandler(handler: handler))
}
Expand Down
13 changes: 13 additions & 0 deletions Tests/AsyncChannelsTests/AsyncChannelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,19 @@ final class AsyncTest: XCTestCase {
await <-b
}

func testUnbufferedPublicSendRec() async {

let a = Channel<Int>()
let b = Channel<Int>()

Task {
await _ = a.receive()
await b.send(0)
}
await a.send(0)
await _ = b.receive()
}

func testCloseNotify() async {
let a = Channel<Bool>()
let done = Channel<Bool>()
Expand Down

0 comments on commit 679ee7d

Please sign in to comment.