From dff95acd106953c36ec7b4512af33d04a5037bcf Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Tue, 14 Sep 2021 03:21:29 +0800 Subject: [PATCH] retry ioctls while errno == EINTR (#191) --- visionipc/visionbuf_ion.cc | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/visionipc/visionbuf_ion.cc b/visionipc/visionbuf_ion.cc index 60f7c66..2ed2d34 100644 --- a/visionipc/visionbuf_ion.cc +++ b/visionipc/visionbuf_ion.cc @@ -15,6 +15,16 @@ #include "visionbuf.h" +// keep trying if x gets interrupted by a signal +#define HANDLE_EINTR(x) \ + ({ \ + decltype(x) ret; \ + int try_cnt = 0; \ + do { \ + ret = (x); \ + } while (ret == -1 && errno == EINTR && try_cnt++ < 100); \ + ret; \ + }) // just hard-code these for convenience // size_t device_page_size = 0; @@ -47,12 +57,12 @@ void VisionBuf::allocate(size_t len) { ion_alloc.heap_id_mask = 1 << ION_IOMMU_HEAP_ID; ion_alloc.flags = ION_FLAG_CACHED; - err = ioctl(ion_fd, ION_IOC_ALLOC, &ion_alloc); + err = HANDLE_EINTR(ioctl(ion_fd, ION_IOC_ALLOC, &ion_alloc)); assert(err == 0); struct ion_fd_data ion_fd_data = {0}; ion_fd_data.handle = ion_alloc.handle; - err = ioctl(ion_fd, ION_IOC_SHARE, &ion_fd_data); + err = HANDLE_EINTR(ioctl(ion_fd, ION_IOC_SHARE, &ion_fd_data)); assert(err == 0); void *addr = mmap(NULL, ion_alloc.len, @@ -78,7 +88,7 @@ void VisionBuf::import(){ // Get handle struct ion_fd_data fd_data = {0}; fd_data.fd = this->fd; - err = ioctl(ion_fd, ION_IOC_IMPORT, &fd_data); + err = HANDLE_EINTR(ioctl(ion_fd, ION_IOC_IMPORT, &fd_data)); assert(err == 0); this->handle = fd_data.handle; @@ -122,7 +132,7 @@ int VisionBuf::sync(int dir) { ION_IOC_INV_CACHES : ION_IOC_CLEAN_CACHES; custom_data.arg = (unsigned long)&flush_data; - return ioctl(ion_fd, ION_IOC_CUSTOM, &custom_data); + return HANDLE_EINTR(ioctl(ion_fd, ION_IOC_CUSTOM, &custom_data)); } int VisionBuf::free() { @@ -140,5 +150,5 @@ int VisionBuf::free() { if (err != 0) return err; struct ion_handle_data handle_data = {.handle = this->handle}; - return ioctl(ion_fd, ION_IOC_FREE, &handle_data); + return HANDLE_EINTR(ioctl(ion_fd, ION_IOC_FREE, &handle_data)); }