All polling system calls have some way of being instructed to block indefinitely until some event is registered on the file descriptor. Make both the gpiod_chip_wait_info_event() and gpiod_line_request_wait_edge_event() accept negative timeout values in which case the underlying ppoll() will block indefinitely. Signed-off-by: Bartosz Golaszewski <brgl@xxxxxxxx> --- include/gpiod.h | 14 ++++++++++---- lib/chip.c | 2 +- lib/internal.c | 10 ++++++---- lib/internal.h | 2 +- lib/line-request.c | 2 +- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/include/gpiod.h b/include/gpiod.h index 5595ff2..d8b5f39 100644 --- a/include/gpiod.h +++ b/include/gpiod.h @@ -135,11 +135,14 @@ int gpiod_chip_get_fd(struct gpiod_chip *chip); * @brief Wait for line status change events on any of the watched lines * on the chip. * @param chip GPIO chip object. - * @param timeout_ns Wait time limit in nanoseconds. + * @param timeout_ns Wait time limit in nanoseconds. If set to 0, the function + * returns immediatelly. If set to a negative number, the + * function blocks indefinitely until an event becomes + * available. * @return 0 if wait timed out, -1 if an error occurred, 1 if an event is * pending. */ -int gpiod_chip_wait_info_event(struct gpiod_chip *chip, uint64_t timeout_ns); +int gpiod_chip_wait_info_event(struct gpiod_chip *chip, int64_t timeout_ns); /** * @brief Read a single line status change event from the chip. @@ -1320,7 +1323,10 @@ int gpiod_line_request_get_fd(struct gpiod_line_request *request); /** * @brief Wait for edge events on any of the requested lines. * @param request GPIO line request. - * @param timeout_ns Wait time limit in nanoseconds. + * @param timeout_ns Wait time limit in nanoseconds. If set to 0, the function + * returns immediatelly. If set to a negative number, the + * function blocks indefinitely until an event becomes + * available. * @return 0 if wait timed out, -1 if an error occurred, 1 if an event is * pending. *q @@ -1328,7 +1334,7 @@ int gpiod_line_request_get_fd(struct gpiod_line_request *request); * By default edge detection is disabled. */ int gpiod_line_request_wait_edge_event(struct gpiod_line_request *request, - uint64_t timeout_ns); + int64_t timeout_ns); /** * @brief Read a number of edge events from a line request. diff --git a/lib/chip.c b/lib/chip.c index fc3dda2..038d3dd 100644 --- a/lib/chip.c +++ b/lib/chip.c @@ -145,7 +145,7 @@ GPIOD_API int gpiod_chip_get_fd(struct gpiod_chip *chip) } GPIOD_API int gpiod_chip_wait_info_event(struct gpiod_chip *chip, - uint64_t timeout_ns) + int64_t timeout_ns) { return gpiod_poll_fd(chip->fd, timeout_ns); } diff --git a/lib/internal.c b/lib/internal.c index b7da67e..d948814 100644 --- a/lib/internal.c +++ b/lib/internal.c @@ -7,7 +7,7 @@ #include "internal.h" -int gpiod_poll_fd(int fd, uint64_t timeout_ns) +int gpiod_poll_fd(int fd, int64_t timeout_ns) { struct timespec ts; struct pollfd pfd; @@ -17,10 +17,12 @@ int gpiod_poll_fd(int fd, uint64_t timeout_ns) pfd.fd = fd; pfd.events = POLLIN | POLLPRI; - ts.tv_sec = timeout_ns / 1000000000ULL; - ts.tv_nsec = timeout_ns % 1000000000ULL; + if (timeout_ns >= 0) { + ts.tv_sec = timeout_ns / 1000000000ULL; + ts.tv_nsec = timeout_ns % 1000000000ULL; + } - ret = ppoll(&pfd, 1, &ts, NULL); + ret = ppoll(&pfd, 1, timeout_ns < 0 ? NULL : &ts, NULL); if (ret < 0) return -1; else if (ret == 0) diff --git a/lib/internal.h b/lib/internal.h index c87df91..fab12c3 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -36,7 +36,7 @@ struct gpiod_info_event * gpiod_info_event_from_uapi(struct gpio_v2_line_info_changed *uapi_evt); struct gpiod_info_event *gpiod_info_event_read_fd(int fd); -int gpiod_poll_fd(int fd, uint64_t timeout); +int gpiod_poll_fd(int fd, int64_t timeout); void gpiod_line_mask_zero(uint64_t *mask); void gpiod_line_mask_fill(uint64_t *mask); diff --git a/lib/line-request.c b/lib/line-request.c index 33f7f67..04bd78d 100644 --- a/lib/line-request.c +++ b/lib/line-request.c @@ -200,7 +200,7 @@ GPIOD_API int gpiod_line_request_get_fd(struct gpiod_line_request *request) GPIOD_API int gpiod_line_request_wait_edge_event(struct gpiod_line_request *request, - uint64_t timeout_ns) + int64_t timeout_ns) { return gpiod_poll_fd(request->fd, timeout_ns); } -- 2.34.1