Skip to content

Commit 9e08dae

Browse files
committed
Add SocketManager.listen()
1 parent 5c21c31 commit 9e08dae

4 files changed

Lines changed: 49 additions & 45 deletions

File tree

Sources/Socket/Socket.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ public struct Socket {
140140
}
141141

142142
/// Listen for connections on a socket.
143-
public func listen(backlog: Int = Self.maxSocketBacklog) throws {
144-
try fileDescriptor.listen(backlog: backlog)
143+
public func listen(backlog: Int = Self.maxSocketBacklog) async throws {
144+
try await manager.listen(backlog: backlog, for: fileDescriptor)
145145
}
146146

147147
/// Accept new socket.
@@ -208,4 +208,3 @@ public extension Socket.Event {
208208
/// Socket Event Stream
209209
typealias Stream = AsyncStream<Socket.Event>
210210
}
211-

Sources/Socket/SocketManager.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ public protocol SocketManager: AnyObject {
7171
to address: Address,
7272
for fileDescriptor: SocketDescriptor
7373
) async throws
74+
75+
/// Listen for incoming connections
76+
func listen(
77+
backlog: Int,
78+
for fileDescriptor: SocketDescriptor
79+
) async throws
7480
}
7581

7682
/// Socket Manager Configuration

Sources/Socket/SocketManager/AsyncSocketManager.swift

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -165,27 +165,24 @@ internal actor AsyncSocketManager: SocketManager {
165165
return try await socket.receiveMessage(length, fromAddressOf: addressType)
166166
}
167167

168+
nonisolated func listen(backlog: Int, for fileDescriptor: SocketDescriptor) async throws {
169+
let socket = try await self.socket(for: fileDescriptor)
170+
try await socket.listen(backlog: backlog)
171+
}
172+
168173
/// Accept a connection on a socket.
169174
nonisolated func accept(for fileDescriptor: SocketDescriptor) async throws -> SocketDescriptor {
170-
let socket = try await socket(for: fileDescriptor)
171-
let result = try await retry(sleep: state.configuration.monitorInterval) {
172-
fileDescriptor._accept(retryOnInterrupt: true)
173-
}.get()
174-
socket.continuation.yield(.connection)
175-
return result
175+
let socket = try await wait(for: .read, fileDescriptor: fileDescriptor)
176+
return try await socket.accept()
176177
}
177178

178179
/// Accept a connection on a socket.
179180
nonisolated func accept<Address: SocketAddress>(
180181
_ address: Address.Type,
181182
for fileDescriptor: SocketDescriptor
182183
) async throws -> (fileDescriptor: SocketDescriptor, address: Address) {
183-
let socket = try await socket(for: fileDescriptor)
184-
let result = try await retry(sleep: state.configuration.monitorInterval) {
185-
fileDescriptor._accept(address, retryOnInterrupt: true)
186-
}.get()
187-
socket.continuation.yield(.connection)
188-
return result
184+
let socket = try await wait(for: .read, fileDescriptor: fileDescriptor)
185+
return try await socket.accept(address)
189186
}
190187

