From 9a2d7d3b6ac289408c2db7de18a5889959eb147c Mon Sep 17 00:00:00 2001 From: Andrei Konovalov Date: Tue, 16 Apr 2024 11:13:42 +0200 Subject: 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 Reviewed-by: Milan Zamazal Reviewed-by: Laurent Pinchart Co-developed-by: Dennis Bonke Signed-off-by: Dennis Bonke Signed-off-by: Andrei Konovalov Signed-off-by: Hans de Goede Signed-off-by: Kieran Bingham --- include/libcamera/internal/shared_mem_object.h | 103 +++++++++++++------------ 1 file changed, 53 insertions(+), 50 deletions(-) (limited to 'include') 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 #include +#include #include #include -#include -#include +#include #include #include #include +#include namespace libcamera { -template -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 - SharedMemObject(const std::string &name, Args &&...args) - : name_(name), obj_(nullptr) + Span 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 mem_; +}; + +template::value>> +class SharedMemObject : public SharedMem +{ +public: + static constexpr std::size_t kSize = sizeof(T); + + SharedMemObject() + : SharedMem(), obj_(nullptr) + { + } + + template + SharedMemObject(const std::string &name, Args &&...args) + : SharedMem(name, kSize), obj_(nullptr) + { + if (mem().empty()) return; - obj_ = new (mem) T(std::forward(args)...); + obj_ = new (mem().data()) T(std::forward(args)...); } SharedMemObject(SharedMemObject &&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 &operator=(SharedMemObject &&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_; }; -- cgit v1.2.1