Skip to content

Commit c65604d

Browse files
committed
cdev: handle fast close/re-open that failed with EAGAIN
This happens with supervision tree restarts and only affects GPIOs that are listening on interrupts.
1 parent 971f11f commit c65604d

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

c_src/hal_cdev_gpio.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,10 +231,22 @@ int hal_open_gpio(struct gpio_pin *pin,
231231
int value = pin->config.is_output ? pin->config.initial_value : -1;
232232

233233
pin->fd = request_line_v2(gpiochip_fd, pin->offset, flags, value);
234+
if (pin->fd < 0) {
235+
if (pin->fd == -EBUSY) {
236+
// Handle supervision tree restart or any quick close/open restart
237+
// where the closed file descriptor hasn't been fully released by
238+
// the call to poll(3) in the interrupt thread.
239+
usleep(1000);
240+
pin->fd = request_line_v2(gpiochip_fd, pin->offset, flags, value);
241+
}
242+
if (pin->fd < 0) {
243+
error("request_line_v2 failed for %s:%d, errno=%d", pin->gpiochip, pin->offset, -pin->fd);
244+
close(gpiochip_fd);
245+
return pin->fd;
246+
}
247+
}
234248
close(gpiochip_fd);
235249
debug("requesting pin %s:%d -> %d", pin->gpiochip, pin->offset, pin->fd);
236-
if (pin->fd < 0)
237-
return pin->fd;
238250

239251
// Only call hal_apply_interrupts if there's a trigger
240252
if (pin->config.trigger != TRIGGER_NONE) {

0 commit comments

Comments
 (0)