[libcamera-devel] [PATCH v4 22/22] v4l2: v4l2_camera_proxy: Serialize accesses to the proxy
Paul Elder
paul.elder at ideasonboard.com
Wed Jun 24 16:52:56 CEST 2020
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 <paul.elder at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
Changes in v4:
- cosmetic changes
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 3b7a6f4..6896e55 100644
--- a/src/v4l2/v4l2_camera_proxy.cpp
+++ b/src/v4l2/v4l2_camera_proxy.cpp
@@ -45,6 +45,8 @@ int V4L2CameraProxy::open(V4L2CameraFile *file)
{
LOG(V4L2Compat, Debug) << "Servicing open fd = " << file->efd();
+ MutexLocker locker(proxyMutex_);
+
if (refcount_++) {
files_.insert(file);
return 0;
@@ -79,6 +81,8 @@ void V4L2CameraProxy::close(V4L2CameraFile *file)
{
LOG(V4L2Compat, Debug) << "Servicing close fd = " << file->efd();
+ MutexLocker locker(proxyMutex_);
+
files_.erase(file);
release(file);
@@ -94,6 +98,8 @@ void *V4L2CameraProxy::mmap(void *addr, size_t length, int prot, int flags,
{
LOG(V4L2Compat, Debug) << "Servicing mmap";
+ MutexLocker locker(proxyMutex_);
+
/* \todo Validate prot and flags properly. */
if (prot != (PROT_READ | PROT_WRITE)) {
errno = EINVAL;
@@ -128,6 +134,8 @@ int V4L2CameraProxy::munmap(void *addr, size_t length)
{
LOG(V4L2Compat, Debug) << "Servicing munmap";
+ MutexLocker locker(proxyMutex_);
+
auto iter = mmaps_.find(addr);
if (iter == mmaps_.end() || length != sizeimage_) {
errno = EINVAL;
@@ -589,7 +597,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();
@@ -606,9 +615,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;
/*
@@ -703,6 +714,8 @@ const std::set<unsigned long> 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;
@@ -763,7 +776,7 @@ int V4L2CameraProxy::ioctl(V4L2CameraFile *file, unsigned long request, void *ar
ret = vidioc_qbuf(file, static_cast<struct v4l2_buffer *>(arg));
break;
case VIDIOC_DQBUF:
- ret = vidioc_dqbuf(file, static_cast<struct v4l2_buffer *>(arg));
+ ret = vidioc_dqbuf(file, static_cast<struct v4l2_buffer *>(arg), &locker);
break;
case VIDIOC_STREAMON:
ret = vidioc_streamon(file, static_cast<int *>(arg));
diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
index 5de2c5a..d78a472 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:
* will return -EBUSY.
*/
V4L2CameraFile *owner_;
+
+ /* This mutex is to serialize access to the proxy. */
+ Mutex proxyMutex_;
};
#endif /* __V4L2_CAMERA_PROXY_H__ */
--
2.27.0
More information about the libcamera-devel
mailing list