From 6c6acaa7ea1893b99adbf2becc46238e4a5c78b2 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 28 Nov 2021 05:07:54 +0200 Subject: libcamera: Move file_descriptor.h to base/ The FileDescriptor class is a generic helper that matches the criteria for the base library. Move it there. Signed-off-by: Laurent Pinchart Reviewed-by: Hirokazu Honda Reviewed-by: Jacopo Mondi --- src/ipa/raspberrypi/raspberrypi.cpp | 2 +- src/libcamera/base/file_descriptor.cpp | 272 +++++++++++++++++++++ src/libcamera/base/meson.build | 1 + src/libcamera/file_descriptor.cpp | 272 --------------------- src/libcamera/meson.build | 1 - src/libcamera/pipeline/raspberrypi/dma_heaps.h | 2 +- src/libcamera/pipeline/raspberrypi/raspberrypi.cpp | 3 +- src/libcamera/v4l2_videodevice.cpp | 3 +- src/v4l2/v4l2_camera.h | 2 +- 9 files changed, 279 insertions(+), 279 deletions(-) create mode 100644 src/libcamera/base/file_descriptor.cpp delete mode 100644 src/libcamera/file_descriptor.cpp (limited to 'src') diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index fed82e22..c6aec090 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -15,12 +15,12 @@ #include +#include #include #include #include #include -#include #include #include #include diff --git a/src/libcamera/base/file_descriptor.cpp b/src/libcamera/base/file_descriptor.cpp new file mode 100644 index 00000000..f5f87c56 --- /dev/null +++ b/src/libcamera/base/file_descriptor.cpp @@ -0,0 +1,272 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * file_descriptor.cpp - File descriptor wrapper + */ + +#include + +#include +#include +#include +#include +#include + +#include + +/** + * \file base/file_descriptor.h + * \brief File descriptor wrapper + */ + +namespace libcamera { + +LOG_DEFINE_CATEGORY(FileDescriptor) + +/** + * \class FileDescriptor + * \brief RAII-style wrapper for file descriptors + * + * The FileDescriptor class provides RAII-style lifetime management of file + * descriptors with an efficient mechanism for ownership sharing. At its core, + * an internal Descriptor object wraps a file descriptor (expressed as a signed + * integer) with an RAII-style interface. The Descriptor is then implicitly + * shared with all FileDescriptor instances constructed as copies. + * + * When constructed from a numerical file descriptor, the FileDescriptor + * instance either duplicates or takes over the file descriptor: + * + * - The FileDescriptor(const int &) constructor duplicates the numerical file + * descriptor and wraps the duplicate in a Descriptor. The caller is + * responsible for closing the original file descriptor, and the value + * returned by fd() will be different from the value passed to the + * constructor. + * + * - The FileDescriptor(int &&) constructor takes over the numerical file + * descriptor and wraps it in a Descriptor. The caller shall not touch the + * original file descriptor once the function returns, and the value returned + * by fd() will be identical to the value passed to the constructor. + * + * The copy constructor and assignment operator create copies that share the + * Descriptor, while the move versions of those functions additionally make the + * other FileDescriptor invalid. When the last FileDescriptor that references a + * Descriptor is destroyed, the file descriptor is closed. + * + * The numerical file descriptor is available through the fd() function. All + * FileDescriptor instances created as copies of a FileDescriptor will report + * the same fd() value. Callers can perform operations on the fd(), but shall + * never close it manually. + */ + +/** + * \brief Create a FileDescriptor copying a given \a fd + * \param[in] fd File descriptor + * + * Construct a FileDescriptor from a numerical file descriptor by duplicating + * the \a fd, and take ownership of the copy. The original \a fd is left + * untouched, and the caller is responsible for closing it when appropriate. + * The duplicated file descriptor will be closed automatically when all + * FileDescriptor instances that reference it are destroyed. + * + * If the \a fd is negative, the FileDescriptor is constructed as invalid and + * the fd() function will return -1. + */ +FileDescriptor::FileDescriptor(const int &fd) +{ + if (fd < 0) + return; + + fd_ = std::make_shared(fd, true); + if (fd_->fd() < 0) + fd_.reset(); +} + +/** + * \brief Create a FileDescriptor taking ownership of a given \a fd + * \param[in] fd File descriptor + * + * Construct a FileDescriptor from a numerical file descriptor by taking + * ownership of the \a fd. The original \a fd is set to -1 and shall not be + * touched by the caller anymore. In particular, the caller shall not close the + * original \a fd manually. The duplicated file descriptor will be closed + * automatically when all FileDescriptor instances that reference it are + * destroyed. + * + * If the \a fd is negative, the FileDescriptor is constructed as invalid and + * the fd() function will return -1. + */ +FileDescriptor::FileDescriptor(int &&fd) +{ + if (fd < 0) + return; + + fd_ = std::make_shared(fd, false); + /* + * The Descriptor constructor can't have failed here, as it took over + * the fd without duplicating it. Just set the original fd to -1 to + * implement move semantics. + */ + fd = -1; +} + +/** + * \brief Copy constructor, create a FileDescriptor from a copy of \a other + * \param[in] other The other FileDescriptor + * + * Copying a FileDescriptor implicitly shares ownership of the wrapped file + * descriptor. The original FileDescriptor is left untouched, and the caller is + * responsible for destroying it when appropriate. The wrapped file descriptor + * will be closed automatically when all FileDescriptor instances that + * reference it are destroyed. + */ +FileDescriptor::FileDescriptor(const FileDescriptor &other) + : fd_(other.fd_) +{ +} + +/** + * \brief Move constructor, create a FileDescriptor by taking over \a other + * \param[in] other The other FileDescriptor + * + * Moving a FileDescriptor moves the reference to the wrapped descriptor owned + * by \a other to the new FileDescriptor. The \a other FileDescriptor is + * invalidated and its fd() function will return -1. The wrapped file descriptor + * will be closed automatically when all FileDescriptor instances that + * reference it are destroyed. + */ +FileDescriptor::FileDescriptor(FileDescriptor &&other) + : fd_(std::move(other.fd_)) +{ +} + +/** + * \brief Destroy the FileDescriptor instance + * + * Destroying a FileDescriptor instance releases its reference to the wrapped + * descriptor, if any. When the last instance that references a wrapped + * descriptor is destroyed, the file descriptor is automatically closed. + */ +FileDescriptor::~FileDescriptor() +{ +} + +/** + * \brief Copy assignment operator, replace the wrapped file descriptor with a + * copy of \a other + * \param[in] other The other FileDescriptor + * + * Copying a FileDescriptor creates a new reference to the wrapped file + * descriptor owner by \a other. If \a other is invalid, *this will also be + * invalid. The original FileDescriptor is left untouched, and the caller is + * responsible for destroying it when appropriate. The wrapped file descriptor + * will be closed automatically when all FileDescriptor instances that + * reference it are destroyed. + * + * \return A reference to this FileDescriptor + */ +FileDescriptor &FileDescriptor::operator=(const FileDescriptor &other) +{ + fd_ = other.fd_; + + return *this; +} + +/** + * \brief Move assignment operator, replace the wrapped file descriptor by + * taking over \a other + * \param[in] other The other FileDescriptor + * + * Moving a FileDescriptor moves the reference to the wrapped descriptor owned + * by \a other to the new FileDescriptor. If \a other is invalid, *this will + * also be invalid. The \a other FileDescriptor is invalidated and its fd() + * function will return -1. The wrapped file descriptor will be closed + * automatically when all FileDescriptor instances that reference it are + * destroyed. + * + * \return A reference to this FileDescriptor + */ +FileDescriptor &FileDescriptor::operator=(FileDescriptor &&other) +{ + fd_ = std::move(other.fd_); + + return *this; +} + +/** + * \fn FileDescriptor::isValid() + * \brief Check if the FileDescriptor instance is valid + * \return True if the FileDescriptor is valid, false otherwise + */ + +/** + * \fn FileDescriptor::fd() + * \brief Retrieve the numerical file descriptor + * \return The numerical file descriptor, which may be -1 if the FileDescriptor + * instance is invalid + */ + +/** + * \brief Duplicate a FileDescriptor + * + * Duplicating a FileDescriptor creates a duplicate of the wrapped file + * descriptor and returns a new FileDescriptor instance that wraps the + * duplicate. The fd() function of the original and duplicate instances will + * return different values. The duplicate instance will not be affected by + * destruction of the original instance or its copies. + * + * \return A new FileDescriptor instance wrapping a duplicate of the original + * file descriptor + */ +FileDescriptor FileDescriptor::dup() const +{ + return FileDescriptor(fd()); +} + +/** + * \brief Retrieve the file descriptor inode + * + * \todo Should this move to the File class ? + * + * \return The file descriptor inode on success, or 0 on error + */ +ino_t FileDescriptor::inode() const +{ + if (!isValid()) + return 0; + + struct stat st; + int ret = fstat(fd_->fd(), &st); + if (ret < 0) { + ret = -errno; + LOG(FileDescriptor, Fatal) + << "Failed to fstat() fd: " << strerror(-ret); + return 0; + } + + return st.st_ino; +} + +FileDescriptor::Descriptor::Descriptor(int fd, bool duplicate) +{ + if (!duplicate) { + fd_ = fd; + return; + } + + /* Failing to dup() a fd should not happen and is fatal. */ + fd_ = ::dup(fd); + if (fd_ == -1) { + int ret = -errno; + LOG(FileDescriptor, Fatal) + << "Failed to dup() fd: " << strerror(-ret); + } +} + +FileDescriptor::Descriptor::~Descriptor() +{ + if (fd_ != -1) + close(fd_); +} + +} /* namespace libcamera */ diff --git a/src/libcamera/base/meson.build b/src/libcamera/base/meson.build index b93b8505..55692015 100644 --- a/src/libcamera/base/meson.build +++ b/src/libcamera/base/meson.build @@ -8,6 +8,7 @@ libcamera_base_sources = files([ 'event_dispatcher_poll.cpp', 'event_notifier.cpp', 'file.cpp', + 'file_descriptor.cpp', 'flags.cpp', 'log.cpp', 'message.cpp', diff --git a/src/libcamera/file_descriptor.cpp b/src/libcamera/file_descriptor.cpp deleted file mode 100644 index 0409c3e1..00000000 --- a/src/libcamera/file_descriptor.cpp +++ /dev/null @@ -1,272 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2019, Google Inc. - * - * file_descriptor.cpp - File descriptor wrapper - */ - -#include - -#include -#include -#include -#include -#include - -#include - -/** - * \file file_descriptor.h - * \brief File descriptor wrapper - */ - -namespace libcamera { - -LOG_DEFINE_CATEGORY(FileDescriptor) - -/** - * \class FileDescriptor - * \brief RAII-style wrapper for file descriptors - * - * The FileDescriptor class provides RAII-style lifetime management of file - * descriptors with an efficient mechanism for ownership sharing. At its core, - * an internal Descriptor object wraps a file descriptor (expressed as a signed - * integer) with an RAII-style interface. The Descriptor is then implicitly - * shared with all FileDescriptor instances constructed as copies. - * - * When constructed from a numerical file descriptor, the FileDescriptor - * instance either duplicates or takes over the file descriptor: - * - * - The FileDescriptor(const int &) constructor duplicates the numerical file - * descriptor and wraps the duplicate in a Descriptor. The caller is - * responsible for closing the original file descriptor, and the value - * returned by fd() will be different from the value passed to the - * constructor. - * - * - The FileDescriptor(int &&) constructor takes over the numerical file - * descriptor and wraps it in a Descriptor. The caller shall not touch the - * original file descriptor once the function returns, and the value returned - * by fd() will be identical to the value passed to the constructor. - * - * The copy constructor and assignment operator create copies that share the - * Descriptor, while the move versions of those functions additionally make the - * other FileDescriptor invalid. When the last FileDescriptor that references a - * Descriptor is destroyed, the file descriptor is closed. - * - * The numerical file descriptor is available through the fd() function. All - * FileDescriptor instances created as copies of a FileDescriptor will report - * the same fd() value. Callers can perform operations on the fd(), but shall - * never close it manually. - */ - -/** - * \brief Create a FileDescriptor copying a given \a fd - * \param[in] fd File descriptor - * - * Construct a FileDescriptor from a numerical file descriptor by duplicating - * the \a fd, and take ownership of the copy. The original \a fd is left - * untouched, and the caller is responsible for closing it when appropriate. - * The duplicated file descriptor will be closed automatically when all - * FileDescriptor instances that reference it are destroyed. - * - * If the \a fd is negative, the FileDescriptor is constructed as invalid and - * the fd() function will return -1. - */ -FileDescriptor::FileDescriptor(const int &fd) -{ - if (fd < 0) - return; - - fd_ = std::make_shared(fd, true); - if (fd_->fd() < 0) - fd_.reset(); -} - -/** - * \brief Create a FileDescriptor taking ownership of a given \a fd - * \param[in] fd File descriptor - * - * Construct a FileDescriptor from a numerical file descriptor by taking - * ownership of the \a fd. The original \a fd is set to -1 and shall not be - * touched by the caller anymore. In particular, the caller shall not close the - * original \a fd manually. The duplicated file descriptor will be closed - * automatically when all FileDescriptor instances that reference it are - * destroyed. - * - * If the \a fd is negative, the FileDescriptor is constructed as invalid and - * the fd() function will return -1. - */ -FileDescriptor::FileDescriptor(int &&fd) -{ - if (fd < 0) - return; - - fd_ = std::make_shared(fd, false); - /* - * The Descriptor constructor can't have failed here, as it took over - * the fd without duplicating it. Just set the original fd to -1 to - * implement move semantics. - */ - fd = -1; -} - -/** - * \brief Copy constructor, create a FileDescriptor from a copy of \a other - * \param[in] other The other FileDescriptor - * - * Copying a FileDescriptor implicitly shares ownership of the wrapped file - * descriptor. The original FileDescriptor is left untouched, and the caller is - * responsible for destroying it when appropriate. The wrapped file descriptor - * will be closed automatically when all FileDescriptor instances that - * reference it are destroyed. - */ -FileDescriptor::FileDescriptor(const FileDescriptor &other) - : fd_(other.fd_) -{ -} - -/** - * \brief Move constructor, create a FileDescriptor by taking over \a other - * \param[in] other The other FileDescriptor - * - * Moving a FileDescriptor moves the reference to the wrapped descriptor owned - * by \a other to the new FileDescriptor. The \a other FileDescriptor is - * invalidated and its fd() function will return -1. The wrapped file descriptor - * will be closed automatically when all FileDescriptor instances that - * reference it are destroyed. - */ -FileDescriptor::FileDescriptor(FileDescriptor &&other) - : fd_(std::move(other.fd_)) -{ -} - -/** - * \brief Destroy the FileDescriptor instance - * - * Destroying a FileDescriptor instance releases its reference to the wrapped - * descriptor, if any. When the last instance that references a wrapped - * descriptor is destroyed, the file descriptor is automatically closed. - */ -FileDescriptor::~FileDescriptor() -{ -} - -/** - * \brief Copy assignment operator, replace the wrapped file descriptor with a - * copy of \a other - * \param[in] other The other FileDescriptor - * - * Copying a FileDescriptor creates a new reference to the wrapped file - * descriptor owner by \a other. If \a other is invalid, *this will also be - * invalid. The original FileDescriptor is left untouched, and the caller is - * responsible for destroying it when appropriate. The wrapped file descriptor - * will be closed automatically when all FileDescriptor instances that - * reference it are destroyed. - * - * \return A reference to this FileDescriptor - */ -FileDescriptor &FileDescriptor::operator=(const FileDescriptor &other) -{ - fd_ = other.fd_; - - return *this; -} - -/** - * \brief Move assignment operator, replace the wrapped file descriptor by - * taking over \a other - * \param[in] other The other FileDescriptor - * - * Moving a FileDescriptor moves the reference to the wrapped descriptor owned - * by \a other to the new FileDescriptor. If \a other is invalid, *this will - * also be invalid. The \a other FileDescriptor is invalidated and its fd() - * function will return -1. The wrapped file descriptor will be closed - * automatically when all FileDescriptor instances that reference it are - * destroyed. - * - * \return A reference to this FileDescriptor - */ -FileDescriptor &FileDescriptor::operator=(FileDescriptor &&other) -{ - fd_ = std::move(other.fd_); - - return *this; -} - -/** - * \fn FileDescriptor::isValid() - * \brief Check if the FileDescriptor instance is valid - * \return True if the FileDescriptor is valid, false otherwise - */ - -/** - * \fn FileDescriptor::fd() - * \brief Retrieve the numerical file descriptor - * \return The numerical file descriptor, which may be -1 if the FileDescriptor - * instance is invalid - */ - -/** - * \brief Duplicate a FileDescriptor - * - * Duplicating a FileDescriptor creates a duplicate of the wrapped file - * descriptor and returns a new FileDescriptor instance that wraps the - * duplicate. The fd() function of the original and duplicate instances will - * return different values. The duplicate instance will not be affected by - * destruction of the original instance or its copies. - * - * \return A new FileDescriptor instance wrapping a duplicate of the original - * file descriptor - */ -FileDescriptor FileDescriptor::dup() const -{ - return FileDescriptor(fd()); -} - -/** - * \brief Retrieve the file descriptor inode - * - * \todo Should this move to the File class ? - * - * \return The file descriptor inode on success, or 0 on error - */ -ino_t FileDescriptor::inode() const -{ - if (!isValid()) - return 0; - - struct stat st; - int ret = fstat(fd_->fd(), &st); - if (ret < 0) { - ret = -errno; - LOG(FileDescriptor, Fatal) - << "Failed to fstat() fd: " << strerror(-ret); - return 0; - } - - return st.st_ino; -} - -FileDescriptor::Descriptor::Descriptor(int fd, bool duplicate) -{ - if (!duplicate) { - fd_ = fd; - return; - } - - /* Failing to dup() a fd should not happen and is fatal. */ - fd_ = ::dup(fd); - if (fd_ == -1) { - int ret = -errno; - LOG(FileDescriptor, Fatal) - << "Failed to dup() fd: " << strerror(-ret); - } -} - -FileDescriptor::Descriptor::~Descriptor() -{ - if (fd_ != -1) - close(fd_); -} - -} /* namespace libcamera */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index a0e3c689..2e54cc04 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -15,7 +15,6 @@ libcamera_sources = files([ 'delayed_controls.cpp', 'device_enumerator.cpp', 'device_enumerator_sysfs.cpp', - 'file_descriptor.cpp', 'formats.cpp', 'framebuffer.cpp', 'framebuffer_allocator.cpp', diff --git a/src/libcamera/pipeline/raspberrypi/dma_heaps.h b/src/libcamera/pipeline/raspberrypi/dma_heaps.h index 38dfc242..57beaeb2 100644 --- a/src/libcamera/pipeline/raspberrypi/dma_heaps.h +++ b/src/libcamera/pipeline/raspberrypi/dma_heaps.h @@ -7,7 +7,7 @@ #pragma once -#include +#include namespace libcamera { diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 7f387626..f4ddcc04 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -13,9 +13,10 @@ #include #include +#include + #include #include -#include #include #include #include diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index 4f04212d..0a85bcf6 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -22,11 +22,10 @@ #include #include +#include #include #include -#include - #include "libcamera/internal/formats.h" #include "libcamera/internal/framebuffer.h" #include "libcamera/internal/media_device.h" diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h index 9307d61d..47d2259c 100644 --- a/src/v4l2/v4l2_camera.h +++ b/src/v4l2/v4l2_camera.h @@ -10,11 +10,11 @@ #include #include +#include #include #include #include -#include #include #include -- cgit v1.2.1