libcamera: media_device: Move recursive lock handling to pipeline handler

The MediaDevice lock is meant to prevent concurrent usage of multiple
cameras from the same pipeline handlers. As media devices are acquired
by pipeline handlers, we can't have multiple pipeline handlers trying to
lock the same media device. The recursive locking detection can thus be
moved to the pipeline handler. This simplifies the media device
implementation that now implements true lock semantics, and prepares for
support of concurrent camera usage.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
This commit is contained in:
Laurent Pinchart 2021-08-29 21:03:23 +03:00
parent 46b32fa0e4
commit ec6921d7f7
4 changed files with 15 additions and 15 deletions

View file

@ -86,7 +86,6 @@ private:
UniqueFD fd_; UniqueFD fd_;
bool valid_; bool valid_;
bool acquired_; bool acquired_;
bool lockOwner_;
std::map<unsigned int, MediaObject *> objects_; std::map<unsigned int, MediaObject *> objects_;
std::vector<MediaEntity *> entities_; std::vector<MediaEntity *> entities_;

View file

@ -88,6 +88,8 @@ private:
const char *name_; const char *name_;
bool lockOwner_;
friend class PipelineHandlerFactory; friend class PipelineHandlerFactory;
}; };

View file

@ -63,8 +63,7 @@ LOG_DEFINE_CATEGORY(MediaDevice)
* populate() before the media graph can be queried. * populate() before the media graph can be queried.
*/ */
MediaDevice::MediaDevice(const std::string &deviceNode) MediaDevice::MediaDevice(const std::string &deviceNode)
: deviceNode_(deviceNode), valid_(false), acquired_(false), : deviceNode_(deviceNode), valid_(false), acquired_(false)
lockOwner_(false)
{ {
} }
@ -145,15 +144,9 @@ bool MediaDevice::lock()
if (!fd_.isValid()) if (!fd_.isValid())
return false; return false;
/* Do not allow nested locking in the same libcamera instance. */
if (lockOwner_)
return false;
if (lockf(fd_.get(), F_TLOCK, 0)) if (lockf(fd_.get(), F_TLOCK, 0))
return false; return false;
lockOwner_ = true;
return true; return true;
} }
@ -171,11 +164,6 @@ void MediaDevice::unlock()
if (!fd_.isValid()) if (!fd_.isValid())
return; return;
if (!lockOwner_)
return;
lockOwner_ = false;
lockf(fd_.get(), F_ULOCK, 0); lockf(fd_.get(), F_ULOCK, 0);
} }

View file

@ -67,7 +67,7 @@ LOG_DEFINE_CATEGORY(Pipeline)
* respective factories. * respective factories.
*/ */
PipelineHandler::PipelineHandler(CameraManager *manager) PipelineHandler::PipelineHandler(CameraManager *manager)
: manager_(manager) : manager_(manager), lockOwner_(false)
{ {
} }
@ -155,6 +155,10 @@ MediaDevice *PipelineHandler::acquireMediaDevice(DeviceEnumerator *enumerator,
*/ */
bool PipelineHandler::lock() bool PipelineHandler::lock()
{ {
/* Do not allow nested locking in the same libcamera instance. */
if (lockOwner_)
return false;
for (std::shared_ptr<MediaDevice> &media : mediaDevices_) { for (std::shared_ptr<MediaDevice> &media : mediaDevices_) {
if (!media->lock()) { if (!media->lock()) {
unlock(); unlock();
@ -162,6 +166,8 @@ bool PipelineHandler::lock()
} }
} }
lockOwner_ = true;
return true; return true;
} }
@ -177,8 +183,13 @@ bool PipelineHandler::lock()
*/ */
void PipelineHandler::unlock() void PipelineHandler::unlock()
{ {
if (!lockOwner_)
return;
for (std::shared_ptr<MediaDevice> &media : mediaDevices_) for (std::shared_ptr<MediaDevice> &media : mediaDevices_)
media->unlock(); media->unlock();
lockOwner_ = false;
} }
/** /**