simple-api: allow the simple event loop callback to indicate an error
authorBartosz Golaszewski <bartekgola@gmail.com>
Wed, 11 Oct 2017 15:31:24 +0000 (17:31 +0200)
committerBartosz Golaszewski <bartekgola@gmail.com>
Wed, 11 Oct 2017 15:40:50 +0000 (17:40 +0200)
Add a new return value for the simple event loop callback which, when
returned, makes the loop function return a negative value indicating
an error.

Include new test cases.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
include/gpiod.h
src/lib/simple.c
tests/tests-simple-api.c

index 264c403e6ca99261b1efd28cbf37c8b069c0479e..04f89d94f5f69bac3dca1648022c782bd668a581 100644 (file)
@@ -150,9 +150,11 @@ enum {
  * @brief Return status values that the simple event callback can return.
  */
 enum {
+       GPIOD_SIMPLE_EVENT_CB_RET_ERR = -1,
+       /**< Stop processing events and indicate an error. */
        GPIOD_SIMPLE_EVENT_CB_RET_OK = 0,
        /**< Continue processing events. */
-       GPIOD_SIMPLE_EVENT_CB_RET_STOP,
+       GPIOD_SIMPLE_EVENT_CB_RET_STOP = 1,
        /**< Stop processing events. */
 };
 
index 04fcf49c1de0c59222ec5f80f7e18e4bf84ab352..a71ea0015a9e8850b33e16e003e7b85fd972cc3a 100644 (file)
@@ -256,7 +256,10 @@ int gpiod_simple_event_loop_multiple(const char *consumer, const char *device,
                } else if (cnt == GPIOD_SIMPLE_EVENT_POLL_RET_TIMEOUT) {
                        rv = event_cb(GPIOD_SIMPLE_EVENT_CB_TIMEOUT,
                                      0, &event.ts, data);
-                       if (rv == GPIOD_SIMPLE_EVENT_CB_RET_STOP) {
+                       if (rv == GPIOD_SIMPLE_EVENT_CB_RET_ERR) {
+                               ret = -1;
+                               goto out;
+                       } else if (rv == GPIOD_SIMPLE_EVENT_CB_RET_STOP) {
                                ret = 0;
                                goto out;
                        }
@@ -281,8 +284,12 @@ int gpiod_simple_event_loop_multiple(const char *consumer, const char *device,
                        else
                                evtype = GPIOD_SIMPLE_EVENT_CB_FALLING_EDGE;
 
-                       rv = event_cb(evtype, gpiod_line_offset(line), &event.ts, data);
-                       if (rv == GPIOD_SIMPLE_EVENT_CB_RET_STOP) {
+                       rv = event_cb(evtype, gpiod_line_offset(line),
+                                     &event.ts, data);
+                       if (rv == GPIOD_SIMPLE_EVENT_CB_RET_ERR) {
+                               ret = -1;
+                               goto out;
+                       } else if (rv == GPIOD_SIMPLE_EVENT_CB_RET_STOP) {
                                ret = 0;
                                goto out;
                        }
index a2dbee407f55eb9967707d1902d54c95243cb44d..bfbe6262bc3feb00f9b13830d09807a10a4522da 100644 (file)
@@ -195,6 +195,48 @@ TEST_DEFINE(simple_event_loop_multiple,
            "gpiod_simple_event_loop_multiple() - single event",
            0, { 8 });
 
+static int error_event_cb(int evtype TEST_UNUSED,
+                         unsigned int offset TEST_UNUSED,
+                         const struct timespec *ts TEST_UNUSED,
+                         void *data TEST_UNUSED)
+{
+       errno = ENOTBLK;
+
+       return GPIOD_SIMPLE_EVENT_CB_RET_ERR;
+}
+
+static void simple_event_loop_indicate_error(void)
+{
+       struct timespec ts = { 1, 0 };
+       int rv;
+
+       test_set_event(0, 3, TEST_EVENT_ALTERNATING, 100);
+
+       rv = gpiod_simple_event_loop(TEST_CONSUMER, test_chip_name(0), 3,
+                                    false, &ts, NULL, error_event_cb, NULL);
+
+       TEST_ASSERT_EQ(rv, -1);
+       TEST_ASSERT_ERRNO_IS(ENOTBLK);
+}
+TEST_DEFINE(simple_event_loop_indicate_error,
+           "gpiod_simple_event_loop() - error in callback",
+           0, { 8 });
+
+static void simple_event_loop_indicate_error_timeout(void)
+{
+       struct timespec ts = { 0, 100000 };
+       int rv;
+
+       rv = gpiod_simple_event_loop(TEST_CONSUMER, test_chip_name(0), 3,
+                                    false, &ts, NULL, error_event_cb, NULL);
+
+       TEST_ASSERT_EQ(rv, -1);
+       TEST_ASSERT_ERRNO_IS(ENOTBLK);
+}
+TEST_DEFINE(simple_event_loop_indicate_error_timeout,
+           "gpiod_simple_event_loop() - error in callback after timeout",
+           0, { 8 });
+
 static void simple_find_line_good(void)
 {
        unsigned int offset;