summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libcamera/include/media_device.h4
-rw-r--r--src/libcamera/media_device.cpp59
2 files changed, 62 insertions, 1 deletions
diff --git a/src/libcamera/include/media_device.h b/src/libcamera/include/media_device.h
index e513a2fe..7b88e287 100644
--- a/src/libcamera/include/media_device.h
+++ b/src/libcamera/include/media_device.h
@@ -30,6 +30,9 @@ public:
void release();
bool busy() const { return acquired_; }
+ bool lock();
+ void unlock();
+
int populate();
bool valid() const { return valid_; }
@@ -58,6 +61,7 @@ private:
int fd_;
bool valid_;
bool acquired_;
+ bool lockOwner_;
int open();
void close();
diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp
index 62c59e7e..bd99deba 100644
--- a/src/libcamera/media_device.cpp
+++ b/src/libcamera/media_device.cpp
@@ -63,7 +63,8 @@ LOG_DEFINE_CATEGORY(MediaDevice)
* populate() before the media graph can be queried.
*/
MediaDevice::MediaDevice(const std::string &deviceNode)
- : deviceNode_(deviceNode), fd_(-1), valid_(false), acquired_(false)
+ : deviceNode_(deviceNode), fd_(-1), valid_(false), acquired_(false),
+ lockOwner_(false)
{
}
@@ -119,6 +120,62 @@ void MediaDevice::release()
}
/**
+ * \brief Lock the device to prevent it from being used by other instances of
+ * libcamera
+ *
+ * Multiple instances of libcamera might be running on the same system, at the
+ * same time. To allow the different instances to coexist, system resources in
+ * the form of media devices must be accessible for enumerating the cameras
+ * they provide at all times, while still allowing an instance to lock a
+ * resource while it prepares to actively use a camera from the resource.
+ *
+ * This method shall not be called from a pipeline handler implementation
+ * directly, as the base PipelineHandler implementation handles this on the
+ * behalf of the specified implementation.
+ *
+ * \return True if the device could be locked, false otherwise
+ * \sa unlock()
+ */
+bool MediaDevice::lock()
+{
+ if (fd_ == -1)
+ return false;
+
+ /* Do not allow nested locking in the same libcamera instance. */
+ if (lockOwner_)
+ return false;
+
+ if (lockf(fd_, F_TLOCK, 0))
+ return false;
+
+ lockOwner_ = true;
+
+ return true;
+}
+
+/**
+ * \brief Unlock the device and free it for use for libcamera instances
+ *
+ * This method shall not be called from a pipeline handler implementation
+ * directly, as the base PipelineHandler implementation handles this on the
+ * behalf of the specified implementation.
+ *
+ * \sa lock()
+ */
+void MediaDevice::unlock()
+{
+ if (fd_ == -1)
+ return;
+
+ if (!lockOwner_)
+ return;
+
+ lockOwner_ = false;
+
+ lockf(fd_, F_ULOCK, 0);
+}
+
+/**
* \fn MediaDevice::busy()
* \brief Check if a device is in use
* \return true if the device has been claimed for exclusive use, or false if it