From patchwork Fri Jun 5 09:01:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 3941 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 74C7E61368 for ; Fri, 5 Jun 2020 11:01:25 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="mCJ23lnb"; dkim-atps=neutral Received: from emerald.amanokami.net (fs76eef344.knge213.ap.nuro.jp [118.238.243.68]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5169D27C; Fri, 5 Jun 2020 11:01:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1591347685; bh=8ue+lVlQb2TeMNQ6WnLK9Xnp+aHKtMRPuaD3Yl8Q8jU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mCJ23lnblxDiua68mcvhqH5iIMygOrlFBJlO6+vW9pYu44Qct+vgARCrIrPb4eroO m1yHWmN+uItP0WhGavSeAL7YZeDt4HhKx4tcqZP6pEIrUwQZXQlxVO0t4TvRerFaod ipPBXMMDATbanqQ03YYdNQZkmUhpoFlKmJt8LZPM= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Fri, 5 Jun 2020 18:01:05 +0900 Message-Id: <20200605090106.15424-7-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200605090106.15424-1-paul.elder@ideasonboard.com> References: <20200605090106.15424-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 6/7] v4l2: v4l2_compat: Add eventfd signaling to support polling X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Jun 2020 09:01:25 -0000 To support polling, we need to be able to signal when data is available to be read (POLLIN), as well as events (POLLPRI). Add the necessary calls to eventfd to allow signaling POLLIN. We signal POLLIN by writing writing to the eventfd, and clear it by reading from the eventfd, upon VIDIOC_DQBUF. Note that eventfd does not support signaling POLLPRI, so we don't yet support V4L2 events. Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart --- Changes in v2: use eventfd instead of socket --- src/v4l2/v4l2_camera.cpp | 9 +++++++++ src/v4l2/v4l2_camera.h | 3 +++ src/v4l2/v4l2_camera_proxy.cpp | 10 ++++++++++ src/v4l2/v4l2_camera_proxy.h | 4 ++++ src/v4l2/v4l2_compat_manager.cpp | 7 ++++++- 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp index 4da01a45..3c369328 100644 --- a/src/v4l2/v4l2_camera.cpp +++ b/src/v4l2/v4l2_camera.cpp @@ -8,6 +8,7 @@ #include "v4l2_camera.h" #include +#include #include "libcamera/internal/log.h" @@ -53,6 +54,11 @@ void V4L2Camera::close() camera_->release(); } +void V4L2Camera::bind(int efd) +{ + efd_ = efd; +} + void V4L2Camera::getStreamConfig(StreamConfiguration *streamConfig) { *streamConfig = config_->at(0); @@ -84,6 +90,9 @@ void V4L2Camera::requestComplete(Request *request) completedBuffers_.push_back(std::move(metadata)); bufferLock_.unlock(); + uint64_t data = 1; + ::write(efd_, &data, sizeof(data)); + bufferSema_.release(); } diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h index 303eda44..33f5eb02 100644 --- a/src/v4l2/v4l2_camera.h +++ b/src/v4l2/v4l2_camera.h @@ -39,6 +39,7 @@ public: int open(); void close(); + void bind(int efd); void getStreamConfig(StreamConfiguration *streamConfig); std::vector completedBuffers(); @@ -70,6 +71,8 @@ private: std::deque> pendingRequests_; std::deque> completedBuffers_; + + int efd_; }; #endif /* __V4L2_CAMERA_H__ */ diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp index cbe9e026..7ee4c0cb 100644 --- a/src/v4l2/v4l2_camera_proxy.cpp +++ b/src/v4l2/v4l2_camera_proxy.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -451,6 +452,9 @@ int V4L2CameraProxy::vidioc_dqbuf(struct v4l2_buffer *arg) currentBuf_ = (currentBuf_ + 1) % bufferCount_; + uint64_t data; + ::read(efd_, &data, sizeof(data)); + return 0; } @@ -529,6 +533,12 @@ int V4L2CameraProxy::ioctl(unsigned long request, void *arg) return ret; } +void V4L2CameraProxy::bind(int fd) +{ + efd_ = fd; + vcam_->bind(fd); +} + struct PixelFormatPlaneInfo { unsigned int bitsPerPixel; unsigned int hSubSampling; diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h index af9f9bbe..7c65c886 100644 --- a/src/v4l2/v4l2_camera_proxy.h +++ b/src/v4l2/v4l2_camera_proxy.h @@ -33,6 +33,8 @@ public: int ioctl(unsigned long request, void *arg); + void bind(int fd); + private: bool validateBufferType(uint32_t type); bool validateMemoryType(uint32_t memory); @@ -77,6 +79,8 @@ private: std::map mmaps_; std::unique_ptr vcam_; + + int efd_; }; #endif /* __V4L2_CAMERA_PROXY_H__ */ diff --git a/src/v4l2/v4l2_compat_manager.cpp b/src/v4l2/v4l2_compat_manager.cpp index 2338a0ee..56533c4f 100644 --- a/src/v4l2/v4l2_compat_manager.cpp +++ b/src/v4l2/v4l2_compat_manager.cpp @@ -155,12 +155,17 @@ int V4L2CompatManager::openat(int dirfd, const char *path, int oflag, mode_t mod if (ret < 0) return ret; - int efd = eventfd(0, oflag & (O_CLOEXEC | O_NONBLOCK)); + int efd = eventfd(0, EFD_SEMAPHORE | + ((oflag & O_CLOEXEC) ? EFD_CLOEXEC : 0) | + ((oflag & O_NONBLOCK) ? EFD_NONBLOCK : 0)); if (efd < 0) { + int err = errno; proxy->close(); + errno = err; return efd; } + proxy->bind(efd); devices_.emplace(efd, proxy); return efd;