@@ -41,7 +41,15 @@ struct Entrypoint: AsyncParsableCommand {
4141 @Option ( help: " TCP port that a debugger can connect to " )
4242 var port = 8080
4343
44- @Option ( name: . shortAndLong)
44+ @Option (
45+ name: . shortAndLong,
46+ transform: { stringValue in
47+ guard let logLevel = Logger . Level ( rawValue: stringValue. lowercased ( ) ) else {
48+ throw ValidationError ( " not a valid log level: \( stringValue) " )
49+ }
50+ return logLevel
51+ }
52+ )
4553 var logLevel = Logger . Level. info
4654
4755 @Argument
@@ -54,62 +62,61 @@ struct Entrypoint: AsyncParsableCommand {
5462 return result
5563 } ( )
5664
57- let group = MultiThreadedEventLoopGroup ( numberOfThreads: System . coreCount)
58- let bootstrap = ServerBootstrap ( group: group)
59- // Specify backlog and enable SO_REUSEADDR for the server itself
60- . serverChannelOption ( . backlog, value: 256 )
61- . serverChannelOption ( . socketOption( . so_reuseaddr) , value: 1 )
65+ try await MultiThreadedEventLoopGroup . withEventLoopGroup ( numberOfThreads: System . coreCount) { group in
66+ let bootstrap = ServerBootstrap ( group: group)
67+ // Specify backlog and enable SO_REUSEADDR for the server itself
68+ . serverChannelOption ( . backlog, value: 256 )
69+ . serverChannelOption ( . socketOption( . so_reuseaddr) , value: 1 )
6270
63- // Set the handlers that are applied to the accepted child `Channel`s.
64- . childChannelInitializer { channel in
65- // Ensure we don't read faster then we can write by adding the BackPressureHandler into the pipeline.
66- channel. eventLoop. makeCompletedFuture {
67- try channel. pipeline. syncOperations. addHandler ( BackPressureHandler ( ) )
68- // make sure to instantiate your `ChannelHandlers` inside of
69- // the closure as it will be invoked once per connection.
70- try channel. pipeline. syncOperations. addHandlers ( [
71- ByteToMessageHandler ( GDBHostCommandDecoder ( logger: logger) ) ,
72- MessageToByteHandler ( GDBTargetResponseEncoder ( ) ) ,
73- ] )
71+ // Set the handlers that are applied to the accepted child `Channel`s.
72+ . childChannelInitializer { channel in
73+ // Ensure we don't read faster then we can write by adding the BackPressureHandler into the pipeline.
74+ channel. eventLoop. makeCompletedFuture {
75+ try channel. pipeline. syncOperations. addHandler ( BackPressureHandler ( ) )
76+ // make sure to instantiate your `ChannelHandlers` inside of
77+ // the closure as it will be invoked once per connection.
78+ try channel. pipeline. syncOperations. addHandlers ( [
79+ ByteToMessageHandler ( GDBHostCommandDecoder ( logger: logger) ) ,
80+ MessageToByteHandler ( GDBTargetResponseEncoder ( ) ) ,
81+ ] )
82+ }
7483 }
75- }
7684
77- // Enable SO_REUSEADDR for the accepted Channels
78- . childChannelOption ( . socketOption( . so_reuseaddr) , value: 1 )
79- . childChannelOption ( . maxMessagesPerRead, value: 16 )
80- . childChannelOption ( . recvAllocator, value: AdaptiveRecvByteBufferAllocator ( ) )
85+ // Enable SO_REUSEADDR for the accepted Channels
86+ . childChannelOption ( . socketOption( . so_reuseaddr) , value: 1 )
87+ . childChannelOption ( . maxMessagesPerRead, value: 16 )
88+ . childChannelOption ( . recvAllocator, value: AdaptiveRecvByteBufferAllocator ( ) )
8189
82- let serverChannel = try await bootstrap. bind ( host: " 127.0.0.1 " , port: port) { childChannel in
83- childChannel. eventLoop. makeCompletedFuture {
84- try NIOAsyncChannel < GDBPacket < GDBHostCommand > , GDBTargetResponse > (
85- wrappingChannelSynchronously: childChannel
86- )
90+ let serverChannel = try await bootstrap. bind ( host: " 127.0.0.1 " , port: port) { childChannel in
91+ childChannel. eventLoop. makeCompletedFuture {
92+ try NIOAsyncChannel < GDBPacket < GDBHostCommand > , GDBTargetResponse > (
93+ wrappingChannelSynchronously: childChannel
94+ )
95+ }
8796 }
88- }
89- /* the server will now be accepting connections */
90- logger. info ( " listening on port \( port) " )
97+ /* the server will now be accepting connections */
98+ logger. info ( " listening on port \( port) " )
9199
92- let debugger = try WasmKitDebugger ( logger: logger, moduleFilePath: self . wasmModulePath)
100+ let debugger = try WasmKitDebugger ( logger: logger, moduleFilePath: self . wasmModulePath)
93101
94- try await withThrowingDiscardingTaskGroup { group in
95- try await serverChannel. executeThenClose { serverChannelInbound in
96- for try await connectionChannel in serverChannelInbound {
97- group. addTask {
98- do {
99- try await connectionChannel. executeThenClose { connectionChannelInbound, connectionChannelOutbound in
100- for try await inboundData in connectionChannelInbound {
101- // Let's echo back all inbound data
102- try await connectionChannelOutbound. write ( debugger. handle ( command: inboundData. payload) )
102+ try await withThrowingDiscardingTaskGroup { group in
103+ try await serverChannel. executeThenClose { serverChannelInbound in
104+ for try await connectionChannel in serverChannelInbound {
105+ group. addTask {
106+ do {
107+ try await connectionChannel. executeThenClose { connectionChannelInbound, connectionChannelOutbound in
108+ for try await inboundData in connectionChannelInbound {
109+ // Let's echo back all inbound data
110+ try await connectionChannelOutbound. write ( debugger. handle ( command: inboundData. payload) )
111+ }
103112 }
113+ } catch {
114+ logger. error ( " Error in GDB remote protocol connection channel " , metadata: [ " error " : " \( error) " ] )
104115 }
105- } catch {
106- logger. error ( " Error in GDB remote protocol connection channel " , metadata: [ " error " : " \( error) " ] )
107116 }
108117 }
109118 }
110119 }
111120 }
112-
113- try await group. shutdownGracefully ( )
114121 }
115122}
0 commit comments