From: Bartosz Golaszewski Date: Wed, 11 Oct 2017 15:31:24 +0000 (+0200) Subject: simple-api: allow the simple event loop callback to indicate an error X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=9cbe16952f49b89bbf2c94db31ea87fea1727731;p=qemu-gpiodev%2Flibgpiod.git simple-api: allow the simple event loop callback to indicate an error 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 --- diff --git a/include/gpiod.h b/include/gpiod.h index 264c403..04f89d9 100644 --- a/include/gpiod.h +++ b/include/gpiod.h @@ -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. */ }; diff --git a/src/lib/simple.c b/src/lib/simple.c index 04fcf49..a71ea00 100644 --- a/src/lib/simple.c +++ b/src/lib/simple.c @@ -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; } diff --git a/tests/tests-simple-api.c b/tests/tests-simple-api.c index a2dbee4..bfbe626 100644 --- a/tests/tests-simple-api.c +++ b/tests/tests-simple-api.c @@ -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;