From: Bartosz Golaszewski <brgl@bgdev.pl>
To: Kent Gibson <warthog618@gmail.com>,
Linus Walleij <linus.walleij@linaro.org>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: linux-gpio@vger.kernel.org, Bartosz Golaszewski <brgl@bgdev.pl>
Subject: [libgpiod v2][PATCH] chip: don't set the request's file descriptor to non-blocking
Date: Tue, 26 Apr 2022 13:48:50 +0200 [thread overview]
Message-ID: <20220426114850.2593123-1-brgl@bgdev.pl> (raw)
Make the behavior consistent with the documentation and don't set the
line request's fd to non-blocking. Add two more test-cases that make
sure the library behaves correctly.
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
---
lib/chip.c | 23 --------
tests/tests-edge-event.c | 119 +++++++++++++++++++++++++++++++++++++++
2 files changed, 119 insertions(+), 23 deletions(-)
diff --git a/lib/chip.c b/lib/chip.c
index eef3be2..fc3dda2 100644
--- a/lib/chip.c
+++ b/lib/chip.c
@@ -181,23 +181,6 @@ GPIOD_API int gpiod_chip_get_line_offset_from_name(struct gpiod_chip *chip,
return -1;
}
-static int set_fd_noblock(int fd)
-{
- int ret, flags;
-
- flags = fcntl(fd, F_GETFL, 0);
- if (flags < 0)
- return -1;
-
- flags |= O_NONBLOCK;
-
- ret = fcntl(fd, F_SETFL, flags);
- if (ret < 0)
- return -1;
-
- return 0;
-}
-
GPIOD_API struct gpiod_line_request *
gpiod_chip_request_lines(struct gpiod_chip *chip,
struct gpiod_request_config *req_cfg,
@@ -222,12 +205,6 @@ gpiod_chip_request_lines(struct gpiod_chip *chip,
if (ret < 0)
return NULL;
- ret = set_fd_noblock(uapi_req.fd);
- if (ret) {
- close(uapi_req.fd);
- return NULL;
- }
-
request = gpiod_line_request_from_uapi(&uapi_req);
if (!request) {
close(uapi_req.fd);
diff --git a/tests/tests-edge-event.c b/tests/tests-edge-event.c
index 306383f..987155f 100644
--- a/tests/tests-edge-event.c
+++ b/tests/tests-edge-event.c
@@ -357,6 +357,75 @@ GPIOD_TEST_CASE(read_rising_edge_event_polled)
g_thread_join(thread);
}
+GPIOD_TEST_CASE(read_both_events_blocking)
+{
+ /*
+ * This time without polling so that the read gets a chance to block
+ * and we can make sure it doesn't immediately return an error.
+ */
+
+ static const guint offset = 2;
+
+ g_autoptr(GPIOSimChip) sim = g_gpiosim_chip_new("num-lines", 8, NULL);
+ g_autoptr(struct_gpiod_chip) chip = NULL;
+ g_autoptr(struct_gpiod_request_config) req_cfg = NULL;
+ g_autoptr(struct_gpiod_line_config) line_cfg = NULL;
+ g_autoptr(struct_gpiod_line_request) request = NULL;
+ g_autoptr(GThread) thread = NULL;
+ g_autoptr(struct_gpiod_edge_event_buffer) buffer = NULL;
+ struct gpiod_edge_event *event;
+ gint ret;
+
+ chip = gpiod_test_open_chip_or_fail(g_gpiosim_chip_get_dev_path(sim));
+ req_cfg = gpiod_test_create_request_config_or_fail();
+ line_cfg = gpiod_test_create_line_config_or_fail();
+ buffer = gpiod_test_create_edge_event_buffer_or_fail(64);
+
+ gpiod_request_config_set_offsets(req_cfg, 1, &offset);
+ gpiod_line_config_set_direction_default(line_cfg,
+ GPIOD_LINE_DIRECTION_INPUT);
+ gpiod_line_config_set_edge_detection_default(line_cfg,
+ GPIOD_LINE_EDGE_BOTH);
+
+ request = gpiod_test_request_lines_or_fail(chip, req_cfg, line_cfg);
+
+ thread = g_thread_new("request-release",
+ falling_and_rising_edge_events, sim);
+ g_thread_ref(thread);
+
+ /* First event. */
+
+ ret = gpiod_line_request_read_edge_event(request, buffer, 1);
+ g_assert_cmpint(ret, ==, 1);
+ gpiod_test_join_thread_and_return_if_failed(thread);
+
+ g_assert_cmpuint(gpiod_edge_event_buffer_get_num_events(buffer), ==, 1);
+ event = gpiod_edge_event_buffer_get_event(buffer, 0);
+ g_assert_nonnull(event);
+ gpiod_test_join_thread_and_return_if_failed(thread);
+
+ g_assert_cmpint(gpiod_edge_event_get_event_type(event),
+ ==, GPIOD_EDGE_EVENT_RISING_EDGE);
+ g_assert_cmpuint(gpiod_edge_event_get_line_offset(event), ==, 2);
+
+ /* Second event. */
+
+ ret = gpiod_line_request_read_edge_event(request, buffer, 1);
+ g_assert_cmpint(ret, ==, 1);
+ gpiod_test_join_thread_and_return_if_failed(thread);
+
+ g_assert_cmpuint(gpiod_edge_event_buffer_get_num_events(buffer), ==, 1);
+ event = gpiod_edge_event_buffer_get_event(buffer, 0);
+ g_assert_nonnull(event);
+ gpiod_test_join_thread_and_return_if_failed(thread);
+
+ g_assert_cmpint(gpiod_edge_event_get_event_type(event),
+ ==, GPIOD_EDGE_EVENT_FALLING_EDGE);
+ g_assert_cmpuint(gpiod_edge_event_get_line_offset(event), ==, 2);
+
+ g_thread_join(thread);
+}
+
static gpointer rising_edge_events_on_two_offsets(gpointer data)
{
GPIOSimChip *sim = data;
@@ -488,3 +557,53 @@ GPIOD_TEST_CASE(event_copy)
g_assert_nonnull(copy);
g_assert_true(copy != event);
}
+
+GPIOD_TEST_CASE(reading_more_events_than_the_queue_contains_doesnt_block)
+{
+ static const guint offset = 2;
+
+ g_autoptr(GPIOSimChip) sim = g_gpiosim_chip_new("num-lines", 8, NULL);
+ g_autoptr(struct_gpiod_chip) chip = NULL;
+ g_autoptr(struct_gpiod_request_config) req_cfg = NULL;
+ g_autoptr(struct_gpiod_line_config) line_cfg = NULL;
+ g_autoptr(struct_gpiod_line_request) request = NULL;
+ g_autoptr(GThread) thread = NULL;
+ g_autoptr(struct_gpiod_edge_event_buffer) buffer = NULL;
+ gint ret;
+
+ chip = gpiod_test_open_chip_or_fail(g_gpiosim_chip_get_dev_path(sim));
+ req_cfg = gpiod_test_create_request_config_or_fail();
+ line_cfg = gpiod_test_create_line_config_or_fail();
+ buffer = gpiod_test_create_edge_event_buffer_or_fail(64);
+
+ gpiod_request_config_set_offsets(req_cfg, 1, &offset);
+ gpiod_line_config_set_direction_default(line_cfg,
+ GPIOD_LINE_DIRECTION_INPUT);
+ gpiod_line_config_set_edge_detection_default(line_cfg,
+ GPIOD_LINE_EDGE_BOTH);
+
+ request = gpiod_test_request_lines_or_fail(chip, req_cfg, line_cfg);
+
+ g_gpiosim_chip_set_pull(sim, 2, G_GPIOSIM_PULL_UP);
+ g_usleep(500);
+ g_gpiosim_chip_set_pull(sim, 2, G_GPIOSIM_PULL_DOWN);
+ g_usleep(500);
+ g_gpiosim_chip_set_pull(sim, 2, G_GPIOSIM_PULL_UP);
+ g_usleep(500);
+ g_gpiosim_chip_set_pull(sim, 2, G_GPIOSIM_PULL_DOWN);
+ g_usleep(500);
+ g_gpiosim_chip_set_pull(sim, 2, G_GPIOSIM_PULL_UP);
+ g_usleep(500);
+ g_gpiosim_chip_set_pull(sim, 2, G_GPIOSIM_PULL_DOWN);
+ g_usleep(500);
+ g_gpiosim_chip_set_pull(sim, 2, G_GPIOSIM_PULL_UP);
+ g_usleep(500);
+
+ ret = gpiod_line_request_read_edge_event(request, buffer, 12);
+ g_assert_cmpint(ret, ==, 7);
+ gpiod_test_return_if_failed();
+
+ ret = gpiod_line_request_wait_edge_event(request, 1000);
+ g_assert_cmpint(ret, ==, 0);
+ gpiod_test_return_if_failed();
+}
--
2.32.0
next reply other threads:[~2022-04-26 11:48 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-26 11:48 Bartosz Golaszewski [this message]
2022-04-27 6:01 ` [libgpiod v2][PATCH] chip: don't set the request's file descriptor to non-blocking Kent Gibson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220426114850.2593123-1-brgl@bgdev.pl \
--to=brgl@bgdev.pl \
--cc=andriy.shevchenko@linux.intel.com \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=warthog618@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).