From patchwork Tue Jun 23 19:08:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 4196 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9DD28609A5 for ; Tue, 23 Jun 2020 21:09:54 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="aYFYKMfd"; dkim-atps=neutral Received: from jade.rasen.tech (unknown [IPv6:2400:4051:61:600:8147:f2a2:a8c6:9087]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D82D62A9; Tue, 23 Jun 2020 21:09:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1592939394; bh=k8o6WuWrzmBNrvXuH4vQNDxdWsdjieEbXQZDGJ4Tib8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aYFYKMfdizUdEB3LEj/WS9j4AU9LmiDaW2fM2FHpDHKnazmUj9Oj7xXEFIzQOgtQg dvILgj1TUHqiFDFUQCgU9XJmWfMf4BuKKaLeQuY8Eb+XPgCmM7enG/4E+kfuDRxadS /NQZXFDC49F8Z8z767+/CZKj8PtD4c85jipjs+ss= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Wed, 24 Jun 2020 04:08:36 +0900 Message-Id: <20200623190836.53446-23-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623190836.53446-1-paul.elder@ideasonboard.com> References: <20200623190836.53446-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 22/22] v4l2: v4l2_camera_proxy: Serialize accesses to the proxy 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: Tue, 23 Jun 2020 19:09:54 -0000 Make the V4L2 compatibility layer thread-safe by serializing accesses to the V4L2CameraProxy with a lock. Release the lock when blocking for dqbuf. Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart --- New in v3 --- src/v4l2/v4l2_camera_proxy.cpp | 21 +++++++++++++++++---- src/v4l2/v4l2_camera_proxy.h | 5 ++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp index ed3bcbc..fb3a1fc 100644 --- a/src/v4l2/v4l2_camera_proxy.cpp +++ b/src/v4l2/v4l2_camera_proxy.cpp @@ -43,6 +43,8 @@ V4L2CameraProxy::V4L2CameraProxy(unsigned int index, int V4L2CameraProxy::open(V4L2CameraFile *file) { + MutexLocker locker(proxyMutex_); + LOG(V4L2Compat, Debug) << "Servicing open fd = " << file->efd(); files_.insert(file); @@ -75,6 +77,8 @@ int V4L2CameraProxy::open(V4L2CameraFile *file) void V4L2CameraProxy::close(V4L2CameraFile *file) { + MutexLocker locker(proxyMutex_); + LOG(V4L2Compat, Debug) << "Servicing close fd = " << file->efd(); files_.erase(file); @@ -90,6 +94,8 @@ void V4L2CameraProxy::close(V4L2CameraFile *file) void *V4L2CameraProxy::mmap(void *addr, size_t length, int prot, int flags, off64_t offset) { + MutexLocker locker(proxyMutex_); + LOG(V4L2Compat, Debug) << "Servicing mmap"; /* \todo Validate prot and flags properly. */ @@ -124,6 +130,8 @@ void *V4L2CameraProxy::mmap(void *addr, size_t length, int prot, int flags, int V4L2CameraProxy::munmap(void *addr, size_t length) { + MutexLocker locker(proxyMutex_); + LOG(V4L2Compat, Debug) << "Servicing munmap"; auto iter = mmaps_.find(addr); @@ -592,7 +600,8 @@ int V4L2CameraProxy::vidioc_qbuf(V4L2CameraFile *file, struct v4l2_buffer *arg) return ret; } -int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg) +int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, + struct v4l2_buffer *arg, MutexLocker &locker) { LOG(V4L2Compat, Debug) << "Servicing vidioc_dqbuf fd = " << file->efd(); @@ -609,9 +618,11 @@ int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg) !validateMemoryType(arg->memory)) return -EINVAL; - if (!(file->nonBlocking())) + if (!(file->nonBlocking())) { + locker.unlock(); vcam_->waitForBufferAvailable(); - else if (!vcam_->isBufferAvailable()) + locker.lock(); + } else if (!vcam_->isBufferAvailable()) return -EAGAIN; /* @@ -706,6 +717,8 @@ const std::set V4L2CameraProxy::supportedIoctls_ = { int V4L2CameraProxy::ioctl(V4L2CameraFile *file, unsigned long request, void *arg) { + MutexLocker locker(proxyMutex_); + if (!arg && (_IOC_DIR(request) & _IOC_WRITE)) { errno = EFAULT; return -1; @@ -766,7 +779,7 @@ int V4L2CameraProxy::ioctl(V4L2CameraFile *file, unsigned long request, void *ar ret = vidioc_qbuf(file, static_cast(arg)); break; case VIDIOC_DQBUF: - ret = vidioc_dqbuf(file, static_cast(arg)); + ret = vidioc_dqbuf(file, static_cast(arg), locker); break; case VIDIOC_STREAMON: ret = vidioc_streamon(file, static_cast(arg)); diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h index 041f536..b6d2c2c 100644 --- a/src/v4l2/v4l2_camera_proxy.h +++ b/src/v4l2/v4l2_camera_proxy.h @@ -61,7 +61,7 @@ private: int vidioc_reqbufs(V4L2CameraFile *file, struct v4l2_requestbuffers *arg); int vidioc_querybuf(V4L2CameraFile *file, struct v4l2_buffer *arg); int vidioc_qbuf(V4L2CameraFile *file, struct v4l2_buffer *arg); - int vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg); + int vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg, MutexLocker &locker); int vidioc_streamon(V4L2CameraFile *file, int *arg); int vidioc_streamoff(V4L2CameraFile *file, int *arg); @@ -105,6 +105,9 @@ private: * g/s_priority, enum/g/s_input */ V4L2CameraFile *owner_; + + /* This mutex is to serialize access to the proxy. */ + Mutex proxyMutex_; }; #endif /* __V4L2_CAMERA_PROXY_H__ */