% Generated by tinyroxygen: do not edit by hand
% Please edit documentation in later2.R
\name{later_fd}
\alias{later_fd}
\title{Executes a function when a file descriptor is ready}
\usage{
later_fd(
  func,
  readfds = integer(),
  writefds = integer(),
  exceptfds = integer(),
  timeout = Inf,
  loop = current_loop()
)
}

\arguments{
\item{func}{A function that takes a single argument, a logical vector that
  indicates which file descriptors are ready (a concatenation of `readfds`,
  `writefds` and `exceptfds`). This may be all `FALSE` if the
  `timeout` argument is non-`Inf`. File descriptors with error conditions
  pending are represented as `NA`, as are invalid file descriptors such as
  those already closed.}

\item{readfds}{Integer vector of file descriptors, or Windows SOCKETs, to
  monitor for being ready to read.}

\item{writefds}{Integer vector of file descriptors, or Windows SOCKETs, to
  monitor being ready to write.}

\item{exceptfds}{Integer vector of file descriptors, or Windows SOCKETs, to
  monitor for error conditions pending.}

\item{timeout}{Number of seconds to wait before giving up, and calling `func`
  with all `FALSE`. The default `Inf` implies waiting indefinitely.
  Specifying `0` will check once without blocking, and supplying a negative
  value defaults to a timeout of 1s.}

\item{loop}{A handle to an event loop. Defaults to the currently-active loop.}
}

\value{
A delayed function evaluation.
}

\description{
Schedule an R function or formula to run after an indeterminate
amount of time when file descriptors are ready for reading or writing,
subject to an optional timeout.

On the occasion the system-level `poll` (on Windows `WSAPoll`) returns an
error, the callback will be made on a vector of all `NA`s. This is
indistinguishable from a case where the `poll` succeeds but there are error
conditions pending against each file descriptor. If no file descriptors are
supplied, the callback is scheduled for immediate execution and made on the
empty logical vector `logical(0)`.
}

\examples{
\dontrun{
# Unix-only example

# Use the base R 'parallel' package to fork child processes and obtain
# real, pollable file descriptors. A child's `fd` becomes ready for
# reading once the child finishes running.

# 1. timeout: prints FALSE, FALSE
job1 <- parallel::mcparallel({
  Sys.sleep(1)
  TRUE
})
job2 <- parallel::mcparallel({
  Sys.sleep(1)
  TRUE
})
fd1 <- job1$fd[1]
fd2 <- job2$fd[1]
later_fd(print, c(fd1, fd2), timeout = 0.1)
Sys.sleep(0.2)
run_now()

# 2. fd1 ready: prints TRUE, FALSE
job1 <- parallel::mcparallel(TRUE)
fd1 <- job1$fd[1]
Sys.sleep(0.1)
later_fd(print, c(fd1, fd2), timeout = 1)
Sys.sleep(0.1)
run_now()

# 3. both ready: prints TRUE, TRUE
job2 <- parallel::mcparallel(TRUE)
fd2 <- job2$fd[1]
Sys.sleep(0.1)
later_fd(print, c(fd1, fd2), timeout = 1)
Sys.sleep(0.1)
run_now()

# 4. fd2 ready: prints FALSE, TRUE
parallel::mccollect(job1)
job1 <- parallel::mcparallel({
  Sys.sleep(1)
  TRUE
})
fd1 <- job1$fd[1]
later_fd(print, c(fd1, fd2), timeout = 1)
Sys.sleep(0.1)
run_now()

# 5. fds invalid: prints NA, NA
parallel::mccollect(job1)
parallel::mccollect(job2)
later_fd(print, c(fd1, fd2), timeout = 0)
Sys.sleep(0.1)
run_now()
}
}