191188
/// Initiate a connection on a socket.
@@ -224,7 +221,7 @@ private extension AsyncSocketManager {
224221
var tasks = [Task<Void, Never>]()
225222
while self.state.isMonitoring {
226223
do {
227-
tasks.reserveCapacity(state.sockets.count * 2)
224+
tasks.reserveCapacity(state.sockets.count)
228225
// poll
229226
let hasEvents = try poll(&tasks)
230227
// stop monitoring if no sockets
@@ -331,39 +328,28 @@ private extension AsyncSocketManager {
331328
}
332329

333330
func process(_ poll: SocketDescriptor.Poll, socket: AsyncSocketManager.SocketState, tasks: inout [Task<Void, Never>]) {
334-
/*
335-
let isListening = self.sockets[poll.socket]?.isListening ?? false
336-
if isListening, poll.returnedEvents.contains([.read, .write]) {
337-
event([.read, .write], notification: .connection, for: poll.socket)
338-
} else {
331+
let task = Task {
339332
if poll.returnedEvents.contains(.read) {
340-
event(.read, notification: .read, for: poll.socket)
333+
if await socket.isListening {
334+
await socket.event(.read, notification: .connection)
335+
} else {
336+
await socket.event(.read, notification: .read)
337+
}
341338
}
342339
if poll.returnedEvents.contains(.write) {
343-
event(.write, notification: .write, for: poll.socket)
340+
await socket.event(.write, notification: .write)
344341
}
345-
}*/
346-
if poll.returnedEvents.contains(.read) {
347-
let task = Task(priority: state.configuration.monitorPriority) {
348-
await socket.event(.read, notification: .read)
342+
if poll.returnedEvents.contains(.invalidRequest) {
343+
error(.badFileDescriptor, for: poll.socket)
349344
}
350-
tasks.append(task)
351-
}
352-
if poll.returnedEvents.contains(.write) {
353-
let task = Task(priority: state.configuration.monitorPriority) {
354-
await socket.event(.write, notification: .write)
345+
if poll.returnedEvents.contains(.error) {
346+
error(.connectionReset, for: poll.socket)
347+
}
348+
if poll.returnedEvents.contains(.hangup) {
349+
hangup(poll.socket)
355350
}
356-
tasks.append(task)
357-
}
358-
if poll.returnedEvents.contains(.invalidRequest) {
359-
error(.badFileDescriptor, for: poll.socket)
360-
}
361-
if poll.returnedEvents.contains(.error) {
362-
error(.connectionReset, for: poll.socket)
363-
}
364-
if poll.returnedEvents.contains(.hangup) {
365-
hangup(poll.socket)
366351
}
352+
tasks.append(task)
367353
}
368354

369355
func error(_ error: Errno, for fileDescriptor: SocketDescriptor) {
@@ -443,6 +429,19 @@ extension AsyncSocketManager.SocketState {
443429
didRead(bytesRead)
444430
return (data, address)
445431
}
432+
433+
func listen(backlog: Int) throws {
434+
try fileDescriptor.listen(backlog: backlog)
435+
isListening = true
436+
}
437+
438+
func accept() throws -> SocketDescriptor {
439+
try fileDescriptor.accept()
440+
}
441+
442+
func accept<Address: SocketAddress>(_ address: Address.Type) throws -> (SocketDescriptor, Address) {
443+
try fileDescriptor.accept(address)
444+
}
446445
}
447446

448447
fileprivate extension AsyncSocketManager.SocketState {

Tests/SocketTests/SocketTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ final class SocketTests: XCTestCase {
4949
let newConnectionTask = Task {
5050
XCTAssertEqual(try server.fileDescriptor.address(IPv4SocketAddress.self), address)
5151
NSLog("Server: Created server socket \(server.fileDescriptor)")
52-
try server.listen()
52+
try await server.listen()
5353

5454
NSLog("Server: Waiting on incoming connection")
5555
let newConnection = try await server.accept()
@@ -103,8 +103,8 @@ final class SocketTests: XCTestCase {
103103
try await Task.sleep(nanoseconds: 1_000_000_000)
104104
await client.close()
105105
let clientEvents = try await clientEventsTask.value
106-
XCTAssertEqual(clientEvents.count, 4)
107-
XCTAssertEqual("\(clientEvents)", "[Socket.Socket.Event.write, Socket.Socket.Event.read, Socket.Socket.Event.didRead(41), Socket.Socket.Event.close]")
106+
XCTAssertEqual(clientEvents.count, 5)
107+
XCTAssertEqual("\(clientEvents)", "[Socket.Socket.Event.write, Socket.Socket.Event.read, Socket.Socket.Event.didRead(41), Socket.Socket.Event.read, Socket.Socket.Event.close]")
108108
await server.close()
109109
let serverEvents = try await serverEventsTask.value
110110
XCTAssertEqual(serverEvents.count, 2)

0 commit comments

Comments
 (0)