summaryrefslogtreecommitdiff
path: root/src/libcamera/camera.cpp
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2021-08-30 01:20:10 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2021-11-19 22:38:44 +0200
commita01007b102749caa08c1197f8ee3e1c4ed1cc530 (patch)
treec612280e2d636d0bc76484f27829c1e582eff284 /src/libcamera/camera.cpp
parentf6a5d675b1cfd1ee9cb9358526e1f84b821b9e07 (diff)
libcamera: Allow concurrent use of cameras from same pipeline handler
libcamera implements a pipeline handler locking mechanism based on advisory locks on media devices, to prevent concurrent access to cameras from the same pipeline handler from different processes (this only works between multiple libcamera instances, as other processes won't use advisory locks on media devices). A side effect of the implementation prevents multiple cameras created by the same pipeline handler from being used concurrently. Fix this by turning the PipelineHandler lock() and unlock() functions into acquire() and release(), with a use count to replace the boolean lock flag. The Camera class is updated accordingly. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/libcamera/camera.cpp')
-rw-r--r--src/libcamera/camera.cpp12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 400a7cf0..c10972cf 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -424,6 +424,11 @@ static const char *const camera_state_names[] = {
"Running",
};
+bool Camera::Private::isAcquired() const
+{
+ return state_.load(std::memory_order_acquire) == CameraRunning;
+}
+
bool Camera::Private::isRunning() const
{
return state_.load(std::memory_order_acquire) == CameraRunning;
@@ -727,7 +732,7 @@ int Camera::exportFrameBuffers(Stream *stream,
* not blocking, if the device has already been acquired (by the same or another
* process) the -EBUSY error code is returned.
*
- * Acquiring a camera will limit usage of any other camera(s) provided by the
+ * Acquiring a camera may limit usage of any other camera(s) provided by the
* same pipeline handler to the same instance of libcamera. The limit is in
* effect until all cameras from the pipeline handler are released. Other
* instances of libcamera can still list and examine the cameras but will fail
@@ -755,7 +760,7 @@ int Camera::acquire()
if (ret < 0)
return ret == -EACCES ? -EBUSY : ret;
- if (!d->pipe_->lock()) {
+ if (!d->pipe_->acquire()) {
LOG(Camera, Info)
<< "Pipeline handler in use by another process";
return -EBUSY;
@@ -789,7 +794,8 @@ int Camera::release()
if (ret < 0)
return ret == -EACCES ? -EBUSY : ret;
- d->pipe_->unlock();
+ if (d->isAcquired())
+ d->pipe_->release();
d->setState(Private::CameraAvailable);