[libcamera-devel] [PATCH v3 17/17] libcamera: base: Rename FileDescriptor to SharedFD
Hirokazu Honda
hiroh at chromium.org
Mon Nov 29 15:04:26 CET 2021
Hi Laurent,
On Mon, Nov 29, 2021 at 8:58 AM Laurent Pinchart
<laurent.pinchart at ideasonboard.com> wrote:
>
> Now that we have a UniqueFD class, the name FileDescriptor is ambiguous.
> Rename it to SharedFD.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh at chromium.org>
> ---
> include/libcamera/base/file.h | 4 +-
> include/libcamera/base/meson.build | 2 +-
> .../base/{file_descriptor.h => shared_fd.h} | 20 +-
> include/libcamera/framebuffer.h | 4 +-
> .../libcamera/internal/ipa_data_serializer.h | 40 +--
> include/libcamera/internal/ipc_pipe.h | 8 +-
> include/libcamera/ipa/core.mojom | 6 +-
> include/libcamera/ipa/raspberrypi.mojom | 2 +-
> src/android/camera_device.cpp | 2 +-
> src/ipa/raspberrypi/raspberrypi.cpp | 4 +-
> src/libcamera/base/file.cpp | 6 +-
> src/libcamera/base/file_descriptor.cpp | 266 ------------------
> src/libcamera/base/meson.build | 2 +-
> src/libcamera/base/shared_fd.cpp | 262 +++++++++++++++++
> src/libcamera/framebuffer.cpp | 6 +-
> src/libcamera/ipa_data_serializer.cpp | 100 +++----
> src/libcamera/ipc_pipe.cpp | 4 +-
> .../pipeline/raspberrypi/raspberrypi.cpp | 6 +-
> src/libcamera/v4l2_videodevice.cpp | 6 +-
> src/v4l2/v4l2_camera.h | 2 +-
> test/meson.build | 2 +-
> .../ipa_data_serializer_test.cpp | 14 +-
> test/{file-descriptor.cpp => shared-fd.cpp} | 46 +--
> .../module_ipa_proxy.cpp.tmpl | 2 +-
> .../module_ipa_proxy.h.tmpl | 2 +-
> .../libcamera_templates/proxy_functions.tmpl | 2 +-
> .../libcamera_templates/serializer.tmpl | 22 +-
> .../generators/mojom_libcamera_generator.py | 6 +-
> 28 files changed, 422 insertions(+), 426 deletions(-)
> rename include/libcamera/base/{file_descriptor.h => shared_fd.h} (55%)
> delete mode 100644 src/libcamera/base/file_descriptor.cpp
> create mode 100644 src/libcamera/base/shared_fd.cpp
> rename test/{file-descriptor.cpp => shared-fd.cpp} (80%)
>
> diff --git a/include/libcamera/base/file.h b/include/libcamera/base/file.h
> index 47769da7abc2..691b52d6ab2d 100644
> --- a/include/libcamera/base/file.h
> +++ b/include/libcamera/base/file.h
> @@ -21,7 +21,7 @@
>
> namespace libcamera {
>
> -class FileDescriptor;
> +class SharedFD;
>
> class File
> {
> @@ -69,7 +69,7 @@ public:
> bool unmap(uint8_t *addr);
>
> static bool exists(const std::string &name);
> - static ino_t inode(const FileDescriptor &fd);
> + static ino_t inode(const SharedFD &fd);
>
> private:
> LIBCAMERA_DISABLE_COPY(File)
> diff --git a/include/libcamera/base/meson.build b/include/libcamera/base/meson.build
> index cca374a769cc..112420dab225 100644
> --- a/include/libcamera/base/meson.build
> +++ b/include/libcamera/base/meson.build
> @@ -11,13 +11,13 @@ libcamera_base_headers = files([
> 'event_dispatcher_poll.h',
> 'event_notifier.h',
> 'file.h',
> - 'file_descriptor.h',
> 'flags.h',
> 'log.h',
> 'message.h',
> 'object.h',
> 'private.h',
> 'semaphore.h',
> + 'shared_fd.h',
> 'signal.h',
> 'span.h',
> 'thread.h',
> diff --git a/include/libcamera/base/file_descriptor.h b/include/libcamera/base/shared_fd.h
> similarity index 55%
> rename from include/libcamera/base/file_descriptor.h
> rename to include/libcamera/base/shared_fd.h
> index 12a43f95d414..a786885ceb32 100644
> --- a/include/libcamera/base/file_descriptor.h
> +++ b/include/libcamera/base/shared_fd.h
> @@ -2,7 +2,7 @@
> /*
> * Copyright (C) 2019, Google Inc.
> *
> - * file_descriptor.h - File descriptor wrapper
> + * shared_fd.h - File descriptor wrapper with shared ownership
> */
>
> #pragma once
> @@ -13,18 +13,18 @@ namespace libcamera {
>
> class UniqueFD;
>
> -class FileDescriptor final
> +class SharedFD final
> {
> public:
> - explicit FileDescriptor(const int &fd = -1);
> - explicit FileDescriptor(int &&fd);
> - explicit FileDescriptor(UniqueFD fd);
> - FileDescriptor(const FileDescriptor &other);
> - FileDescriptor(FileDescriptor &&other);
> - ~FileDescriptor();
> + explicit SharedFD(const int &fd = -1);
> + explicit SharedFD(int &&fd);
> + explicit SharedFD(UniqueFD fd);
> + SharedFD(const SharedFD &other);
> + SharedFD(SharedFD &&other);
> + ~SharedFD();
>
> - FileDescriptor &operator=(const FileDescriptor &other);
> - FileDescriptor &operator=(FileDescriptor &&other);
> + SharedFD &operator=(const SharedFD &other);
> + SharedFD &operator=(SharedFD &&other);
>
> bool isValid() const { return fd_ != nullptr; }
> int fd() const { return fd_ ? fd_->fd() : -1; }
> diff --git a/include/libcamera/framebuffer.h b/include/libcamera/framebuffer.h
> index 2fbea9c5be16..357bbe189551 100644
> --- a/include/libcamera/framebuffer.h
> +++ b/include/libcamera/framebuffer.h
> @@ -13,7 +13,7 @@
> #include <vector>
>
> #include <libcamera/base/class.h>
> -#include <libcamera/base/file_descriptor.h>
> +#include <libcamera/base/shared_fd.h>
> #include <libcamera/base/span.h>
>
> namespace libcamera {
> @@ -51,7 +51,7 @@ class FrameBuffer final : public Extensible
> public:
> struct Plane {
> static constexpr unsigned int kInvalidOffset = std::numeric_limits<unsigned int>::max();
> - FileDescriptor fd;
> + SharedFD fd;
> unsigned int offset = kInvalidOffset;
> unsigned int length;
> };
> diff --git a/include/libcamera/internal/ipa_data_serializer.h b/include/libcamera/internal/ipa_data_serializer.h
> index c2f602d5b7de..a87449c9be48 100644
> --- a/include/libcamera/internal/ipa_data_serializer.h
> +++ b/include/libcamera/internal/ipa_data_serializer.h
> @@ -66,7 +66,7 @@ template<typename T>
> class IPADataSerializer
> {
> public:
> - static std::tuple<std::vector<uint8_t>, std::vector<FileDescriptor>>
> + static std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
> serialize(const T &data, ControlSerializer *cs = nullptr);
>
> static T deserialize(const std::vector<uint8_t> &data,
> @@ -76,12 +76,12 @@ public:
> ControlSerializer *cs = nullptr);
>
> static T deserialize(const std::vector<uint8_t> &data,
> - const std::vector<FileDescriptor> &fds,
> + const std::vector<SharedFD> &fds,
> ControlSerializer *cs = nullptr);
> static T deserialize(std::vector<uint8_t>::const_iterator dataBegin,
> std::vector<uint8_t>::const_iterator dataEnd,
> - std::vector<FileDescriptor>::const_iterator fdsBegin,
> - std::vector<FileDescriptor>::const_iterator fdsEnd,
> + std::vector<SharedFD>::const_iterator fdsBegin,
> + std::vector<SharedFD>::const_iterator fdsEnd,
> ControlSerializer *cs = nullptr);
> };
>
> @@ -104,11 +104,11 @@ template<typename V>
> class IPADataSerializer<std::vector<V>>
> {
> public:
> - static std::tuple<std::vector<uint8_t>, std::vector<FileDescriptor>>
> + static std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
> serialize(const std::vector<V> &data, ControlSerializer *cs = nullptr)
> {
> std::vector<uint8_t> dataVec;
> - std::vector<FileDescriptor> fdsVec;
> + std::vector<SharedFD> fdsVec;
>
> /* Serialize the length. */
> uint32_t vecLen = data.size();
> @@ -117,7 +117,7 @@ public:
> /* Serialize the members. */
> for (auto const &it : data) {
> std::vector<uint8_t> dvec;
> - std::vector<FileDescriptor> fvec;
> + std::vector<SharedFD> fvec;
>
> std::tie(dvec, fvec) =
> IPADataSerializer<V>::serialize(it, cs);
> @@ -141,11 +141,11 @@ public:
> std::vector<uint8_t>::const_iterator dataEnd,
> ControlSerializer *cs = nullptr)
> {
> - std::vector<FileDescriptor> fds;
> + std::vector<SharedFD> fds;
> return deserialize(dataBegin, dataEnd, fds.cbegin(), fds.end(), cs);
> }
>
> - static std::vector<V> deserialize(std::vector<uint8_t> &data, std::vector<FileDescriptor> &fds,
> + static std::vector<V> deserialize(std::vector<uint8_t> &data, std::vector<SharedFD> &fds,
> ControlSerializer *cs = nullptr)
> {
> return deserialize(data.cbegin(), data.end(), fds.cbegin(), fds.end(), cs);
> @@ -153,15 +153,15 @@ public:
>
> static std::vector<V> deserialize(std::vector<uint8_t>::const_iterator dataBegin,
> std::vector<uint8_t>::const_iterator dataEnd,
> - std::vector<FileDescriptor>::const_iterator fdsBegin,
> - [[maybe_unused]] std::vector<FileDescriptor>::const_iterator fdsEnd,
> + std::vector<SharedFD>::const_iterator fdsBegin,
> + [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd,
> ControlSerializer *cs = nullptr)
> {
> uint32_t vecLen = readPOD<uint32_t>(dataBegin, 0, dataEnd);
> std::vector<V> ret(vecLen);
>
> std::vector<uint8_t>::const_iterator dataIter = dataBegin + 4;
> - std::vector<FileDescriptor>::const_iterator fdIter = fdsBegin;
> + std::vector<SharedFD>::const_iterator fdIter = fdsBegin;
> for (uint32_t i = 0; i < vecLen; i++) {
> uint32_t sizeofData = readPOD<uint32_t>(dataIter, 0, dataEnd);
> uint32_t sizeofFds = readPOD<uint32_t>(dataIter, 4, dataEnd);
> @@ -201,11 +201,11 @@ template<typename K, typename V>
> class IPADataSerializer<std::map<K, V>>
> {
> public:
> - static std::tuple<std::vector<uint8_t>, std::vector<FileDescriptor>>
> + static std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
> serialize(const std::map<K, V> &data, ControlSerializer *cs = nullptr)
> {
> std::vector<uint8_t> dataVec;
> - std::vector<FileDescriptor> fdsVec;
> + std::vector<SharedFD> fdsVec;
>
> /* Serialize the length. */
> uint32_t mapLen = data.size();
> @@ -214,7 +214,7 @@ public:
> /* Serialize the members. */
> for (auto const &it : data) {
> std::vector<uint8_t> dvec;
> - std::vector<FileDescriptor> fvec;
> + std::vector<SharedFD> fvec;
>
> std::tie(dvec, fvec) =
> IPADataSerializer<K>::serialize(it.first, cs);
> @@ -247,11 +247,11 @@ public:
> std::vector<uint8_t>::const_iterator dataEnd,
> ControlSerializer *cs = nullptr)
> {
> - std::vector<FileDescriptor> fds;
> + std::vector<SharedFD> fds;
> return deserialize(dataBegin, dataEnd, fds.cbegin(), fds.end(), cs);
> }
>
> - static std::map<K, V> deserialize(std::vector<uint8_t> &data, std::vector<FileDescriptor> &fds,
> + static std::map<K, V> deserialize(std::vector<uint8_t> &data, std::vector<SharedFD> &fds,
> ControlSerializer *cs = nullptr)
> {
> return deserialize(data.cbegin(), data.end(), fds.cbegin(), fds.end(), cs);
> @@ -259,8 +259,8 @@ public:
>
> static std::map<K, V> deserialize(std::vector<uint8_t>::const_iterator dataBegin,
> std::vector<uint8_t>::const_iterator dataEnd,
> - std::vector<FileDescriptor>::const_iterator fdsBegin,
> - [[maybe_unused]] std::vector<FileDescriptor>::const_iterator fdsEnd,
> + std::vector<SharedFD>::const_iterator fdsBegin,
> + [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd,
> ControlSerializer *cs = nullptr)
> {
> std::map<K, V> ret;
> @@ -268,7 +268,7 @@ public:
> uint32_t mapLen = readPOD<uint32_t>(dataBegin, 0, dataEnd);
>
> std::vector<uint8_t>::const_iterator dataIter = dataBegin + 4;
> - std::vector<FileDescriptor>::const_iterator fdIter = fdsBegin;
> + std::vector<SharedFD>::const_iterator fdIter = fdsBegin;
> for (uint32_t i = 0; i < mapLen; i++) {
> uint32_t sizeofData = readPOD<uint32_t>(dataIter, 0, dataEnd);
> uint32_t sizeofFds = readPOD<uint32_t>(dataIter, 4, dataEnd);
> diff --git a/include/libcamera/internal/ipc_pipe.h b/include/libcamera/internal/ipc_pipe.h
> index 986f8d886fa6..ab5dd67c3813 100644
> --- a/include/libcamera/internal/ipc_pipe.h
> +++ b/include/libcamera/internal/ipc_pipe.h
> @@ -9,7 +9,7 @@
>
> #include <vector>
>
> -#include <libcamera/base/file_descriptor.h>
> +#include <libcamera/base/shared_fd.h>
> #include <libcamera/base/signal.h>
>
> #include "libcamera/internal/ipc_unixsocket.h"
> @@ -33,17 +33,17 @@ public:
>
> Header &header() { return header_; }
> std::vector<uint8_t> &data() { return data_; }
> - std::vector<FileDescriptor> &fds() { return fds_; }
> + std::vector<SharedFD> &fds() { return fds_; }
>
> const Header &header() const { return header_; }
> const std::vector<uint8_t> &data() const { return data_; }
> - const std::vector<FileDescriptor> &fds() const { return fds_; }
> + const std::vector<SharedFD> &fds() const { return fds_; }
>
> private:
> Header header_;
>
> std::vector<uint8_t> data_;
> - std::vector<FileDescriptor> fds_;
> + std::vector<SharedFD> fds_;
> };
>
> class IPCPipe
> diff --git a/include/libcamera/ipa/core.mojom b/include/libcamera/ipa/core.mojom
> index f7eff0c7ab8c..74f3339e56f2 100644
> --- a/include/libcamera/ipa/core.mojom
> +++ b/include/libcamera/ipa/core.mojom
> @@ -32,7 +32,7 @@ module libcamera;
> * - This attribute instructs the build system that a (de)serializer is
> * available for the type and there's no need to generate one
> * - hasFd - struct fields or empty structs only
> - * - Designate that this field or empty struct contains a FileDescriptor
> + * - Designate that this field or empty struct contains a SharedFD
> *
> * Rules:
> * - If the type is defined in a libcamera C++ header *and* a (de)serializer is
> @@ -60,7 +60,7 @@ module libcamera;
> * - In mojom, reference the type as FrameBuffer.Plane and only as map/array
> * member
> * - [skipHeader] and [skipSerdes] only work here in core.mojom
> - * - If a field in a struct has a FileDescriptor, but is not explicitly
> + * - If a field in a struct has a SharedFD, but is not explicitly
> * defined so in mojom, then the field must be marked with the [hasFd]
> * attribute
> *
> @@ -71,7 +71,7 @@ module libcamera;
> */
> [skipSerdes, skipHeader] struct ControlInfoMap {};
> [skipSerdes, skipHeader] struct ControlList {};
> -[skipSerdes, skipHeader] struct FileDescriptor {};
> +[skipSerdes, skipHeader] struct SharedFD {};
>
> [skipHeader] struct Point {
> int32 x;
> diff --git a/include/libcamera/ipa/raspberrypi.mojom b/include/libcamera/ipa/raspberrypi.mojom
> index e453d46cb14f..acd3cafe6c91 100644
> --- a/include/libcamera/ipa/raspberrypi.mojom
> +++ b/include/libcamera/ipa/raspberrypi.mojom
> @@ -35,7 +35,7 @@ struct ISPConfig {
>
> struct IPAConfig {
> uint32 transform;
> - libcamera.FileDescriptor lsTableHandle;
> + libcamera.SharedFD lsTableHandle;
> };
>
> struct StartConfig {
> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> index f2e0bdbdbbf6..1938b10509fa 100644
> --- a/src/android/camera_device.cpp
> +++ b/src/android/camera_device.cpp
> @@ -725,7 +725,7 @@ CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer,
>
> std::vector<FrameBuffer::Plane> planes(buf.numPlanes());
> for (size_t i = 0; i < buf.numPlanes(); ++i) {
> - FileDescriptor fd{ camera3buffer->data[i] };
> + SharedFD fd{ camera3buffer->data[i] };
> if (!fd.isValid()) {
> LOG(HAL, Fatal) << "No valid fd";
> return nullptr;
> diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp
> index c6aec09046f7..aaf629eeb3fc 100644
> --- a/src/ipa/raspberrypi/raspberrypi.cpp
> +++ b/src/ipa/raspberrypi/raspberrypi.cpp
> @@ -15,8 +15,8 @@
>
> #include <linux/bcm2835-isp.h>
>
> -#include <libcamera/base/file_descriptor.h>
> #include <libcamera/base/log.h>
> +#include <libcamera/base/shared_fd.h>
> #include <libcamera/base/span.h>
>
> #include <libcamera/control_ids.h>
> @@ -164,7 +164,7 @@ private:
> bool processPending_;
>
> /* LS table allocation passed in from the pipeline handler. */
> - FileDescriptor lsTableHandle_;
> + SharedFD lsTableHandle_;
> void *lsTable_;
>
> /* Distinguish the first camera start from others. */
> diff --git a/src/libcamera/base/file.cpp b/src/libcamera/base/file.cpp
> index 66c73c406198..3ca9839bb989 100644
> --- a/src/libcamera/base/file.cpp
> +++ b/src/libcamera/base/file.cpp
> @@ -14,8 +14,8 @@
> #include <sys/types.h>
> #include <unistd.h>
>
> -#include <libcamera/base/file_descriptor.h>
> #include <libcamera/base/log.h>
> +#include <libcamera/base/shared_fd.h>
>
> /**
> * \file base/file.h
> @@ -473,11 +473,11 @@ bool File::exists(const std::string &name)
> }
>
> /**
> - * \brief Retrieve the inode of a FileDescriptor
> + * \brief Retrieve the inode of a SharedFD
> *
> * \return The file descriptor inode on success, or 0 on error
> */
> -ino_t File::inode(const FileDescriptor &fd)
> +ino_t File::inode(const SharedFD &fd)
> {
> if (!fd.isValid())
> return 0;
> diff --git a/src/libcamera/base/file_descriptor.cpp b/src/libcamera/base/file_descriptor.cpp
> deleted file mode 100644
> index a83bf52c31e6..000000000000
> --- a/src/libcamera/base/file_descriptor.cpp
> +++ /dev/null
> @@ -1,266 +0,0 @@
> -/* SPDX-License-Identifier: LGPL-2.1-or-later */
> -/*
> - * Copyright (C) 2019, Google Inc.
> - *
> - * file_descriptor.cpp - File descriptor wrapper
> - */
> -
> -#include <libcamera/base/file_descriptor.h>
> -
> -#include <string.h>
> -#include <sys/types.h>
> -#include <unistd.h>
> -#include <utility>
> -
> -#include <libcamera/base/log.h>
> -#include <libcamera/base/unique_fd.h>
> -
> -/**
> - * \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<Descriptor>(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<Descriptor>(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 Create a FileDescriptor taking ownership of a given UniqueFD \a fd
> - * \param[in] fd UniqueFD
> - *
> - * Construct a FileDescriptor from UniqueFD by taking ownership of the \a fd.
> - * The original \a fd becomes invalid.
> - */
> -FileDescriptor::FileDescriptor(UniqueFD fd)
> - : FileDescriptor(fd.release())
> -{
> -}
> -
> -/**
> - * \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 UniqueFD that owns the duplicate. The fd() function
> - * of the original and the get() function of the duplicate will return different
> - * values. The duplicate instance will not be affected by destruction of the
> - * original instance or its copies.
> - *
> - * \return A UniqueFD owning a duplicate of the original file descriptor
> - */
> -UniqueFD FileDescriptor::dup() const
> -{
> - int dupFd = ::dup(fd());
> - if (dupFd == -1) {
> - int ret = -errno;
> - LOG(FileDescriptor, Error)
> - << "Failed to dup() fd: " << strerror(-ret);
> - }
> -
> - return UniqueFD(dupFd);
> -}
> -
> -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 b0d85bc19245..ccb746c27466 100644
> --- a/src/libcamera/base/meson.build
> +++ b/src/libcamera/base/meson.build
> @@ -8,12 +8,12 @@ libcamera_base_sources = files([
> 'event_dispatcher_poll.cpp',
> 'event_notifier.cpp',
> 'file.cpp',
> - 'file_descriptor.cpp',
> 'flags.cpp',
> 'log.cpp',
> 'message.cpp',
> 'object.cpp',
> 'semaphore.cpp',
> + 'shared_fd.cpp',
> 'signal.cpp',
> 'thread.cpp',
> 'timer.cpp',
> diff --git a/src/libcamera/base/shared_fd.cpp b/src/libcamera/base/shared_fd.cpp
> new file mode 100644
> index 000000000000..05b6892f7e19
> --- /dev/null
> +++ b/src/libcamera/base/shared_fd.cpp
> @@ -0,0 +1,262 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2019, Google Inc.
> + *
> + * shared_fd.cpp - File descriptor wrapper with shared ownership
> + */
> +
> +#include <libcamera/base/shared_fd.h>
> +
> +#include <string.h>
> +#include <sys/types.h>
> +#include <unistd.h>
> +#include <utility>
> +
> +#include <libcamera/base/log.h>
> +#include <libcamera/base/unique_fd.h>
> +
> +/**
> + * \file base/shared_fd.h
> + * \brief File descriptor wrapper
> + */
> +
> +namespace libcamera {
> +
> +LOG_DEFINE_CATEGORY(SharedFD)
> +
> +/**
> + * \class SharedFD
> + * \brief RAII-style wrapper for file descriptors
> + *
> + * The SharedFD 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 SharedFD instances constructed as copies.
> + *
> + * When constructed from a numerical file descriptor, the SharedFD instance
> + * either duplicates or takes over the file descriptor:
> + *
> + * - The SharedFD(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 SharedFD(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 SharedFD invalid. When the last SharedFD that references a Descriptor
> + * is destroyed, the file descriptor is closed.
> + *
> + * The numerical file descriptor is available through the fd() function. All
> + * SharedFD instances created as copies of a SharedFD will report the same fd()
> + * value. Callers can perform operations on the fd(), but shall never close it
> + * manually.
> + */
> +
> +/**
> + * \brief Create a SharedFD copying a given \a fd
> + * \param[in] fd File descriptor
> + *
> + * Construct a SharedFD 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 SharedFD instances that
> + * reference it are destroyed.
> + *
> + * If the \a fd is negative, the SharedFD is constructed as invalid and the fd()
> + * function will return -1.
> + */
> +SharedFD::SharedFD(const int &fd)
> +{
> + if (fd < 0)
> + return;
> +
> + fd_ = std::make_shared<Descriptor>(fd, true);
> + if (fd_->fd() < 0)
> + fd_.reset();
> +}
> +
> +/**
> + * \brief Create a SharedFD taking ownership of a given \a fd
> + * \param[in] fd File descriptor
> + *
> + * Construct a SharedFD 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 SharedFD instances that reference it are destroyed.
> + *
> + * If the \a fd is negative, the SharedFD is constructed as invalid and the fd()
> + * function will return -1.
> + */
> +SharedFD::SharedFD(int &&fd)
> +{
> + if (fd < 0)
> + return;
> +
> + fd_ = std::make_shared<Descriptor>(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 Create a SharedFD taking ownership of a given UniqueFD \a fd
> + * \param[in] fd UniqueFD
> + *
> + * Construct a SharedFD from UniqueFD by taking ownership of the \a fd. The
> + * original \a fd becomes invalid.
> + */
> +SharedFD::SharedFD(UniqueFD fd)
> + : SharedFD(fd.release())
> +{
> +}
> +
> +/**
> + * \brief Copy constructor, create a SharedFD from a copy of \a other
> + * \param[in] other The other SharedFD
> + *
> + * Copying a SharedFD implicitly shares ownership of the wrapped file
> + * descriptor. The original SharedFD is left untouched, and the caller is
> + * responsible for destroying it when appropriate. The wrapped file descriptor
> + * will be closed automatically when all SharedFD instances that reference it
> + * are destroyed.
> + */
> +SharedFD::SharedFD(const SharedFD &other)
> + : fd_(other.fd_)
> +{
> +}
> +
> +/**
> + * \brief Move constructor, create a SharedFD by taking over \a other
> + * \param[in] other The other SharedFD
> + *
> + * Moving a SharedFD moves the reference to the wrapped descriptor owned by
> + * \a other to the new SharedFD. The \a other SharedFD is invalidated and its
> + * fd() function will return -1. The wrapped file descriptor will be closed
> + * automatically when all SharedFD instances that reference it are destroyed.
> + */
> +SharedFD::SharedFD(SharedFD &&other)
> + : fd_(std::move(other.fd_))
> +{
> +}
> +
> +/**
> + * \brief Destroy the SharedFD instance
> + *
> + * Destroying a SharedFD 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.
> + */
> +SharedFD::~SharedFD()
> +{
> +}
> +
> +/**
> + * \brief Copy assignment operator, replace the wrapped file descriptor with a
> + * copy of \a other
> + * \param[in] other The other SharedFD
> + *
> + * Copying a SharedFD 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 SharedFD is left untouched, and the caller is responsible for
> + * destroying it when appropriate. The wrapped file descriptor will be closed
> + * automatically when all SharedFD instances that reference it are destroyed.
> + *
> + * \return A reference to this SharedFD
> + */
> +SharedFD &SharedFD::operator=(const SharedFD &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 SharedFD
> + *
> + * Moving a SharedFD moves the reference to the wrapped descriptor owned by
> + * \a other to the new SharedFD. If \a other is invalid, *this will also be
> + * invalid. The \a other SharedFD is invalidated and its fd() function will
> + * return -1. The wrapped file descriptor will be closed automatically when
> + * all SharedFD instances that reference it are destroyed.
> + *
> + * \return A reference to this SharedFD
> + */
> +SharedFD &SharedFD::operator=(SharedFD &&other)
> +{
> + fd_ = std::move(other.fd_);
> +
> + return *this;
> +}
> +
> +/**
> + * \fn SharedFD::isValid()
> + * \brief Check if the SharedFD instance is valid
> + * \return True if the SharedFD is valid, false otherwise
> + */
> +
> +/**
> + * \fn SharedFD::fd()
> + * \brief Retrieve the numerical file descriptor
> + * \return The numerical file descriptor, which may be -1 if the SharedFD
> + * instance is invalid
> + */
> +
> +/**
> + * \brief Duplicate a SharedFD
> + *
> + * Duplicating a SharedFD creates a duplicate of the wrapped file descriptor and
> + * returns a UniqueFD that owns the duplicate. The fd() function of the original
> + * and the get() function of the duplicate will return different values. The
> + * duplicate instance will not be affected by destruction of the original
> + * instance or its copies.
> + *
> + * \return A UniqueFD owning a duplicate of the original file descriptor
> + */
> +UniqueFD SharedFD::dup() const
> +{
> + int dupFd = ::dup(fd());
> + if (dupFd == -1) {
> + int ret = -errno;
> + LOG(SharedFD, Error)
> + << "Failed to dup() fd: " << strerror(-ret);
> + }
> +
> + return UniqueFD(dupFd);
> +}
> +
> +SharedFD::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(SharedFD, Fatal)
> + << "Failed to dup() fd: " << strerror(-ret);
> + }
> +}
> +
> +SharedFD::Descriptor::~Descriptor()
> +{
> + if (fd_ != -1)
> + close(fd_);
> +}
> +
> +} /* namespace libcamera */
> diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp
> index f5bcf107d7aa..0a5bf7fdbeb7 100644
> --- a/src/libcamera/framebuffer.cpp
> +++ b/src/libcamera/framebuffer.cpp
> @@ -180,9 +180,9 @@ FrameBuffer::Private::Private()
> * offset and length.
> *
> * To support DMA access, planes are associated with dmabuf objects represented
> - * by FileDescriptor handles. The Plane class doesn't handle mapping of the
> - * memory to the CPU, but applications and IPAs may use the dmabuf file
> - * descriptors to map the plane memory with mmap() and access its contents.
> + * by SharedFD handles. The Plane class doesn't handle mapping of the memory to
> + * the CPU, but applications and IPAs may use the dmabuf file descriptors to map
> + * the plane memory with mmap() and access its contents.
> *
> * \todo Specify how an application shall decide whether to use a single or
> * multiple dmabufs, based on the camera requirements.
> diff --git a/src/libcamera/ipa_data_serializer.cpp b/src/libcamera/ipa_data_serializer.cpp
> index 82ec9b20a411..0a259305afa2 100644
> --- a/src/libcamera/ipa_data_serializer.cpp
> +++ b/src/libcamera/ipa_data_serializer.cpp
> @@ -31,7 +31,7 @@ LOG_DEFINE_CATEGORY(IPADataSerializer)
> *
> * \todo Harden the vector and map deserializer
> *
> - * \todo For FileDescriptors, instead of storing a validity flag, store an
> + * \todo For SharedFDs, instead of storing a validity flag, store an
> * index into the fd array. This will allow us to use views instead of copying.
> */
>
> @@ -112,7 +112,7 @@ namespace {
> * \param[in] cs ControlSerializer
> *
> * This version of deserialize() can be used if the object type \a T and its
> - * members don't have any FileDescriptor.
> + * members don't have any SharedFD.
> *
> * \a cs is only necessary if the object type \a T or its members contain
> * ControlList or ControlInfoMap.
> @@ -132,7 +132,7 @@ namespace {
> * \param[in] cs ControlSerializer
> *
> * This version of deserialize() can be used if the object type \a T and its
> - * members don't have any FileDescriptor.
> + * members don't have any SharedFD.
> *
> * \a cs is only necessary if the object type \a T or its members contain
> * ControlList or ControlInfoMap.
> @@ -143,7 +143,7 @@ namespace {
> /**
> * \fn template<typename T> IPADataSerializer<T>::deserialize(
> * const std::vector<uint8_t> &data,
> - * const std::vector<FileDescriptor> &fds,
> + * const std::vector<SharedFD> &fds,
> * ControlSerializer *cs = nullptr)
> * \brief Deserialize byte vector and fd vector into an object
> * \tparam T Type of object to deserialize to
> @@ -152,7 +152,7 @@ namespace {
> * \param[in] cs ControlSerializer
> *
> * This version of deserialize() (or the iterator version) must be used if
> - * the object type \a T or its members contain FileDescriptor.
> + * the object type \a T or its members contain SharedFD.
> *
> * \a cs is only necessary if the object type \a T or its members contain
> * ControlList or ControlInfoMap.
> @@ -164,8 +164,8 @@ namespace {
> * \fn template<typename T> IPADataSerializer::deserialize(
> * std::vector<uint8_t>::const_iterator dataBegin,
> * std::vector<uint8_t>::const_iterator dataEnd,
> - * std::vector<FileDescriptor>::const_iterator fdsBegin,
> - * std::vector<FileDescriptor>::const_iterator fdsEnd,
> + * std::vector<SharedFD>::const_iterator fdsBegin,
> + * std::vector<SharedFD>::const_iterator fdsEnd,
> * ControlSerializer *cs = nullptr)
> * \brief Deserialize byte vector and fd vector into an object
> * \tparam T Type of object to deserialize to
> @@ -176,7 +176,7 @@ namespace {
> * \param[in] cs ControlSerializer
> *
> * This version of deserialize() (or the vector version) must be used if
> - * the object type \a T or its members contain FileDescriptor.
> + * the object type \a T or its members contain SharedFD.
> *
> * \a cs is only necessary if the object type \a T or its members contain
> * ControlList or ControlInfoMap.
> @@ -189,7 +189,7 @@ namespace {
> #define DEFINE_POD_SERIALIZER(type) \
> \
> template<> \
> -std::tuple<std::vector<uint8_t>, std::vector<FileDescriptor>> \
> +std::tuple<std::vector<uint8_t>, std::vector<SharedFD>> \
> IPADataSerializer<type>::serialize(const type &data, \
> [[maybe_unused]] ControlSerializer *cs) \
> { \
> @@ -217,7 +217,7 @@ type IPADataSerializer<type>::deserialize(const std::vector<uint8_t> &data, \
> \
> template<> \
> type IPADataSerializer<type>::deserialize(const std::vector<uint8_t> &data, \
> - [[maybe_unused]] const std::vector<FileDescriptor> &fds, \
> + [[maybe_unused]] const std::vector<SharedFD> &fds, \
> ControlSerializer *cs) \
> { \
> return deserialize(data.cbegin(), data.end(), cs); \
> @@ -226,8 +226,8 @@ type IPADataSerializer<type>::deserialize(const std::vector<uint8_t> &data, \
> template<> \
> type IPADataSerializer<type>::deserialize(std::vector<uint8_t>::const_iterator dataBegin, \
> std::vector<uint8_t>::const_iterator dataEnd, \
> - [[maybe_unused]] std::vector<FileDescriptor>::const_iterator fdsBegin, \
> - [[maybe_unused]] std::vector<FileDescriptor>::const_iterator fdsEnd, \
> + [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsBegin, \
> + [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd, \
> ControlSerializer *cs) \
> { \
> return deserialize(dataBegin, dataEnd, cs); \
> @@ -251,7 +251,7 @@ DEFINE_POD_SERIALIZER(double)
> * function parameter serdes).
> */
> template<>
> -std::tuple<std::vector<uint8_t>, std::vector<FileDescriptor>>
> +std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
> IPADataSerializer<std::string>::serialize(const std::string &data,
> [[maybe_unused]] ControlSerializer *cs)
> {
> @@ -278,7 +278,7 @@ IPADataSerializer<std::string>::deserialize(std::vector<uint8_t>::const_iterator
> template<>
> std::string
> IPADataSerializer<std::string>::deserialize(const std::vector<uint8_t> &data,
> - [[maybe_unused]] const std::vector<FileDescriptor> &fds,
> + [[maybe_unused]] const std::vector<SharedFD> &fds,
> [[maybe_unused]] ControlSerializer *cs)
> {
> return { data.cbegin(), data.cend() };
> @@ -288,8 +288,8 @@ template<>
> std::string
> IPADataSerializer<std::string>::deserialize(std::vector<uint8_t>::const_iterator dataBegin,
> std::vector<uint8_t>::const_iterator dataEnd,
> - [[maybe_unused]] std::vector<FileDescriptor>::const_iterator fdsBegin,
> - [[maybe_unused]] std::vector<FileDescriptor>::const_iterator fdsEnd,
> + [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsBegin,
> + [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd,
> [[maybe_unused]] ControlSerializer *cs)
> {
> return { dataBegin, dataEnd };
> @@ -307,7 +307,7 @@ IPADataSerializer<std::string>::deserialize(std::vector<uint8_t>::const_iterator
> * be used. The serialized ControlInfoMap will have zero length.
> */
> template<>
> -std::tuple<std::vector<uint8_t>, std::vector<FileDescriptor>>
> +std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
> IPADataSerializer<ControlList>::serialize(const ControlList &data, ControlSerializer *cs)
> {
> if (!cs)
> @@ -407,7 +407,7 @@ IPADataSerializer<ControlList>::deserialize(const std::vector<uint8_t> &data,
> template<>
> ControlList
> IPADataSerializer<ControlList>::deserialize(const std::vector<uint8_t> &data,
> - [[maybe_unused]] const std::vector<FileDescriptor> &fds,
> + [[maybe_unused]] const std::vector<SharedFD> &fds,
> ControlSerializer *cs)
> {
> return deserialize(data.cbegin(), data.end(), cs);
> @@ -417,8 +417,8 @@ template<>
> ControlList
> IPADataSerializer<ControlList>::deserialize(std::vector<uint8_t>::const_iterator dataBegin,
> std::vector<uint8_t>::const_iterator dataEnd,
> - [[maybe_unused]] std::vector<FileDescriptor>::const_iterator fdsBegin,
> - [[maybe_unused]] std::vector<FileDescriptor>::const_iterator fdsEnd,
> + [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsBegin,
> + [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd,
> ControlSerializer *cs)
> {
> return deserialize(dataBegin, dataEnd, cs);
> @@ -431,7 +431,7 @@ IPADataSerializer<ControlList>::deserialize(std::vector<uint8_t>::const_iterator
> * X bytes - Serialized ControlInfoMap (using ControlSerializer)
> */
> template<>
> -std::tuple<std::vector<uint8_t>, std::vector<FileDescriptor>>
> +std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
> IPADataSerializer<ControlInfoMap>::serialize(const ControlInfoMap &map,
> ControlSerializer *cs)
> {
> @@ -493,7 +493,7 @@ IPADataSerializer<ControlInfoMap>::deserialize(const std::vector<uint8_t> &data,
> template<>
> ControlInfoMap
> IPADataSerializer<ControlInfoMap>::deserialize(const std::vector<uint8_t> &data,
> - [[maybe_unused]] const std::vector<FileDescriptor> &fds,
> + [[maybe_unused]] const std::vector<SharedFD> &fds,
> ControlSerializer *cs)
> {
> return deserialize(data.cbegin(), data.end(), cs);
> @@ -503,30 +503,30 @@ template<>
> ControlInfoMap
> IPADataSerializer<ControlInfoMap>::deserialize(std::vector<uint8_t>::const_iterator dataBegin,
> std::vector<uint8_t>::const_iterator dataEnd,
> - [[maybe_unused]] std::vector<FileDescriptor>::const_iterator fdsBegin,
> - [[maybe_unused]] std::vector<FileDescriptor>::const_iterator fdsEnd,
> + [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsBegin,
> + [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd,
> ControlSerializer *cs)
> {
> return deserialize(dataBegin, dataEnd, cs);
> }
>
> /*
> - * FileDescriptors are serialized into four bytes that tells if the
> - * FileDescriptor is valid or not. If it is valid, then for serialization
> - * the fd will be written to the fd vector, or for deserialization the
> - * fd vector const_iterator will be valid.
> + * SharedFD instances are serialized into four bytes that tells if the SharedFD
> + * is valid or not. If it is valid, then for serialization the fd will be
> + * written to the fd vector, or for deserialization the fd vector const_iterator
> + * will be valid.
> *
> * This validity is necessary so that we don't send -1 fd over sendmsg(). It
> * also allows us to simply send the entire fd vector into the deserializer
> * and it will be recursively consumed as necessary.
> */
> template<>
> -std::tuple<std::vector<uint8_t>, std::vector<FileDescriptor>>
> -IPADataSerializer<FileDescriptor>::serialize(const FileDescriptor &data,
> - [[maybe_unused]] ControlSerializer *cs)
> +std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
> +IPADataSerializer<SharedFD>::serialize(const SharedFD &data,
> + [[maybe_unused]] ControlSerializer *cs)
> {
> std::vector<uint8_t> dataVec;
> - std::vector<FileDescriptor> fdVec;
> + std::vector<SharedFD> fdVec;
>
> /*
> * Store as uint32_t to prepare for conversion from validity flag
> @@ -542,11 +542,11 @@ IPADataSerializer<FileDescriptor>::serialize(const FileDescriptor &data,
> }
>
> template<>
> -FileDescriptor IPADataSerializer<FileDescriptor>::deserialize([[maybe_unused]] std::vector<uint8_t>::const_iterator dataBegin,
> - [[maybe_unused]] std::vector<uint8_t>::const_iterator dataEnd,
> - std::vector<FileDescriptor>::const_iterator fdsBegin,
> - std::vector<FileDescriptor>::const_iterator fdsEnd,
> - [[maybe_unused]] ControlSerializer *cs)
> +SharedFD IPADataSerializer<SharedFD>::deserialize([[maybe_unused]] std::vector<uint8_t>::const_iterator dataBegin,
> + [[maybe_unused]] std::vector<uint8_t>::const_iterator dataEnd,
> + std::vector<SharedFD>::const_iterator fdsBegin,
> + std::vector<SharedFD>::const_iterator fdsEnd,
> + [[maybe_unused]] ControlSerializer *cs)
> {
> ASSERT(std::distance(dataBegin, dataEnd) >= 4);
>
> @@ -554,13 +554,13 @@ FileDescriptor IPADataSerializer<FileDescriptor>::deserialize([[maybe_unused]] s
>
> ASSERT(!(valid && std::distance(fdsBegin, fdsEnd) < 1));
>
> - return valid ? *fdsBegin : FileDescriptor();
> + return valid ? *fdsBegin : SharedFD();
> }
>
> template<>
> -FileDescriptor IPADataSerializer<FileDescriptor>::deserialize(const std::vector<uint8_t> &data,
> - const std::vector<FileDescriptor> &fds,
> - [[maybe_unused]] ControlSerializer *cs)
> +SharedFD IPADataSerializer<SharedFD>::deserialize(const std::vector<uint8_t> &data,
> + const std::vector<SharedFD> &fds,
> + [[maybe_unused]] ControlSerializer *cs)
> {
> return deserialize(data.cbegin(), data.end(), fds.cbegin(), fds.end());
> }
> @@ -568,22 +568,22 @@ FileDescriptor IPADataSerializer<FileDescriptor>::deserialize(const std::vector<
> /*
> * FrameBuffer::Plane is serialized as:
> *
> - * 4 byte - FileDescriptor
> + * 4 byte - SharedFD
> * 4 bytes - uint32_t Offset
> * 4 bytes - uint32_t Length
> */
> template<>
> -std::tuple<std::vector<uint8_t>, std::vector<FileDescriptor>>
> +std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
> IPADataSerializer<FrameBuffer::Plane>::serialize(const FrameBuffer::Plane &data,
> [[maybe_unused]] ControlSerializer *cs)
> {
> std::vector<uint8_t> dataVec;
> - std::vector<FileDescriptor> fdsVec;
> + std::vector<SharedFD> fdsVec;
>
> std::vector<uint8_t> fdBuf;
> - std::vector<FileDescriptor> fdFds;
> + std::vector<SharedFD> fdFds;
> std::tie(fdBuf, fdFds) =
> - IPADataSerializer<FileDescriptor>::serialize(data.fd);
> + IPADataSerializer<SharedFD>::serialize(data.fd);
> dataVec.insert(dataVec.end(), fdBuf.begin(), fdBuf.end());
> fdsVec.insert(fdsVec.end(), fdFds.begin(), fdFds.end());
>
> @@ -597,13 +597,13 @@ template<>
> FrameBuffer::Plane
> IPADataSerializer<FrameBuffer::Plane>::deserialize(std::vector<uint8_t>::const_iterator dataBegin,
> std::vector<uint8_t>::const_iterator dataEnd,
> - std::vector<FileDescriptor>::const_iterator fdsBegin,
> - [[maybe_unused]] std::vector<FileDescriptor>::const_iterator fdsEnd,
> + std::vector<SharedFD>::const_iterator fdsBegin,
> + [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd,
> [[maybe_unused]] ControlSerializer *cs)
> {
> FrameBuffer::Plane ret;
>
> - ret.fd = IPADataSerializer<FileDescriptor>::deserialize(dataBegin, dataBegin + 4,
> + ret.fd = IPADataSerializer<SharedFD>::deserialize(dataBegin, dataBegin + 4,
> fdsBegin, fdsBegin + 1);
> ret.offset = readPOD<uint32_t>(dataBegin, 4, dataEnd);
> ret.length = readPOD<uint32_t>(dataBegin, 8, dataEnd);
> @@ -614,7 +614,7 @@ IPADataSerializer<FrameBuffer::Plane>::deserialize(std::vector<uint8_t>::const_i
> template<>
> FrameBuffer::Plane
> IPADataSerializer<FrameBuffer::Plane>::deserialize(const std::vector<uint8_t> &data,
> - const std::vector<FileDescriptor> &fds,
> + const std::vector<SharedFD> &fds,
> ControlSerializer *cs)
> {
> return deserialize(data.cbegin(), data.end(), fds.cbegin(), fds.end(), cs);
> diff --git a/src/libcamera/ipc_pipe.cpp b/src/libcamera/ipc_pipe.cpp
> index ad870fd4137f..3b47032de0a2 100644
> --- a/src/libcamera/ipc_pipe.cpp
> +++ b/src/libcamera/ipc_pipe.cpp
> @@ -87,7 +87,7 @@ IPCMessage::IPCMessage(IPCUnixSocket::Payload &payload)
> data_ = std::vector<uint8_t>(payload.data.begin() + sizeof(header_),
> payload.data.end());
> for (int32_t &fd : payload.fds)
> - fds_.push_back(FileDescriptor(std::move(fd)));
> + fds_.push_back(SharedFD(std::move(fd)));
> }
>
> /**
> @@ -112,7 +112,7 @@ IPCUnixSocket::Payload IPCMessage::payload() const
> data_.data(), data_.size());
> }
>
> - for (const FileDescriptor &fd : fds_)
> + for (const SharedFD &fd : fds_)
> payload.fds.push_back(fd.fd());
>
> return payload;
> diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> index ffa51a0c65ca..ea8243912a29 100644
> --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
> @@ -12,7 +12,7 @@
> #include <queue>
> #include <unordered_set>
>
> -#include <libcamera/base/file_descriptor.h>
> +#include <libcamera/base/shared_fd.h>
>
> #include <libcamera/camera.h>
> #include <libcamera/control_ids.h>
> @@ -228,7 +228,7 @@ public:
>
> /* DMAHEAP allocation helper. */
> RPi::DmaHeap dmaHeap_;
> - FileDescriptor lsTable_;
> + SharedFD lsTable_;
>
> std::unique_ptr<DelayedControls> delayedCtrls_;
> bool sensorMetadata_;
> @@ -1365,7 +1365,7 @@ int RPiCameraData::configureIPA(const CameraConfiguration *config)
> if (!fd.isValid())
> return -ENOMEM;
>
> - lsTable_ = FileDescriptor(std::move(fd));
> + lsTable_ = SharedFD(std::move(fd));
>
> /* Allow the IPA to mmap the LS table via the file descriptor. */
> /*
> diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
> index 3966483a365f..97d431071def 100644
> --- a/src/libcamera/v4l2_videodevice.cpp
> +++ b/src/libcamera/v4l2_videodevice.cpp
> @@ -22,8 +22,8 @@
> #include <linux/version.h>
>
> #include <libcamera/base/event_notifier.h>
> -#include <libcamera/base/file_descriptor.h>
> #include <libcamera/base/log.h>
> +#include <libcamera/base/shared_fd.h>
> #include <libcamera/base/unique_fd.h>
> #include <libcamera/base/utils.h>
>
> @@ -1325,7 +1325,7 @@ std::unique_ptr<FrameBuffer> V4L2VideoDevice::createBuffer(unsigned int index)
> return nullptr;
>
> FrameBuffer::Plane plane;
> - plane.fd = FileDescriptor(std::move(fd));
> + plane.fd = SharedFD(std::move(fd));
> /*
> * V4L2 API doesn't provide dmabuf offset information of plane.
> * Set 0 as a placeholder offset.
> @@ -1354,7 +1354,7 @@ std::unique_ptr<FrameBuffer> V4L2VideoDevice::createBuffer(unsigned int index)
> ASSERT(numPlanes == 1u);
>
> planes.resize(formatInfo_->numPlanes());
> - const FileDescriptor &fd = planes[0].fd;
> + const SharedFD &fd = planes[0].fd;
> size_t offset = 0;
>
> for (auto [i, plane] : utils::enumerate(planes)) {
> diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h
> index 9817fd393d59..586347829845 100644
> --- a/src/v4l2/v4l2_camera.h
> +++ b/src/v4l2/v4l2_camera.h
> @@ -11,8 +11,8 @@
> #include <mutex>
> #include <utility>
>
> -#include <libcamera/base/file_descriptor.h>
> #include <libcamera/base/semaphore.h>
> +#include <libcamera/base/shared_fd.h>
>
> #include <libcamera/camera.h>
> #include <libcamera/framebuffer.h>
> diff --git a/test/meson.build b/test/meson.build
> index 42dfbc1f8ee9..daaa3862cdd6 100644
> --- a/test/meson.build
> +++ b/test/meson.build
> @@ -40,7 +40,6 @@ internal_tests = [
> ['event-dispatcher', 'event-dispatcher.cpp'],
> ['event-thread', 'event-thread.cpp'],
> ['file', 'file.cpp'],
> - ['file-descriptor', 'file-descriptor.cpp'],
> ['flags', 'flags.cpp'],
> ['hotplug-cameras', 'hotplug-cameras.cpp'],
> ['mapped-buffer', 'mapped-buffer.cpp'],
> @@ -49,6 +48,7 @@ internal_tests = [
> ['object-delete', 'object-delete.cpp'],
> ['object-invoke', 'object-invoke.cpp'],
> ['pixel-format', 'pixel-format.cpp'],
> + ['shared-fd', 'shared-fd.cpp'],
> ['signal-threads', 'signal-threads.cpp'],
> ['threads', 'threads.cpp'],
> ['timer', 'timer.cpp'],
> diff --git a/test/serialization/ipa_data_serializer_test.cpp b/test/serialization/ipa_data_serializer_test.cpp
> index 5fcdcb8eae92..d2050a868b38 100644
> --- a/test/serialization/ipa_data_serializer_test.cpp
> +++ b/test/serialization/ipa_data_serializer_test.cpp
> @@ -53,7 +53,7 @@ template<typename T>
> int testPodSerdes(T in)
> {
> std::vector<uint8_t> buf;
> - std::vector<FileDescriptor> fds;
> + std::vector<SharedFD> fds;
>
> std::tie(buf, fds) = IPADataSerializer<T>::serialize(in);
> T out = IPADataSerializer<T>::deserialize(buf, fds);
> @@ -72,7 +72,7 @@ int testVectorSerdes(const std::vector<T> &in,
> ControlSerializer *cs = nullptr)
> {
> std::vector<uint8_t> buf;
> - std::vector<FileDescriptor> fds;
> + std::vector<SharedFD> fds;
>
> std::tie(buf, fds) = IPADataSerializer<std::vector<T>>::serialize(in, cs);
> std::vector<T> out = IPADataSerializer<std::vector<T>>::deserialize(buf, fds, cs);
> @@ -92,7 +92,7 @@ int testMapSerdes(const std::map<K, V> &in,
> ControlSerializer *cs = nullptr)
> {
> std::vector<uint8_t> buf;
> - std::vector<FileDescriptor> fds;
> + std::vector<SharedFD> fds;
>
> std::tie(buf, fds) = IPADataSerializer<std::map<K, V>>::serialize(in, cs);
> std::map<K, V> out = IPADataSerializer<std::map<K, V>>::deserialize(buf, fds, cs);
> @@ -198,7 +198,7 @@ private:
> ControlSerializer cs(ControlSerializer::Role::Proxy);
>
> /*
> - * We don't test FileDescriptor serdes because it dup()s, so we
> + * We don't test SharedFD serdes because it dup()s, so we
> * can't check for equality.
> */
> std::vector<uint8_t> vecUint8 = { 1, 2, 3, 4, 5, 6 };
> @@ -219,7 +219,7 @@ private:
> };
>
> std::vector<uint8_t> buf;
> - std::vector<FileDescriptor> fds;
> + std::vector<SharedFD> fds;
>
> if (testVectorSerdes(vecUint8) != TestPass)
> return TestFail;
> @@ -291,7 +291,7 @@ private:
> { { "a", { 1, 2, 3 } }, { "b", { 4, 5, 6 } }, { "c", { 7, 8, 9 } } };
>
> std::vector<uint8_t> buf;
> - std::vector<FileDescriptor> fds;
> + std::vector<SharedFD> fds;
>
> if (testMapSerdes(mapUintStr) != TestPass)
> return TestFail;
> @@ -359,7 +359,7 @@ private:
> std::string strEmpty = "";
>
> std::vector<uint8_t> buf;
> - std::vector<FileDescriptor> fds;
> + std::vector<SharedFD> fds;
>
> if (testPodSerdes(u32min) != TestPass)
> return TestFail;
> diff --git a/test/file-descriptor.cpp b/test/shared-fd.cpp
> similarity index 80%
> rename from test/file-descriptor.cpp
> rename to test/shared-fd.cpp
> index 76badc4c5fad..60e5d0aaa395 100644
> --- a/test/file-descriptor.cpp
> +++ b/test/shared-fd.cpp
> @@ -2,7 +2,7 @@
> /*
> * Copyright (C) 2019, Google Inc.
> *
> - * file_descriptor.cpp - FileDescriptor test
> + * shared_fd.cpp - SharedFD test
> */
>
> #include <fcntl.h>
> @@ -11,7 +11,7 @@
> #include <sys/types.h>
> #include <unistd.h>
>
> -#include <libcamera/base/file_descriptor.h>
> +#include <libcamera/base/shared_fd.h>
> #include <libcamera/base/utils.h>
>
> #include "test.h"
> @@ -19,7 +19,7 @@
> using namespace libcamera;
> using namespace std;
>
> -class FileDescriptorTest : public Test
> +class SharedFDTest : public Test
> {
> protected:
> int init()
> @@ -43,8 +43,8 @@ protected:
>
> int run()
> {
> - /* Test creating empty FileDescriptor. */
> - desc1_ = new FileDescriptor();
> + /* Test creating empty SharedFD. */
> + desc1_ = new SharedFD();
>
> if (desc1_->fd() != -1) {
> std::cout << "Failed fd numerical check (default constructor)"
> @@ -56,10 +56,10 @@ protected:
> desc1_ = nullptr;
>
> /*
> - * Test creating FileDescriptor by copying numerical file
> + * Test creating SharedFD by copying numerical file
> * descriptor.
> */
> - desc1_ = new FileDescriptor(fd_);
> + desc1_ = new SharedFD(fd_);
> if (desc1_->fd() == fd_) {
> std::cout << "Failed fd numerical check (lvalue ref constructor)"
> << std::endl;
> @@ -84,13 +84,13 @@ protected:
> }
>
> /*
> - * Test creating FileDescriptor by taking ownership of
> + * Test creating SharedFD by taking ownership of
> * numerical file descriptor.
> */
> int dupFd = dup(fd_);
> int dupFdCopy = dupFd;
>
> - desc1_ = new FileDescriptor(std::move(dupFd));
> + desc1_ = new SharedFD(std::move(dupFd));
> if (desc1_->fd() != dupFdCopy) {
> std::cout << "Failed fd numerical check (rvalue ref constructor)"
> << std::endl;
> @@ -114,9 +114,9 @@ protected:
> return TestFail;
> }
>
> - /* Test creating FileDescriptor from other FileDescriptor. */
> - desc1_ = new FileDescriptor(fd_);
> - desc2_ = new FileDescriptor(*desc1_);
> + /* Test creating SharedFD from other SharedFD. */
> + desc1_ = new SharedFD(fd_);
> + desc2_ = new SharedFD(*desc1_);
>
> if (desc1_->fd() == fd_ || desc2_->fd() == fd_ || desc1_->fd() != desc2_->fd()) {
> std::cout << "Failed fd numerical check (copy constructor)"
> @@ -142,10 +142,10 @@ protected:
> delete desc2_;
> desc2_ = nullptr;
>
> - /* Test creating FileDescriptor by taking over other FileDescriptor. */
> - desc1_ = new FileDescriptor(fd_);
> + /* Test creating SharedFD by taking over other SharedFD. */
> + desc1_ = new SharedFD(fd_);
> fd = desc1_->fd();
> - desc2_ = new FileDescriptor(std::move(*desc1_));
> + desc2_ = new SharedFD(std::move(*desc1_));
>
> if (desc1_->fd() != -1 || desc2_->fd() != fd) {
> std::cout << "Failed fd numerical check (move constructor)"
> @@ -164,9 +164,9 @@ protected:
> delete desc2_;
> desc2_ = nullptr;
>
> - /* Test creating FileDescriptor by copy assignment. */
> - desc1_ = new FileDescriptor();
> - desc2_ = new FileDescriptor(fd_);
> + /* Test creating SharedFD by copy assignment. */
> + desc1_ = new SharedFD();
> + desc2_ = new SharedFD(fd_);
>
> fd = desc2_->fd();
> *desc1_ = *desc2_;
> @@ -188,9 +188,9 @@ protected:
> delete desc2_;
> desc2_ = nullptr;
>
> - /* Test creating FileDescriptor by move assignment. */
> - desc1_ = new FileDescriptor();
> - desc2_ = new FileDescriptor(fd_);
> + /* Test creating SharedFD by move assignment. */
> + desc1_ = new SharedFD();
> + desc2_ = new SharedFD(fd_);
>
> fd = desc2_->fd();
> *desc1_ = std::move(*desc2_);
> @@ -237,7 +237,7 @@ private:
>
> int fd_;
> ino_t inodeNr_;
> - FileDescriptor *desc1_, *desc2_;
> + SharedFD *desc1_, *desc2_;
> };
>
> -TEST_REGISTER(FileDescriptorTest)
> +TEST_REGISTER(SharedFDTest)
> diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl
> index d856339aa9ee..c37c4941b528 100644
> --- a/utils/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl
> +++ b/utils/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl
> @@ -237,7 +237,7 @@ void {{proxy_name}}::recvMessage(const IPCMessage &data)
> void {{proxy_name}}::{{method.mojom_name}}IPC(
> std::vector<uint8_t>::const_iterator data,
> size_t dataSize,
> - [[maybe_unused]] const std::vector<FileDescriptor> &fds)
> + [[maybe_unused]] const std::vector<SharedFD> &fds)
> {
> {%- for param in method.parameters %}
> {{param|name}} {{param.mojom_name}};
> diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl
> index ce396c183d0c..c308dd10c7e5 100644
> --- a/utils/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl
> +++ b/utils/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl
> @@ -64,7 +64,7 @@ private:
> void {{method.mojom_name}}IPC(
> std::vector<uint8_t>::const_iterator data,
> size_t dataSize,
> - const std::vector<FileDescriptor> &fds);
> + const std::vector<SharedFD> &fds);
> {% endfor %}
>
> /* Helper class to invoke async functions in another thread. */
> diff --git a/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl b/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl
> index ebcd2aaaafae..bac826a74c2d 100644
> --- a/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl
> +++ b/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl
> @@ -54,7 +54,7 @@
> {%- for param in params %}
> std::vector<uint8_t> {{param.mojom_name}}Buf;
> {%- if param|has_fd %}
> - std::vector<FileDescriptor> {{param.mojom_name}}Fds;
> + std::vector<SharedFD> {{param.mojom_name}}Fds;
> std::tie({{param.mojom_name}}Buf, {{param.mojom_name}}Fds) =
> {%- else %}
> std::tie({{param.mojom_name}}Buf, std::ignore) =
> diff --git a/utils/ipc/generators/libcamera_templates/serializer.tmpl b/utils/ipc/generators/libcamera_templates/serializer.tmpl
> index b8ef8e7b974e..77bae36fe6b7 100644
> --- a/utils/ipc/generators/libcamera_templates/serializer.tmpl
> +++ b/utils/ipc/generators/libcamera_templates/serializer.tmpl
> @@ -40,7 +40,7 @@
> retData.insert(retData.end(), {{field.mojom_name}}.begin(), {{field.mojom_name}}.end());
> {%- elif field|is_fd %}
> std::vector<uint8_t> {{field.mojom_name}};
> - std::vector<FileDescriptor> {{field.mojom_name}}Fds;
> + std::vector<SharedFD> {{field.mojom_name}}Fds;
> std::tie({{field.mojom_name}}, {{field.mojom_name}}Fds) =
> IPADataSerializer<{{field|name}}>::serialize(data.{{field.mojom_name}});
> retData.insert(retData.end(), {{field.mojom_name}}.begin(), {{field.mojom_name}}.end());
> @@ -58,7 +58,7 @@
> {%- elif field|is_plain_struct or field|is_array or field|is_map or field|is_str %}
> std::vector<uint8_t> {{field.mojom_name}};
> {%- if field|has_fd %}
> - std::vector<FileDescriptor> {{field.mojom_name}}Fds;
> + std::vector<SharedFD> {{field.mojom_name}}Fds;
> std::tie({{field.mojom_name}}, {{field.mojom_name}}Fds) =
> {%- else %}
> std::tie({{field.mojom_name}}, std::ignore) =
> @@ -177,7 +177,7 @@
> # \a struct.
> #}
> {%- macro serializer(struct, namespace) %}
> - static std::tuple<std::vector<uint8_t>, std::vector<FileDescriptor>>
> + static std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
> serialize(const {{struct|name_full}} &data,
> {%- if struct|needs_control_serializer %}
> ControlSerializer *cs)
> @@ -187,7 +187,7 @@
> {
> std::vector<uint8_t> retData;
> {%- if struct|has_fd %}
> - std::vector<FileDescriptor> retFds;
> + std::vector<SharedFD> retFds;
> {%- endif %}
> {%- for field in struct.fields %}
> {{serializer_field(field, namespace, loop)}}
> @@ -210,7 +210,7 @@
> {%- macro deserializer_fd(struct, namespace) %}
> static {{struct|name_full}}
> deserialize(std::vector<uint8_t> &data,
> - std::vector<FileDescriptor> &fds,
> + std::vector<SharedFD> &fds,
> {%- if struct|needs_control_serializer %}
> ControlSerializer *cs)
> {%- else %}
> @@ -224,8 +224,8 @@
> static {{struct|name_full}}
> deserialize(std::vector<uint8_t>::const_iterator dataBegin,
> std::vector<uint8_t>::const_iterator dataEnd,
> - std::vector<FileDescriptor>::const_iterator fdsBegin,
> - std::vector<FileDescriptor>::const_iterator fdsEnd,
> + std::vector<SharedFD>::const_iterator fdsBegin,
> + std::vector<SharedFD>::const_iterator fdsEnd,
> {%- if struct|needs_control_serializer %}
> ControlSerializer *cs)
> {%- else %}
> @@ -234,7 +234,7 @@
> {
> {{struct|name_full}} ret;
> std::vector<uint8_t>::const_iterator m = dataBegin;
> - std::vector<FileDescriptor>::const_iterator n = fdsBegin;
> + std::vector<SharedFD>::const_iterator n = fdsBegin;
>
> size_t dataSize = std::distance(dataBegin, dataEnd);
> [[maybe_unused]] size_t fdsSize = std::distance(fdsBegin, fdsEnd);
> @@ -255,7 +255,7 @@
> {%- macro deserializer_fd_simple(struct, namespace) %}
> static {{struct|name_full}}
> deserialize(std::vector<uint8_t> &data,
> - [[maybe_unused]] std::vector<FileDescriptor> &fds,
> + [[maybe_unused]] std::vector<SharedFD> &fds,
> ControlSerializer *cs = nullptr)
> {
> return IPADataSerializer<{{struct|name_full}}>::deserialize(data.cbegin(), data.cend(), cs);
> @@ -264,8 +264,8 @@
> static {{struct|name_full}}
> deserialize(std::vector<uint8_t>::const_iterator dataBegin,
> std::vector<uint8_t>::const_iterator dataEnd,
> - [[maybe_unused]] std::vector<FileDescriptor>::const_iterator fdsBegin,
> - [[maybe_unused]] std::vector<FileDescriptor>::const_iterator fdsEnd,
> + [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsBegin,
> + [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd,
> ControlSerializer *cs = nullptr)
> {
> return IPADataSerializer<{{struct|name_full}}>::deserialize(dataBegin, dataEnd, cs);
> diff --git a/utils/ipc/generators/mojom_libcamera_generator.py b/utils/ipc/generators/mojom_libcamera_generator.py
> index c609f4e5c062..753bfc734e56 100644
> --- a/utils/ipc/generators/mojom_libcamera_generator.py
> +++ b/utils/ipc/generators/mojom_libcamera_generator.py
> @@ -77,7 +77,7 @@ def GetDefaultValue(element):
> if mojom.IsEnumKind(element.kind):
> return f'static_cast<{element.kind.mojom_name}>(0)'
> if isinstance(element.kind, mojom.Struct) and \
> - element.kind.mojom_name == 'FileDescriptor':
> + element.kind.mojom_name == 'SharedFD':
> return '-1'
> return ''
>
> @@ -140,7 +140,7 @@ def HasFd(element):
> types = GetAllTypes(element)
> else:
> types = GetAllTypes(element.kind)
> - return "FileDescriptor" in types or (attrs is not None and "hasFd" in attrs)
> + return "SharedFD" in types or (attrs is not None and "hasFd" in attrs)
>
> def WithDefaultValues(element):
> return [x for x in element if HasDefaultValue(x)]
> @@ -221,7 +221,7 @@ def IsEnum(element):
> return mojom.IsEnumKind(element.kind)
>
> def IsFd(element):
> - return mojom.IsStructKind(element.kind) and element.kind.mojom_name == "FileDescriptor"
> + return mojom.IsStructKind(element.kind) and element.kind.mojom_name == "SharedFD"
>
> def IsMap(element):
> return mojom.IsMapKind(element.kind)
> --
> Regards,
>
> Laurent Pinchart
>
More information about the libcamera-devel
mailing list