diff options
author | Andrei Konovalov <andrey.konovalov.ynk@gmail.com> | 2024-04-16 11:13:42 +0200 |
---|---|---|
committer | Kieran Bingham <kieran.bingham@ideasonboard.com> | 2024-04-16 13:00:21 +0100 |
commit | 9a2d7d3b6ac289408c2db7de18a5889959eb147c (patch) | |
tree | 896b8e11a97f1afd7911edd776f05df3a076adf0 /include | |
parent | ce3c8a5082f492ef1aeac9b2a488ca94d413029d (diff) |
libcamera: shared_mem_object: Reorganize the code and document the SharedMemObject class
The SharedMemObject class template contains a fair amount of inline code
that does not depend on the template types T. To avoid duplicating it in
every template specialization, split that code to a separate base
SharedMem class.
We don't define copy semantics for the classes (we don't need one at the
moment) and we make them non-copyable since the default copy constructor
would lead to use-after-unmap.
Doxygen documentation by Dennis Bonke and Andrei Konovalov.
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Co-developed-by: Dennis Bonke <admin@dennisbonke.com>
Signed-off-by: Dennis Bonke <admin@dennisbonke.com>
Signed-off-by: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/libcamera/internal/shared_mem_object.h | 103 |
1 files changed, 53 insertions, 50 deletions
diff --git a/include/libcamera/internal/shared_mem_object.h b/include/libcamera/internal/shared_mem_object.h index a9970059..9b1d9393 100644 --- a/include/libcamera/internal/shared_mem_object.h +++ b/include/libcamera/internal/shared_mem_object.h @@ -1,85 +1,98 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* - * Copyright (C) 2023, Raspberry Pi Ltd + * Copyright (C) 2023 Raspberry Pi Ltd + * Copyright (C) 2024 Andrei Konovalov + * Copyright (C) 2024 Dennis Bonke * - * shared_mem_object.h - Helper class for shared memory allocations + * shared_mem_object.h - Helpers for shared memory allocations */ #pragma once -#include <fcntl.h> #include <stddef.h> +#include <stdint.h> #include <string> #include <sys/mman.h> -#include <sys/stat.h> -#include <unistd.h> +#include <type_traits> #include <utility> #include <libcamera/base/class.h> #include <libcamera/base/shared_fd.h> +#include <libcamera/base/span.h> namespace libcamera { -template<class T> -class SharedMemObject +class SharedMem { public: - static constexpr std::size_t kSize = sizeof(T); + SharedMem(); - SharedMemObject() - : obj_(nullptr) + SharedMem(const std::string &name, std::size_t size); + SharedMem(SharedMem &&rhs); + + virtual ~SharedMem(); + + SharedMem &operator=(SharedMem &&rhs); + + const SharedFD &fd() const { + return fd_; } - template<class... Args> - SharedMemObject(const std::string &name, Args &&...args) - : name_(name), obj_(nullptr) + Span<uint8_t> mem() const { - void *mem; - int ret; + return mem_; + } - ret = memfd_create(name_.c_str(), MFD_CLOEXEC); - if (ret < 0) - return; + explicit operator bool() const + { + return !mem_.empty(); + } - fd_ = SharedFD(std::move(ret)); - if (!fd_.isValid()) - return; +private: + LIBCAMERA_DISABLE_COPY(SharedMem) - ret = ftruncate(fd_.get(), kSize); - if (ret < 0) - return; + SharedFD fd_; - mem = mmap(nullptr, kSize, PROT_READ | PROT_WRITE, MAP_SHARED, - fd_.get(), 0); - if (mem == MAP_FAILED) + Span<uint8_t> mem_; +}; + +template<class T, typename = std::enable_if_t<std::is_standard_layout<T>::value>> +class SharedMemObject : public SharedMem +{ +public: + static constexpr std::size_t kSize = sizeof(T); + + SharedMemObject() + : SharedMem(), obj_(nullptr) + { + } + + template<class... Args> + SharedMemObject(const std::string &name, Args &&...args) + : SharedMem(name, kSize), obj_(nullptr) + { + if (mem().empty()) return; - obj_ = new (mem) T(std::forward<Args>(args)...); + obj_ = new (mem().data()) T(std::forward<Args>(args)...); } SharedMemObject(SharedMemObject<T> &&rhs) + : SharedMem(std::move(rhs)) { - this->name_ = std::move(rhs.name_); - this->fd_ = std::move(rhs.fd_); this->obj_ = rhs.obj_; rhs.obj_ = nullptr; } ~SharedMemObject() { - if (obj_) { + if (obj_) obj_->~T(); - munmap(obj_, kSize); - } } - /* Make SharedMemObject non-copyable for now. */ - LIBCAMERA_DISABLE_COPY(SharedMemObject) - SharedMemObject<T> &operator=(SharedMemObject<T> &&rhs) { - this->name_ = std::move(rhs.name_); - this->fd_ = std::move(rhs.fd_); + SharedMem::operator=(std::move(rhs)); this->obj_ = rhs.obj_; rhs.obj_ = nullptr; return *this; @@ -105,19 +118,9 @@ public: return *obj_; } - const SharedFD &fd() const - { - return fd_; - } - - explicit operator bool() const - { - return !!obj_; - } - private: - std::string name_; - SharedFD fd_; + LIBCAMERA_DISABLE_COPY(SharedMemObject) + T *obj_; }; |