1 import Base 2 3 # Distinguishes supported socket errors from missing host capabilities. 4 type Classification is Data: 5 UnsupportedPlatform{} 6 Transient{code: U32} 7 Host{code: U32} 8 9 # Carries the state for PollStatus. 10 type PollStatus is Data: 11 Readable{} 12 ReadableFailed{} 13 Idle{} 14 Failed{} 15 16 # Carries the state for PollFailureAction. 17 type PollFailureAction is Data: 18 Retry{} 19 Stop{} 20 21 def event.applies(connection_id: U32, event_id: U32) -> Bool: 22 U32.is_eq(connection_id, event_id) 23 24 # Classifies platform-specific errno values without performing host IO. 25 def classify_code(code: U32) -> Classification: 26 match code: 27 case 45: UnsupportedPlatform{} 28 case 78: UnsupportedPlatform{} 29 case 95: UnsupportedPlatform{} 30 case 38: UnsupportedPlatform{} 31 case 4: Transient{4} 32 case 11: Transient{11} 33 case 35: Transient{35} 34 case _: Host{code} 35 36 def poll.failure.action(classification: Classification) -> PollFailureAction: 37 match classification: 38 case Transient{_}: Retry{} 39 case _: Stop{} 40 41 def poll.failure(code: U32) -> PollFailureAction: 42 poll.failure.action(classify_code(code)) 43 44 def poll.failed(flags: U32) -> Bool: 45 Bool.not(U32.is_eq(U32.and(flags, 56), 0)) 46 47 def poll.readable(flags: U32) -> Bool: 48 Bool.not(U32.is_eq(U32.and(flags, 1), 0)) 49 50 def poll.status.readable(readable: Bool, failed: Bool) -> PollStatus: 51 match readable: 52 case True{}: 53 match failed: 54 case True{}: ReadableFailed{} 55 case False{}: Readable{} 56 case False{}: 57 match failed: 58 case True{}: Failed{} 59 case False{}: Idle{} 60 61 # Handles poll status. 62 def poll_status(+flags: U32) -> PollStatus: 63 poll.status.readable(poll.readable(flags), poll.failed(flags))