summaryrefslogtreecommitdiff
path: root/src/v4l2/v4l2_camera_proxy.cpp
diff options
context:
space:
mode:
authorPaul Elder <paul.elder@ideasonboard.com>2020-06-24 02:41:18 +0900
committerPaul Elder <paul.elder@ideasonboard.com>2020-06-25 23:47:13 +0900
commit0952f2014d1f08d1e5228f90680af16cb66653a6 (patch)
tree755d4d2b037a6de8184da5ac8ae199197d089f2e /src/v4l2/v4l2_camera_proxy.cpp
parent12fa2fe02027a96de6adfddef01381128f23a0dd (diff)
v4l2: v4l2_camera_proxy: Serialize accesses to the proxy
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@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/v4l2/v4l2_camera_proxy.cpp')
-rw-r--r--src/v4l2/v4l2_camera_proxy.cpp21
1 files changed, 17 insertions, 4 deletions
diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
index 7579d93b..c2465701 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;
@@ -587,7 +595,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();
@@ -604,9 +613,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;
/*
@@ -701,6 +712,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;
@@ -761,7 +774,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));