1212//
1313//===----------------------------------------------------------------------===//
1414
15- /// A `ServerBootstrap` is an easy way to bootstrap a `ServerChannel ` when creating network servers.
15+ /// A `ServerBootstrap` is an easy way to bootstrap a `ServerSocketChannel ` when creating network servers.
1616///
1717/// Example:
1818///
@@ -63,7 +63,7 @@ public final class ServerBootstrap {
6363 /// Create a `ServerBootstrap` for the `EventLoopGroup` `group`.
6464 ///
6565 /// - parameters:
66- /// - group: The `EventLoopGroup` to use for the `ServerChannel `.
66+ /// - group: The `EventLoopGroup` to use for the `ServerSocketChannel `.
6767 public convenience init ( group: EventLoopGroup ) {
6868 self . init ( group: group, childGroup: group)
6969 }
@@ -132,12 +132,8 @@ public final class ServerBootstrap {
132132 /// - host: The host to bind on.
133133 /// - port: The port to bind on.
134134 public func bind( host: String , port: Int ) -> EventLoopFuture < Channel > {
135- let evGroup = group
136- do {
137- let address = try SocketAddress . newAddressResolving ( host: host, port: port)
138- return bind0 ( eventLoopGroup: evGroup, to: address)
139- } catch let err {
140- return evGroup. next ( ) . newFailedFuture ( error: err)
135+ return bind0 {
136+ return try SocketAddress . newAddressResolving ( host: host, port: port)
141137 }
142138 }
143139
@@ -146,54 +142,82 @@ public final class ServerBootstrap {
146142 /// - parameters:
147143 /// - address: The `SocketAddress` to bind on.
148144 public func bind( to address: SocketAddress ) -> EventLoopFuture < Channel > {
149- return bind0 ( eventLoopGroup : group , to : address)
145+ return bind0 { address }
150146 }
151147
152148 /// Bind the `ServerSocketChannel` to a UNIX Domain Socket.
153149 ///
154150 /// - parameters:
155151 /// - unixDomainSocketPath: The _Unix domain socket_ path to bind to. `unixDomainSocketPath` must not exist, it will be created by the system.
156152 public func bind( unixDomainSocketPath: String ) -> EventLoopFuture < Channel > {
157- let evGroup = group
153+ return bind0 {
154+ try SocketAddress ( unixDomainSocketPath: unixDomainSocketPath)
155+ }
156+ }
157+
158+ /// Use the existing bound socket file descriptor.
159+ ///
160+ /// - parameters:
161+ /// - descriptor: The _Unix file descriptor_ representing the bound stream socket.
162+ public func withBoundSocket( descriptor: CInt ) -> EventLoopFuture < Channel > {
163+ func makeChannel( _ eventLoop: SelectableEventLoop , _ childEventLoopGroup: EventLoopGroup ) throws -> ServerSocketChannel {
164+ return try ServerSocketChannel ( descriptor: descriptor, eventLoop: eventLoop, group: childEventLoopGroup)
165+ }
166+ return bind0 ( makeServerChannel: makeChannel) { ( eventLoop, serverChannel) in
167+ let promise : EventLoopPromise < Void > = eventLoop. newPromise ( )
168+ serverChannel. registerAlreadyConfigured0 ( promise: promise)
169+ return promise. futureResult
170+ }
171+ }
172+
173+ private func bind0( _ makeSocketAddress: ( ) throws -> SocketAddress ) -> EventLoopFuture < Channel > {
174+ let address : SocketAddress
158175 do {
159- let address = try SocketAddress ( unixDomainSocketPath: unixDomainSocketPath)
160- return bind0 ( eventLoopGroup: evGroup, to: address)
161- } catch let err {
162- return evGroup. next ( ) . newFailedFuture ( error: err)
176+ address = try makeSocketAddress ( )
177+ } catch {
178+ return group. next ( ) . newFailedFuture ( error: error)
179+ }
180+ func makeChannel( _ eventLoop: SelectableEventLoop , _ childEventLoopGroup: EventLoopGroup ) throws -> ServerSocketChannel {
181+ return try ServerSocketChannel ( eventLoop: eventLoop,
182+ group: childEventLoopGroup,
183+ protocolFamily: address. protocolFamily)
184+ }
185+ return bind0 ( makeServerChannel: makeChannel) { ( eventGroup, serverChannel) in
186+ serverChannel. registerAndDoSynchronously { serverChannel in
187+ serverChannel. bind ( to: address)
188+ }
163189 }
164190 }
165191
166- private func bind0( eventLoopGroup: EventLoopGroup , to address: SocketAddress ) -> EventLoopFuture < Channel > {
192+ private func bind0( makeServerChannel: ( _ eventLoop: SelectableEventLoop , _ childGroup: EventLoopGroup ) throws -> ServerSocketChannel , _ register: @escaping ( EventLoop , ServerSocketChannel ) -> EventLoopFuture < Void > ) -> EventLoopFuture < Channel > {
193+ let eventLoop = self . group. next ( )
167194 let childEventLoopGroup = self . childGroup
168195 let serverChannelOptions = self . serverChannelOptions
169- let eventLoop = eventLoopGroup. next ( )
170196 let serverChannelInit = self . serverChannelInit ?? { _ in eventLoop. newSucceededFuture ( result: ( ) ) }
171197 let childChannelInit = self . childChannelInit
172198 let childChannelOptions = self . childChannelOptions
173199
174- let promise : EventLoopPromise < Channel > = eventLoop . newPromise ( )
200+ let future : EventLoopFuture < Channel >
175201 do {
176- let serverChannel = try ServerSocketChannel ( eventLoop: eventLoop as! SelectableEventLoop ,
177- group: childEventLoopGroup,
178- protocolFamily: address. protocolFamily)
202+ let serverChannel = try makeServerChannel ( eventLoop as! SelectableEventLoop , childEventLoopGroup)
179203
180- serverChannelInit ( serverChannel) . then {
204+ future = serverChannelInit ( serverChannel) . then {
181205 serverChannel. pipeline. add ( handler: AcceptHandler ( childChannelInitializer: childChannelInit,
182206 childChannelOptions: childChannelOptions) )
183207 } . then {
184208 serverChannelOptions. applyAll ( channel: serverChannel)
185209 } . then {
186- serverChannel. registerAndDoSynchronously { serverChannel in
187- serverChannel. bind ( to: address)
188- }
210+ register ( eventLoop, serverChannel)
189211 } . map {
190212 serverChannel
191- } . cascade ( promise: promise)
192- } catch let err {
193- promise. fail ( error: err)
213+ }
214+ } catch {
215+ let promise : EventLoopPromise < Channel > = eventLoop. newPromise ( )
216+ promise. fail ( error: error)
217+ future = promise. futureResult
194218 }
195219
196- return promise . futureResult
220+ return future
197221 }
198222
199223 private class AcceptHandler : ChannelInboundHandler {
@@ -388,6 +412,31 @@ public final class ClientBootstrap {
388412 }
389413 }
390414
415+ /// Use the existing connected socket file descriptor.
416+ ///
417+ /// - parameters:
418+ /// - descriptor: The _Unix file descriptor_ representing the connected stream socket.
419+ /// - returns: an `EventLoopFuture<Channel>` to deliver the `Channel` immediately.
420+ public func withConnectedSocket( descriptor: CInt ) -> EventLoopFuture < Channel > {
421+ let eventLoop = group. next ( )
422+ do {
423+ let channelInitializer = self . channelInitializer ?? { _ in eventLoop. newSucceededFuture ( result: ( ) ) }
424+ let channel = try SocketChannel ( eventLoop: eventLoop as! SelectableEventLoop , descriptor: descriptor)
425+
426+ return channelInitializer ( channel) . then {
427+ self . channelOptions. applyAll ( channel: channel)
428+ } . then {
429+ let promise : EventLoopPromise < Void > = eventLoop. newPromise ( )
430+ channel. registerAlreadyConfigured0 ( promise: promise)
431+ return promise. futureResult
432+ } . map {
433+ channel
434+ }
435+ } catch {
436+ return eventLoop. newFailedFuture ( error: error)
437+ }
438+ }
439+
391440 private func execute( eventLoop: EventLoop ,
392441 protocolFamily: Int32 ,
393442 _ body: @escaping ( Channel ) -> EventLoopFuture < Void > ) -> EventLoopFuture < Channel > {
@@ -470,18 +519,29 @@ public final class DatagramBootstrap {
470519 return self
471520 }
472521
522+ /// Use the existing bound socket file descriptor.
523+ ///
524+ /// - parameters:
525+ /// - descriptor: The _Unix file descriptor_ representing the bound datagram socket.
526+ public func withBoundSocket( descriptor: CInt ) -> EventLoopFuture < Channel > {
527+ func makeChannel( _ eventLoop: SelectableEventLoop ) throws -> DatagramChannel {
528+ return try DatagramChannel ( eventLoop: eventLoop, descriptor: descriptor)
529+ }
530+ return bind0 ( makeChannel: makeChannel) { ( eventLoop, channel) in
531+ let promise : EventLoopPromise < Void > = eventLoop. newPromise ( )
532+ channel. registerAlreadyConfigured0 ( promise: promise)
533+ return promise. futureResult
534+ }
535+ }
536+
473537 /// Bind the `DatagramChannel` to `host` and `port`.
474538 ///
475539 /// - parameters:
476540 /// - host: The host to bind on.
477541 /// - port: The port to bind on.
478542 public func bind( host: String , port: Int ) -> EventLoopFuture < Channel > {
479- let evGroup = group
480- do {
481- let address = try SocketAddress . newAddressResolving ( host: host, port: port)
482- return bind0 ( eventLoopGroup: evGroup, to: address)
483- } catch let err {
484- return evGroup. next ( ) . newFailedFuture ( error: err)
543+ return bind0 {
544+ return try SocketAddress . newAddressResolving ( host: host, port: port)
485545 }
486546 }
487547
@@ -490,47 +550,60 @@ public final class DatagramBootstrap {
490550 /// - parameters:
491551 /// - address: The `SocketAddress` to bind on.
492552 public func bind( to address: SocketAddress ) -> EventLoopFuture < Channel > {
493- return bind0 ( eventLoopGroup : group , to : address)
553+ return bind0 { address }
494554 }
495555
496556 /// Bind the `DatagramChannel` to a UNIX Domain Socket.
497557 ///
498558 /// - parameters:
499559 /// - unixDomainSocketPath: The path of the UNIX Domain Socket to bind on. `path` must not exist, it will be created by the system.
500560 public func bind( unixDomainSocketPath: String ) -> EventLoopFuture < Channel > {
501- let evGroup = group
561+ return bind0 {
562+ return try SocketAddress ( unixDomainSocketPath: unixDomainSocketPath)
563+ }
564+ }
565+
566+ private func bind0( _ makeSocketAddress: ( ) throws -> SocketAddress ) -> EventLoopFuture < Channel > {
567+ let address : SocketAddress
502568 do {
503- let address = try SocketAddress ( unixDomainSocketPath: unixDomainSocketPath)
504- return bind0 ( eventLoopGroup: evGroup, to: address)
505- } catch let err {
506- return evGroup. next ( ) . newFailedFuture ( error: err)
569+ address = try makeSocketAddress ( )
570+ } catch {
571+ return group. next ( ) . newFailedFuture ( error: error)
572+ }
573+ func makeChannel( _ eventLoop: SelectableEventLoop ) throws -> DatagramChannel {
574+ return try DatagramChannel ( eventLoop: eventLoop,
575+ protocolFamily: address. protocolFamily)
576+ }
577+ return bind0 ( makeChannel: makeChannel) { ( eventLoop, channel) in
578+ channel. register ( ) . then {
579+ _ in return channel. bind ( to: address)
580+ }
507581 }
508582 }
509583
510- private func bind0( eventLoopGroup : EventLoopGroup , to address : SocketAddress ) -> EventLoopFuture < Channel > {
511- let eventLoop = eventLoopGroup . next ( )
584+ private func bind0( makeChannel : ( _ eventLoop : SelectableEventLoop ) throws -> DatagramChannel , _ registerAndBind : @escaping ( EventLoop , DatagramChannel ) -> EventLoopFuture < Void > ) -> EventLoopFuture < Channel > {
585+ let eventLoop = self . group . next ( )
512586 let channelInitializer = self . channelInitializer ?? { _ in eventLoop. newSucceededFuture ( result: ( ) ) }
513587 let channelOptions = self . channelOptions
514588
515- let promise : EventLoopPromise < Channel > = eventLoop . newPromise ( )
589+ let future : EventLoopFuture < Channel >
516590 do {
517- let channel = try DatagramChannel ( eventLoop: eventLoop as! SelectableEventLoop ,
518- protocolFamily: address. protocolFamily)
591+ let channel = try makeChannel ( eventLoop as! SelectableEventLoop )
519592
520- channelInitializer ( channel) . then {
593+ future = channelInitializer ( channel) . then {
521594 channelOptions. applyAll ( channel: channel)
522595 } . then {
523- channel. register ( )
524- } . then {
525- channel. bind ( to: address)
596+ registerAndBind ( eventLoop, channel)
526597 } . map {
527598 channel
528- } . cascade ( promise: promise)
529- } catch let err {
530- promise. fail ( error: err)
599+ }
600+ } catch {
601+ let promise : EventLoopPromise < Channel > = eventLoop. newPromise ( )
602+ promise. fail ( error: error)
603+ future = promise. futureResult
531604 }
532605
533- return promise . futureResult
606+ return future
534607 }
535608}
536609
0 commit comments