@@ -349,23 +349,25 @@ private struct LambdaHttpServer {
349
349
private final class Pool < T> : AsyncSequence , AsyncIteratorProtocol , Sendable where T: Sendable {
350
350
typealias Element = T
351
351
352
- private let _buffer = Mutex < CircularBuffer < T > > ( . init( ) )
353
- private let _continuation = Mutex < CheckedContinuation < T , any Error > ? > ( nil )
352
+ private let mutex = Mutex < ( CircularBuffer < T > , CheckedContinuation < T , any Error > ? ) > ( ( . init( ) , nil ) )
354
353
355
354
/// retrieve the first element from the buffer
356
- public func popFirst( ) async -> T ? {
357
- self . _buffer . withLock { $0. popFirst ( ) }
355
+ public func popFirst( ) -> T ? {
356
+ self . mutex . withLock { $0 . 0 . popFirst ( ) }
358
357
}
359
358
360
359
/// enqueue an element, or give it back immediately to the iterator if it is waiting for an element
361
360
public func push( _ invocation: T ) async {
362
- // if the iterator is waiting for an element, give it to it
363
- // otherwise, enqueue the element
364
- if let continuation = self . _continuation. withLock ( { $0 } ) {
365
- self . _continuation. withLock { $0 = nil }
366
- continuation. resume ( returning: invocation)
367
- } else {
368
- self . _buffer. withLock { $0. append ( invocation) }
361
+ self . mutex. withLock { mutexContent in
362
+ var ( _buffer, _continuation) = mutexContent
363
+ // if the iterator is waiting for an element, give it to it
364
+ // otherwise, enqueue the element
365
+ if let continuation = _continuation {
366
+ continuation. resume ( returning: invocation)
367
+ _continuation = nil
368
+ } else {
369
+ _buffer. append ( invocation)
370
+ }
369
371
}
370
372
}
371
373
@@ -376,15 +378,17 @@ private struct LambdaHttpServer {
376
378
return nil
377
379
}
378
380
379
- if let element = await self . popFirst ( ) {
381
+ if let element = self . popFirst ( ) {
382
+ // if there is an element in the buffer, dequeue it
380
383
return element
381
384
} else {
382
385
// we can't return nil if there is nothing to dequeue otherwise the async for loop will stop
383
- // wait for an element to be enqueued
384
- return try await withCheckedThrowingContinuation { ( continuation: CheckedContinuation < T , any Error > ) in
385
- // store the continuation for later, when an element is enqueued
386
- self . _continuation. withLock {
387
- $0 = continuation
386
+ // so, wait for an element to be enqueued
387
+ return try await withCheckedThrowingContinuation {
388
+ ( continuation: CheckedContinuation < T , any Error > ) in
389
+ self . mutex. withLock { mutexContent in
390
+ // store the continuation for later, when an element is enqueued
391
+ mutexContent. 1 = continuation
388
392
}
389
393
}
390
394
}
0 commit comments