-
Notifications
You must be signed in to change notification settings - Fork 149
[IO_URING] Add support for pollAdd operation
#273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
ab11b74
e4b352c
e775d1b
2a069e4
dd53132
27b4a4a
6baba54
5b7e24a
75c85d4
2e81d94
bed8e28
0ecb080
bd49600
980a71f
a2ca84e
4df226b
a6d4c15
d4373e3
6e3259a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| /* | ||
| This source file is part of the Swift System open source project | ||
|
|
||
| Copyright (c) 2026 Apple Inc. and the Swift System project authors | ||
| Licensed under Apache License v2.0 with Runtime Library Exception | ||
|
|
||
| See https://swift.org/LICENSE.txt for license information | ||
| */ | ||
|
|
||
| #if compiler(>=6.2) && $Lifetimes | ||
| #if os(Linux) | ||
| extension IORing.Request { | ||
| /// A set of I/O events that can be monitored on a file descriptor. | ||
| /// | ||
| /// `PollEvents` represents the event mask used with io_uring poll | ||
| /// operations to specify which I/O conditions to monitor on a file | ||
| /// descriptor. These events correspond to the standard POSIX poll events | ||
| /// defined in the kernel's `poll.h` header. | ||
| /// | ||
| /// Use `PollEvents` with | ||
| /// ``IORing/Request/pollAdd(_:pollEvents:isMultiShot:context:)`` to | ||
| /// register interest in specific I/O events. The poll operation completes | ||
| /// when any of the specified events become active on the file descriptor. | ||
| /// | ||
| /// ## Usage | ||
| /// | ||
| /// ```swift | ||
| /// // Monitor a socket for incoming data | ||
| /// let request = IORing.Request.pollAdd( | ||
| /// socketFD, | ||
| /// pollEvents: .pollIn, | ||
| /// isMultiShot: true | ||
| /// ) | ||
| /// ``` | ||
| public struct PollEvents: OptionSet, Hashable, Codable, CaseIterable { | ||
| public var rawValue: UInt32 | ||
|
|
||
| @inlinable | ||
| public init(rawValue: UInt32) { | ||
|
Catfish-Man marked this conversation as resolved.
|
||
| self.rawValue = rawValue | ||
| } | ||
|
|
||
| @usableFromInline | ||
| init(_ event: Event) { | ||
| self.rawValue = event.rawValue | ||
| } | ||
|
|
||
| @usableFromInline | ||
| enum Event: UInt32, RawRepresentable, Hashable, CaseIterable { | ||
| case pollIn = 0x0001 | ||
| case pollOut = 0x0004 | ||
| case pollErr = 0x0008 | ||
| case pollHup = 0x0010 | ||
| case pollNval = 0x0020 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added cases for POLLHUP and POLLNVAL. These names are inscrutable in any situation. Should they be pollHup and pollNval, or pollHangup and pollInvalid, or hangUp and invalidDescriptor. For now I continued along with the earlier work in this PR and used what I consider to be the bad names. Missing are POLLPRI and POLLRDHUP, which would be relevant for sockets. Better names would be |
||
| } | ||
|
|
||
| public static var allCases: [PollEvents] { | ||
| Event.allCases.map(PollEvents.init(_:)) | ||
| } | ||
|
|
||
| /// An event indicating data is available for reading. | ||
| /// | ||
| /// This event becomes active when data arrives on the file descriptor | ||
| /// and can be read without blocking. For sockets, this includes when | ||
| /// a new connection is available on a listening socket. Corresponds | ||
| /// to the POSIX `POLLIN` event flag. | ||
| @inlinable | ||
| public static var pollIn: PollEvents { PollEvents(.pollIn) } | ||
|
|
||
| /// An event indicating the file descriptor is ready for writing. | ||
| /// | ||
| /// This event becomes active when writing to the file descriptor will | ||
| /// not block. For sockets, this indicates that send buffer space is | ||
| /// available. Corresponds to the POSIX `POLLOUT` event flag. | ||
| @inlinable | ||
| public static var pollOut: PollEvents { PollEvents(.pollOut) } | ||
|
|
||
| /// An event indicating an error condition on the file descriptor. | ||
| /// | ||
| /// The kernel reports this event whether or not it was requested, so | ||
| /// it can appear in a completion's result mask even when the poll | ||
| /// asked only for ``pollIn`` or ``pollOut``. Requesting it explicitly | ||
| /// has no effect. Corresponds to the POSIX `POLLERR` event flag. | ||
| @_alwaysEmitIntoClient | ||
| public static var pollErr: PollEvents { PollEvents(.pollErr) } | ||
|
|
||
| /// An event indicating the peer closed its end of the channel. | ||
| /// | ||
| /// For a pipe this means the writing end was closed; for a socket, that | ||
| /// the connection was shut down. A descriptor reporting this event will | ||
| /// never become readable again, so treating it as "not ready yet" and | ||
| /// polling again will not make progress. | ||
| /// | ||
| /// The kernel reports this event whether or not it was requested, and | ||
| /// requesting it explicitly has no effect. Corresponds to the POSIX | ||
| /// `POLLHUP` event flag. | ||
| @_alwaysEmitIntoClient | ||
| public static var pollHup: PollEvents { PollEvents(.pollHup) } | ||
|
|
||
| /// An event indicating that the object a descriptor refers to is no | ||
| /// longer valid. | ||
| /// | ||
| /// This arises when the descriptor itself resolves, but the thing it | ||
| /// refers to has since become invalid. For example, the disconnection | ||
| /// of a sound device could cause this event. | ||
| /// | ||
| /// Note that a descriptor which simply does not resolve would | ||
| /// return the EBADF error code (Errno.badFileDescriptor). | ||
| /// | ||
| /// The kernel reports this event whether or not it was requested, and | ||
| /// requesting it explicitly has no effect. Corresponds to the POSIX | ||
| /// `POLLNVAL` event flag. | ||
| @_alwaysEmitIntoClient | ||
| public static var pollNval: PollEvents { PollEvents(.pollNval) } | ||
| } | ||
| } | ||
| #endif | ||
| #endif | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typically Swift naming style would be verb-first but if there's a good reason to have it this way it's probably fine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to match what the io_uring operation was called. I wasn't sure how much we tried to change the naming to fit our Swift naming guidelines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guessed that was probably what you were doing. I remember this coming up during the initial proposal review and iirc folks leaned "don't try to make the names friendlier" so that looking up docs will work better. I'm still torn on it but I see the logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me know what you prefer and I am happy to change if needed. I am open to both.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pollAddis somewhat greppable with io_uring docs, but not directly since the names are usually something likeio_uring_prep_poll_addorIORING_OP_POLL_ADD. This is the name for the request, so maybe justpollwould be better:poll(fd, events: PollEvents, isMultiShot: Bool, context: UInt64).A future addition would be removal of events, and the constant used for that in the C library is
IORING_POLL_UPDATE_EVENTS. I don't think we would wantpollUpdateorpollRemove, maybe justupdate.