1414// limitations under the License.
1515//===----------------------------------------------------------------------===//
1616
17+ #if os(Linux)
18+
1719#if canImport(Musl)
1820import Musl
21+ #elseif canImport(Glibc)
22+ import Glibc
23+ #endif
1924
25+ import CShim
2026import Foundation
2127import Synchronization
2228
29+ // On glibc, epoll constants are EPOLL_EVENTS enum values. On musl they're
30+ // plain UInt32. These helpers normalize them to UInt32/Int32.
31+ private func epollMask( _ value: UInt32 ) -> UInt32 { value }
32+ private func epollMask( _ value: Int32 ) -> UInt32 { UInt32 ( bitPattern: value) }
33+ #if canImport(Glibc)
34+ private func epollMask( _ value: EPOLL_EVENTS ) -> UInt32 { value. rawValue }
35+ private func epollFlag( _ value: EPOLL_EVENTS ) -> Int32 { Int32 ( bitPattern: value. rawValue) }
36+ #endif
37+
2338/// Register file descriptors to receive events via Linux's
2439/// epoll syscall surface.
2540public final class Epoll : Sendable {
2641 public typealias Mask = Int32
2742 public typealias Handler = ( @Sendable ( Mask ) -> Void )
2843
44+ public static let maskIn : Int32 = Int32 ( bitPattern: epollMask ( EPOLLIN) )
45+ public static let maskOut : Int32 = Int32 ( bitPattern: epollMask ( EPOLLOUT) )
46+ public static let defaultMask : Int32 = maskIn | maskOut
47+
2948 private let epollFD : Int32
3049 private let handlers = SafeMap < Int32 , Handler > ( )
3150 private let pipe = Pipe ( ) // to wake up a waiting epoll_wait
3251
3352 public init ( ) throws {
34- let efd = epoll_create1 ( EPOLL_CLOEXEC)
53+ let efd = epoll_create1 ( Int32 ( EPOLL_CLOEXEC) )
3554 guard efd > 0 else {
3655 throw POSIXError . fromErrno ( )
3756 }
@@ -41,14 +60,14 @@ public final class Epoll: Sendable {
4160
4261 public func add(
4362 _ fd: Int32 ,
44- mask: Int32 = EPOLLIN | EPOLLOUT , // HUP is always added
63+ mask: Int32 = Epoll . defaultMask ,
4564 handler: @escaping Handler
4665 ) throws {
4766 guard fcntl ( fd, F_SETFL, O_NONBLOCK) == 0 else {
4867 throw POSIXError . fromErrno ( )
4968 }
5069
51- let events = EPOLLET | UInt32 ( bitPattern: mask)
70+ let events = epollMask ( EPOLLET) | UInt32 ( bitPattern: mask)
5271
5372 var event = epoll_event ( )
5473 event. events = events
@@ -115,7 +134,7 @@ public final class Epoll: Sendable {
115134 public func delete( _ fd: Int32 ) throws {
116135 var event = epoll_event ( )
117136 let result = withUnsafeMutablePointer ( to: & event) { ptr in
118- epoll_ctl ( self . epollFD, EPOLL_CTL_DEL, fd, ptr)
137+ epoll_ctl ( self . epollFD, EPOLL_CTL_DEL, fd, ptr) as Int32
119138 }
120139 if result != 0 {
121140 if !acceptableDeletionErrno( ) {
@@ -162,20 +181,20 @@ public final class Epoll: Sendable {
162181
163182extension Epoll . Mask {
164183 public var isHangup : Bool {
165- ( self & ( EPOLLHUP | EPOLLERR) ) != 0
184+ ( self & Int32 ( bitPattern : epollMask ( EPOLLHUP) | epollMask ( EPOLLERR) ) ) != 0
166185 }
167186
168187 public var isRhangup : Bool {
169- ( self & EPOLLRDHUP) != 0
188+ ( self & Int32 ( bitPattern : epollMask ( EPOLLRDHUP) ) ) != 0
170189 }
171190
172191 public var readyToRead : Bool {
173- ( self & EPOLLIN) != 0
192+ ( self & Int32 ( bitPattern : epollMask ( EPOLLIN) ) ) != 0
174193 }
175194
176195 public var readyToWrite : Bool {
177- ( self & EPOLLOUT) != 0
196+ ( self & Int32 ( bitPattern : epollMask ( EPOLLOUT) ) ) != 0
178197 }
179198}
180199
181- #endif // canImport(Musl )
200+ #endif // os(Linux )
0 commit comments