(
&self,
timeout: OptionalArg<TimeoutArg<true>>,
vm: &VirtualMachine,
)
| 488 | |
| 489 | #[pymethod] |
| 490 | fn poll( |
| 491 | &self, |
| 492 | timeout: OptionalArg<TimeoutArg<true>>, |
| 493 | vm: &VirtualMachine, |
| 494 | ) -> PyResult<Vec<PyObjectRef>> { |
| 495 | let mut fds = self.fds.lock(); |
| 496 | let TimeoutArg(timeout) = timeout.unwrap_or_default(); |
| 497 | let timeout_ms = match timeout { |
| 498 | Some(d) => i32::try_from(d.as_millis()) |
| 499 | .map_err(|_| vm.new_overflow_error("value out of range"))?, |
| 500 | None => -1i32, |
| 501 | }; |
| 502 | let deadline = timeout.map(|d| Instant::now() + d); |
| 503 | let mut poll_timeout = timeout_ms; |
| 504 | loop { |
| 505 | let res = vm.allow_threads(|| unsafe { |
| 506 | libc::poll(fds.as_mut_ptr(), fds.len() as _, poll_timeout) |
| 507 | }); |
| 508 | match nix::Error::result(res) { |
| 509 | Ok(_) => break, |
| 510 | Err(nix::Error::EINTR) => vm.check_signals()?, |
| 511 | Err(e) => return Err(e.into_pyexception(vm)), |
| 512 | } |
| 513 | if let Some(d) = deadline { |
| 514 | if let Some(remaining) = d.checked_duration_since(Instant::now()) { |
| 515 | poll_timeout = remaining.as_millis() as i32; |
| 516 | } else { |
| 517 | break; |
| 518 | } |
| 519 | } |
| 520 | } |
| 521 | Ok(fds |
| 522 | .iter() |
| 523 | .filter(|pfd| pfd.revents != 0) |
| 524 | .map(|pfd| (pfd.fd, pfd.revents & 0xfff).to_pyobject(vm)) |
| 525 | .collect()) |
| 526 | } |
| 527 | } |
| 528 | } |
| 529 |
nothing calls this directly
no test coverage detected