libcamera: media_device: Manage fd by UniqueFD

Manages a file descriptor owned by MediaDevice for a media device
node by UniqueFD.

Signed-off-by: Hirokazu Honda <hiroh@chromium.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
Hirokazu Honda 2021-06-10 16:50:22 +09:00 committed by Laurent Pinchart
parent c49e888848
commit 91dcd719d7
2 changed files with 17 additions and 22 deletions

View file

@ -16,6 +16,7 @@
#include <libcamera/base/log.h> #include <libcamera/base/log.h>
#include <libcamera/base/signal.h> #include <libcamera/base/signal.h>
#include <libcamera/base/unique_fd.h>
#include "libcamera/internal/media_object.h" #include "libcamera/internal/media_object.h"
@ -82,7 +83,7 @@ private:
unsigned int version_; unsigned int version_;
unsigned int hwRevision_; unsigned int hwRevision_;
int fd_; UniqueFD fd_;
bool valid_; bool valid_;
bool acquired_; bool acquired_;
bool lockOwner_; bool lockOwner_;

View file

@ -63,15 +63,14 @@ 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), fd_(-1), valid_(false), acquired_(false), : deviceNode_(deviceNode), valid_(false), acquired_(false),
lockOwner_(false) lockOwner_(false)
{ {
} }
MediaDevice::~MediaDevice() MediaDevice::~MediaDevice()
{ {
if (fd_ != -1) fd_.reset();
::close(fd_);
clear(); clear();
} }
@ -143,14 +142,14 @@ void MediaDevice::release()
*/ */
bool MediaDevice::lock() bool MediaDevice::lock()
{ {
if (fd_ == -1) if (!fd_.isValid())
return false; return false;
/* Do not allow nested locking in the same libcamera instance. */ /* Do not allow nested locking in the same libcamera instance. */
if (lockOwner_) if (lockOwner_)
return false; return false;
if (lockf(fd_, F_TLOCK, 0)) if (lockf(fd_.get(), F_TLOCK, 0))
return false; return false;
lockOwner_ = true; lockOwner_ = true;
@ -169,7 +168,7 @@ bool MediaDevice::lock()
*/ */
void MediaDevice::unlock() void MediaDevice::unlock()
{ {
if (fd_ == -1) if (!fd_.isValid())
return; return;
if (!lockOwner_) if (!lockOwner_)
@ -177,7 +176,7 @@ void MediaDevice::unlock()
lockOwner_ = false; lockOwner_ = false;
lockf(fd_, F_ULOCK, 0); lockf(fd_.get(), F_ULOCK, 0);
} }
/** /**
@ -220,7 +219,7 @@ int MediaDevice::populate()
return ret; return ret;
struct media_device_info info = {}; struct media_device_info info = {};
ret = ioctl(fd_, MEDIA_IOC_DEVICE_INFO, &info); ret = ioctl(fd_.get(), MEDIA_IOC_DEVICE_INFO, &info);
if (ret) { if (ret) {
ret = -errno; ret = -errno;
LOG(MediaDevice, Error) LOG(MediaDevice, Error)
@ -243,7 +242,7 @@ int MediaDevice::populate()
topology.ptr_links = reinterpret_cast<uintptr_t>(links); topology.ptr_links = reinterpret_cast<uintptr_t>(links);
topology.ptr_pads = reinterpret_cast<uintptr_t>(pads); topology.ptr_pads = reinterpret_cast<uintptr_t>(pads);
ret = ioctl(fd_, MEDIA_IOC_G_TOPOLOGY, &topology); ret = ioctl(fd_.get(), MEDIA_IOC_G_TOPOLOGY, &topology);
if (ret < 0) { if (ret < 0) {
ret = -errno; ret = -errno;
LOG(MediaDevice, Error) LOG(MediaDevice, Error)
@ -481,20 +480,19 @@ int MediaDevice::disableLinks()
*/ */
int MediaDevice::open() int MediaDevice::open()
{ {
if (fd_ != -1) { if (fd_.isValid()) {
LOG(MediaDevice, Error) << "MediaDevice already open"; LOG(MediaDevice, Error) << "MediaDevice already open";
return -EBUSY; return -EBUSY;
} }
int ret = ::open(deviceNode_.c_str(), O_RDWR); fd_ = UniqueFD(::open(deviceNode_.c_str(), O_RDWR));
if (ret < 0) { if (!fd_.isValid()) {
ret = -errno; int ret = -errno;
LOG(MediaDevice, Error) LOG(MediaDevice, Error)
<< "Failed to open media device at " << "Failed to open media device at "
<< deviceNode_ << ": " << strerror(-ret); << deviceNode_ << ": " << strerror(-ret);
return ret; return ret;
} }
fd_ = ret;
return 0; return 0;
} }
@ -514,11 +512,7 @@ int MediaDevice::open()
*/ */
void MediaDevice::close() void MediaDevice::close()
{ {
if (fd_ == -1) fd_.reset();
return;
::close(fd_);
fd_ = -1;
} }
/** /**
@ -756,7 +750,7 @@ void MediaDevice::fixupEntityFlags(struct media_v2_entity *entity)
struct media_entity_desc desc = {}; struct media_entity_desc desc = {};
desc.id = entity->id; desc.id = entity->id;
int ret = ioctl(fd_, MEDIA_IOC_ENUM_ENTITIES, &desc); int ret = ioctl(fd_.get(), MEDIA_IOC_ENUM_ENTITIES, &desc);
if (ret < 0) { if (ret < 0) {
ret = -errno; ret = -errno;
LOG(MediaDevice, Debug) LOG(MediaDevice, Debug)
@ -799,7 +793,7 @@ int MediaDevice::setupLink(const MediaLink *link, unsigned int flags)
linkDesc.flags = flags; linkDesc.flags = flags;
int ret = ioctl(fd_, MEDIA_IOC_SETUP_LINK, &linkDesc); int ret = ioctl(fd_.get(), MEDIA_IOC_SETUP_LINK, &linkDesc);
if (ret) { if (ret) {
ret = -errno; ret = -errno;
LOG(MediaDevice, Error) LOG(MediaDevice, Error)