Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions FlyingSocks/Sources/Socket.swift
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,11 @@ extension Socket.Event: CustomStringConvertible {
public extension Socket.Events {
static let read: Self = [.read]
static let write: Self = [.write]
#if canImport(CSystemLinux)
static let connection: Self = [.read]
#else
static let connection: Self = [.read, .write]
#endif
}

public protocol SocketOption {
Expand Down
28 changes: 20 additions & 8 deletions FlyingSocks/Sources/SocketPool+ePoll.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,35 @@
import CSystemLinux

public extension AsyncSocketPool where Self == SocketPool<ePoll> {
static func ePoll(maxEvents limit: Int = 20, logger: some Logging = .disabled) -> SocketPool<ePoll> {
.init(maxEvents: limit, logger: logger)
static func ePoll(triggering: ePoll.TriggerMode = .edge, maxEvents limit: Int = 20, logger: some Logging = .disabled) -> SocketPool<ePoll> {
.init(triggering: triggering, maxEvents: limit, logger: logger)
}

private init(maxEvents limit: Int, logger: some Logging = .disabled) {
self.init(queue: FlyingSocks.ePoll(maxEvents: limit, logger: logger), logger: logger)
private init(triggering: ePoll.TriggerMode, maxEvents limit: Int, logger: some Logging = .disabled) {
self.init(queue: FlyingSocks.ePoll(triggering: triggering, maxEvents: limit, logger: logger), logger: logger)
}
}

public struct ePoll: EventQueue {

public enum TriggerMode: Sendable {
case edge
case level
}

private(set) var file: Socket.FileDescriptor
private(set) var canary: Socket.FileDescriptor
private(set) var existing: [Socket.FileDescriptor: Socket.Events]
private let eventsLimit: Int
private let triggerMode: TriggerMode
private let logger: any Logging

public init(maxEvents limit: Int, logger: some Logging = .disabled) {
public init(triggering: TriggerMode = .edge, maxEvents limit: Int, logger: some Logging = .disabled) {
self.file = .invalid
self.canary = .invalid
self.existing = [:]
self.eventsLimit = limit
self.triggerMode = triggering
self.logger = logger
}

Expand Down Expand Up @@ -105,8 +112,9 @@ public struct ePoll: EventQueue {
}

mutating func setEvents(_ events: Socket.Events, for socket: Socket.FileDescriptor) throws {
guard existing[socket] != events else { return }
var event = CSystemLinux.epoll_event()
event.events = events.epollEvents.rawValue
event.events = events.epollEvents(triggerMode: triggerMode).rawValue
event.data.fd = socket.rawValue

if existing[socket] != nil {
Expand Down Expand Up @@ -241,8 +249,12 @@ private struct EPOLLEvents: OptionSet, Hashable {

private extension Socket.Events {

var epollEvents: EPOLLEvents {
reduce(EPOLLEvents()) { [$0, $1.epollEvent] }
func epollEvents(triggerMode: ePoll.TriggerMode) -> EPOLLEvents {
var events = reduce(EPOLLEvents()) { [$0, $1.epollEvent] }
if triggerMode == .edge {
events.insert(.edgeTriggered)
}
return events
}

static func make(from pollevents: EPOLLEvents) -> Socket.Events {
Expand Down
6 changes: 5 additions & 1 deletion FlyingSocks/Tests/SocketPool+PollTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,11 @@ struct PollTests {
let entry = Poll.Entry(file: .init(rawValue: 30), events: .connection)

#expect(entry.pollfd.fd == 30)
#if canImport(CSystemLinux)
#expect(entry.pollfd.events == Int16(POLLIN))
#else
#expect(entry.pollfd.events == Int16(POLLOUT | POLLIN))
#endif
#expect(entry.pollfd.revents == 0)
}

Expand Down Expand Up @@ -162,7 +166,7 @@ struct PollTests {
revents: POLLHUP
)) == EventNotification(
file: .init(rawValue: 10),
events: .connection,
events: [.read, .write],
errors: [.endOfFile]
)
)
Expand Down
2 changes: 1 addition & 1 deletion FlyingSocks/Tests/SocketPoolTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ struct SocketPoolTests {
Set(waiting.continuationIDs(for: .validMock, events: .write)) == [cnWrite.id]
)
#expect(
Set(waiting.continuationIDs(for: .validMock, events: .connection)) == [cnRead1.id, cnRead.id, cnWrite.id]
Set(waiting.continuationIDs(for: .validMock, events: [.read, .write])) == [cnRead1.id, cnRead.id, cnWrite.id]
)
#expect(
Set(waiting.continuationIDs(for: .validMock, events: [])) == []
Expand Down
Loading