diff options
author | Paul Elder <paul.elder@ideasonboard.com> | 2020-06-24 02:41:18 +0900 |
---|---|---|
committer | Paul Elder <paul.elder@ideasonboard.com> | 2020-06-25 23:47:13 +0900 |
commit | 0952f2014d1f08d1e5228f90680af16cb66653a6 (patch) | |
tree | 755d4d2b037a6de8184da5ac8ae199197d089f2e /src/v4l2 | |
parent | 12fa2fe02027a96de6adfddef01381128f23a0dd (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')
-rw-r--r-- | src/v4l2/v4l2_camera_proxy.cpp | 21 | ||||
-rw-r--r-- | 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 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)); diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h index 5de2c5ae..d78a4723 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__ */ |