1515import Logging
1616import NIOConcurrencyHelpers
1717import NIOCore
18- import Synchronization
18+
19+ // To be re-enabled when we will be able to use Mutex on Linux
20+ // import Synchronization
1921
2022#if canImport(FoundationEssentials)
2123import FoundationEssentials
@@ -26,12 +28,18 @@ import Foundation
2628// This is our gardian to ensure only one LambdaRuntime is initialized
2729// We use a Mutex here to ensure thread safety
2830// We use Bool instead of LambdaRuntime<Handler> as the type here, as we don't know the concrete type that will be used
29- private let _singleton = Mutex < Bool > ( false )
31+ // We would love to use Mutex here, but this sadly crashes the compiler today (on Linux).
32+ // private let _singleton = Mutex<Bool>(false)
33+ private let _singleton : NIOLockedValueBox < Bool > = NIOLockedValueBox < Bool > ( false )
3034public enum LambdaRuntimeError : Error {
3135 case moreThanOneLambdaRuntimeInstance
3236}
33- public final class LambdaRuntime < Handler> : Sendable where Handler: StreamingLambdaHandler {
34- let handlerMutex : Mutex < Handler ? >
37+ // We need `@unchecked` Sendable here, as `NIOLockedValueBox` does not understand `sending` today.
38+ // We don't want to use `NIOLockedValueBox` here anyway. We would love to use Mutex here, but this
39+ // sadly crashes the compiler today (on Linux).
40+ public final class LambdaRuntime < Handler> : @unchecked Sendable where Handler: StreamingLambdaHandler {
41+ // TODO: We want to change this to Mutex as soon as this doesn't crash the Swift compiler on Linux anymore
42+ let handlerMutex : NIOLockedValueBox < Handler ? >
3543 let logger : Logger
3644 let eventLoop : EventLoop
3745
@@ -42,7 +50,14 @@ public final class LambdaRuntime<Handler>: Sendable where Handler: StreamingLamb
4250 ) throws ( LambdaRuntimeError) {
4351
4452 do {
45- try _singleton. withLock {
53+ // try _singleton.withLock {
54+ // let alreadyCreated = $0
55+ // guard alreadyCreated == false else {
56+ // throw LambdaRuntimeError.moreThanOneLambdaRuntimeInstance
57+ // }
58+ // $0 = true
59+ // }
60+ try _singleton. withLockedValue {
4661 let alreadyCreated = $0
4762 guard alreadyCreated == false else {
4863 throw LambdaRuntimeError . moreThanOneLambdaRuntimeInstance
@@ -55,7 +70,7 @@ public final class LambdaRuntime<Handler>: Sendable where Handler: StreamingLamb
5570 fatalError ( " An unknown error occurred: \( error) " )
5671 }
5772
58- self . handlerMutex = Mutex ( handler)
73+ self . handlerMutex = NIOLockedValueBox ( handler)
5974 self . eventLoop = eventLoop
6075
6176 // by setting the log level here, we understand it can not be changed dynamically at runtime
@@ -68,7 +83,7 @@ public final class LambdaRuntime<Handler>: Sendable where Handler: StreamingLamb
6883 }
6984
7085 public func run( ) async throws {
71- let handler = self . handlerMutex. withLock { handler in
86+ let handler = self . handlerMutex. withLockedValue { handler in
7287 let result = handler
7388 handler = nil
7489 return result
0 commit comments