Skip to content

Commit

Permalink
Account for man page description of POLLERR
Browse files Browse the repository at this point in the history
Summary:
This diff refers to our Poll API around sys call `poll`. We've seen a few POLLERR flags in production. The man page says:
```
       POLLERR
              Error condition (only returned in revents; ignored in
              events).  This bit is also set for a file descriptor
              referring to the write end of a pipe when the read end has
              been closed.
```
We account for that by returning `hup = true` if POLLOUT is passed and POLLERR is returned. We also don't consider it an error in that case.

Reviewed By: mheiber

Differential Revision: D66171883

fbshipit-source-id: eb7edad9149862cfb626027ea8cf328119657dc4
  • Loading branch information
Catherine Gasnier authored and facebook-github-bot committed Nov 20, 2024
1 parent d172d7a commit 7589308
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions hphp/hack/src/utils/sys/poll/poll.ml
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ module Flags = struct
in
res

let contains_error_flags flags =
IPoll.Flags.mem flags IPoll.Flags.(pollerr + pollnval + pollpri)

let error_to_string = function
| Pollerr -> "POLLERR"
| Pollnval -> "POLLNVAL"
Expand Down Expand Up @@ -102,15 +99,24 @@ let wait_fd
Ok Timeout
else
let rflags = IPoll.get_revents poll 0 in
if Flags.contains_error_flags rflags then
let pollhup = IPoll.Flags.mem rflags IPoll.Flags.pollhup in
let is_out = IPoll.Flags.mem flags IPoll.Flags.pollout in
let pollerr = IPoll.Flags.mem rflags IPoll.Flags.pollerr in
let pollpri = IPoll.Flags.mem rflags IPoll.Flags.pollpri in
let pollnval = IPoll.Flags.mem rflags IPoll.Flags.pollnval in
let hup =
pollhup
|| (* According to the poll man page, POLLERR
"is also set for a file descriptor
referring to the write end of a pipe when the read end has
been closed." *)
(pollerr && is_out)
in
let has_errors = pollpri || pollnval || (pollerr && not is_out) in
if has_errors then
Error (Flags.flags rflags)
else
Ok
(Event
{
hup = IPoll.Flags.mem rflags IPoll.Flags.pollhup;
ready = IPoll.Flags.mem rflags flags;
})
Ok (Event { hup; ready = IPoll.Flags.mem rflags flags })

let rec f_non_interrupted f x y ~timeout_ms =
let start_time = Unix.gettimeofday () in
Expand Down

0 comments on commit 7589308

Please sign in to comment.