[libgpiod v2][PATCH] treewide: allow polling functions to block indefinitely

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux