Skip to content

fix(bug): ns->us overflow handling - #1655

Draft
HalFrgrd wants to merge 2 commits into
bytecodealliance:mainfrom
HalFrgrd:main
Draft

fix(bug): ns->us overflow handling#1655
HalFrgrd wants to merge 2 commits into
bytecodealliance:mainfrom
HalFrgrd:main

Conversation

@HalFrgrd

@HalFrgrd HalFrgrd commented Aug 7, 2026

Copy link
Copy Markdown

I ran into an odd bug on macos. If my code polls for just under 5s (say 4.999_999_123 seconds), I immediately receive an EINVAL error.

I believe this is due to the rounding logic. With the current logic, we set tv_usec to 1_000_000 when the nanosecond remainder is >= 999_999_001. This creates an invalid timeval on macOS and the OS returns EINVAL.

This is a small example that I need to test on macOS:

  use rustix::event::{fd_set_insert, fd_set_num_elements, select, FdSetElement, Timespec};         
  use rustix::fd::AsRawFd;
  use rustix::pipe::pipe;

  fn main() {
      // Create a pipe so we have a valid file descriptor to pass to select()
      let (reader, _writer) = pipe().unwrap();
      let nfds = reader.as_raw_fd() + 1;
      let num_elems = fd_set_num_elements(1, nfds);

      // 1. 999_999_000 nanoseconds -> (999_999_000 + 999)/1000 = 999_999 μs (< 1,000,000 μs)      
      let mut readfds1 = vec![FdSetElement::default(); num_elems];
      fd_set_insert(&mut readfds1, &reader);
      let res1 = unsafe {
          select(
              nfds,
              Some(&mut readfds1),
              None,
              None,
              Some(&Timespec {
                  tv_sec: 0,
                  tv_nsec: 999_999_000,
              }),
          )
      };
      println!("999_999_000 ns result: {:?}", res1);

      // 2. 999_999_123 nanoseconds -> (999_999_123 + 999)/1000 = 1_000_000 μs
      let mut readfds2 = vec![FdSetElement::default(); num_elems];
      fd_set_insert(&mut readfds2, &reader);
      let res2 = unsafe {
          select(
              nfds,
              Some(&mut readfds2),
              None,
              None,
              Some(&Timespec {
                  tv_sec: 0,
                  tv_nsec: 999_999_123,
              }),
          )
      };
      println!("999_999_123 ns result: {:?}", res2); // Should show an error on macos.
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant