[{"id":28671,"web_url":"https://patchwork.libcamera.org/comment/28671/","msgid":"<87plwxdfcu.fsf@redhat.com>","date":"2024-02-15T13:30:41","subject":"Re: [PATCH v3 05/16] libcamera: shared_mem_object: reorganize the\n\tcode and document the SharedMemObject class","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Hans de Goede <hdegoede@redhat.com> writes:\n\n> From: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>\n>\n> Split the parts which doesn't otherwise depend on the type T or\n> arguments Args out of the SharedMemObject class into a new\n> SharedMem class.\n>\n> Doxygen documentation by Dennis Bonke and Andrei Konovalov.\n>\n> Reviewed-by: Pavel Machek <pavel@ucw.cz>\n> Co-developed-by: Dennis Bonke <admin@dennisbonke.com>\n> Signed-off-by: Dennis Bonke <admin@dennisbonke.com>\n> Signed-off-by: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>\n> ---\n>  .../libcamera/internal/shared_mem_object.h    |  92 ++++++---\n>  src/libcamera/meson.build                     |   1 +\n>  src/libcamera/shared_mem_object.cpp           | 191 ++++++++++++++++++\n>  3 files changed, 253 insertions(+), 31 deletions(-)\n>  create mode 100644 src/libcamera/shared_mem_object.cpp\n>\n> diff --git a/include/libcamera/internal/shared_mem_object.h b/include/libcamera/internal/shared_mem_object.h\n> index bfb639ee..a4de6500 100644\n> --- a/include/libcamera/internal/shared_mem_object.h\n> +++ b/include/libcamera/internal/shared_mem_object.h\n> @@ -7,11 +7,8 @@\n>  #pragma once\n>  \n>  #include <cstddef>\n> -#include <fcntl.h>\n>  #include <string>\n>  #include <sys/mman.h>\n> -#include <sys/stat.h>\n> -#include <unistd.h>\n>  #include <utility>\n>  \n>  #include <libcamera/base/class.h>\n> @@ -19,6 +16,59 @@\n>  \n>  namespace libcamera {\n>  \n> +class SharedMem\n> +{\n> +public:\n> +\tSharedMem()\n> +\t\t: mem_(nullptr)\n> +\t{\n> +\t}\n> +\n> +\tSharedMem(const std::string &name, std::size_t size);\n> +\n> +\tSharedMem(SharedMem &&rhs)\n> +\t{\n> +\t\tthis->name_ = std::move(rhs.name_);\n> +\t\tthis->fd_ = std::move(rhs.fd_);\n> +\t\tthis->mem_ = rhs.mem_;\n> +\t\trhs.mem_ = nullptr;\n> +\t}\n> +\n> +\t~SharedMem()\n> +\t{\n> +\t\tif (mem_)\n> +\t\t\tmunmap(mem_, size_);\n> +\t}\n> +\n> +\t/* Make SharedMem non-copyable for now. */\n> +\tLIBCAMERA_DISABLE_COPY(SharedMem)\n> +\n> +\tSharedMem &operator=(SharedMem &&rhs)\n> +\t{\n> +\t\tthis->name_ = std::move(rhs.name_);\n> +\t\tthis->fd_ = std::move(rhs.fd_);\n> +\t\tthis->mem_ = rhs.mem_;\n> +\t\trhs.mem_ = nullptr;\n> +\t\treturn *this;\n> +\t}\n> +\n> +\tconst SharedFD &fd() const\n> +\t{\n> +\t\treturn fd_;\n> +\t}\n> +\n> +\tvoid *mem() const\n> +\t{\n> +\t\treturn mem_;\n> +\t}\n> +\n> +private:\n> +\tstd::string name_;\n> +\tSharedFD fd_;\n> +\tsize_t size_;\n> +\tvoid *mem_;\n> +};\n> +\n>  template<class T>\n>  class SharedMemObject\n>  {\n> @@ -32,26 +82,11 @@ public:\n>  \n>  \ttemplate<class... Args>\n>  \tSharedMemObject(const std::string &name, Args &&...args)\n> -\t\t: name_(name), obj_(nullptr)\n> +\t\t: shMem_(name, SIZE), obj_(nullptr)\n>  \t{\n> -\t\tvoid *mem;\n> -\t\tint ret;\n> +\t\tvoid *mem = shMem_.mem();\n>  \n> -\t\tret = memfd_create(name_.c_str(), MFD_CLOEXEC);\n> -\t\tif (ret < 0)\n> -\t\t\treturn;\n> -\n> -\t\tfd_ = SharedFD(std::move(ret));\n> -\t\tif (!fd_.isValid())\n> -\t\t\treturn;\n> -\n> -\t\tret = ftruncate(fd_.get(), SIZE);\n> -\t\tif (ret < 0)\n> -\t\t\treturn;\n> -\n> -\t\tmem = mmap(nullptr, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,\n> -\t\t\t   fd_.get(), 0);\n> -\t\tif (mem == MAP_FAILED)\n> +\t\tif (mem == nullptr)\n>  \t\t\treturn;\n>  \n>  \t\tobj_ = new (mem) T(std::forward<Args>(args)...);\n> @@ -59,18 +94,15 @@ public:\n>  \n>  \tSharedMemObject(SharedMemObject<T> &&rhs)\n>  \t{\n> -\t\tthis->name_ = std::move(rhs.name_);\n> -\t\tthis->fd_ = std::move(rhs.fd_);\n> +\t\tthis->shMem_ = std::move(rhs.shMem_);\n>  \t\tthis->obj_ = rhs.obj_;\n>  \t\trhs.obj_ = nullptr;\n>  \t}\n>  \n>  \t~SharedMemObject()\n>  \t{\n> -\t\tif (obj_) {\n> +\t\tif (obj_)\n>  \t\t\tobj_->~T();\n> -\t\t\tmunmap(obj_, SIZE);\n> -\t\t}\n>  \t}\n>  \n>  \t/* Make SharedMemObject non-copyable for now. */\n> @@ -78,8 +110,7 @@ public:\n>  \n>  \tSharedMemObject<T> &operator=(SharedMemObject<T> &&rhs)\n>  \t{\n> -\t\tthis->name_ = std::move(rhs.name_);\n> -\t\tthis->fd_ = std::move(rhs.fd_);\n> +\t\tthis->shMem_ = std::move(rhs.shMem_);\n>  \t\tthis->obj_ = rhs.obj_;\n>  \t\trhs.obj_ = nullptr;\n>  \t\treturn *this;\n> @@ -107,7 +138,7 @@ public:\n>  \n>  \tconst SharedFD &fd() const\n>  \t{\n> -\t\treturn fd_;\n> +\t\treturn shMem_.fd();\n>  \t}\n>  \n>  \texplicit operator bool() const\n> @@ -116,8 +147,7 @@ public:\n>  \t}\n>  \n>  private:\n> -\tstd::string name_;\n> -\tSharedFD fd_;\n> +\tSharedMem shMem_;\n>  \tT *obj_;\n>  };\n>  \n> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n> index 3c5e43df..94a95ae3 100644\n> --- a/src/libcamera/meson.build\n> +++ b/src/libcamera/meson.build\n> @@ -41,6 +41,7 @@ libcamera_sources = files([\n>      'process.cpp',\n>      'pub_key.cpp',\n>      'request.cpp',\n> +    'shared_mem_object.cpp',\n>      'source_paths.cpp',\n>      'stream.cpp',\n>      'sysfs.cpp',\n> diff --git a/src/libcamera/shared_mem_object.cpp b/src/libcamera/shared_mem_object.cpp\n> new file mode 100644\n> index 00000000..06bbee38\n> --- /dev/null\n> +++ b/src/libcamera/shared_mem_object.cpp\n> @@ -0,0 +1,191 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2023, Raspberry Pi Ltd\n> + *\n> + * shared_mem_object.cpp - Helper class for shared memory allocations\n> + */\n> +\n> +#include \"libcamera/internal/shared_mem_object.h\"\n> +\n> +#include <sys/types.h>\n> +#include <unistd.h>\n> +\n> +/**\n> + * \\file shared_mem_object.cpp\n> + * \\brief Helper class for shared memory allocations\n> + */\n> +\n> +namespace libcamera {\n> +\n> +/**\n> + * \\class SharedMem\n> + * \\brief Helper class for allocating shared memory\n> + *\n> + * Memory is allocated and exposed as a SharedFD for use across IPC boundaries.\n> + *\n> + * SharedMem allocates the shared memory of the given size and maps it.\n> + * To check that the shared memory was allocated and mapped successfully, one\n> + * needs to verify that the pointer to the shared memory returned by SharedMem::mem()\n> + * is not nullptr.\n> + *\n> + * To access the shared memory from another process the SharedFD should be passed\n> + * to that process, and then the shared memory should be mapped into that process\n> + * address space by calling mmap().\n> + *\n> + * A single memfd is created for every SharedMem. If there is a need to allocate\n> + * a large number of objects in shared memory, these objects should be grouped\n> + * together and use the shared memory allocated by a single SharedMem object if\n> + * possible. This will help to minimize the number of created memfd's.\n> + */\n> +\n> +/**\n> + * \\fn SharedMem::SharedMem(const std::string &name, std::size_t size)\n> + * \\brief Contstructor for the SharedMem\n> + * \\param[in] name Name of the SharedMem\n> + * \\param[in] size Size of the shared memory to allocate and map\n> + */\n> +\n> +/**\n> + * \\fn SharedMem::SharedMem(SharedMem &&rhs)\n> + * \\brief Move constructor for SharedMem\n> + * \\param[in] rhs The object to move\n> + */\n> +\n> +/**\n> + * \\fn SharedMem::~SharedMem()\n> + * \\brief SharedMem destructor\n> + *\n> + * Unmaps the allocated shared memory. Decrements the shared memory descriptor use\n> + * count.\n> + */\n> +\n> +/**\n> + * \\fn SharedMem &SharedMem::operator=(SharedMem &&rhs)\n> + * \\brief Move constructor for SharedMem\n> + * \\param[in] rhs The object to move\n> + */\n> +\n> +/**\n> + * \\fn const SharedFD &SharedMem::fd() const\n> + * \\brief Gets the file descriptor for the underlaying shared memory\n> + * \\return The file descriptor\n> + */\n> +\n> +/**\n> + * \\fn void *SharedMem::mem() const\n> + * \\brief Gets the pointer to the underlaying shared memory\n> + * \\return The pointer to the shared memory\n> + */\n> +\n> +SharedMem::SharedMem(const std::string &name, std::size_t size)\n> +\t: name_(name), size_(size), mem_(nullptr)\n> +{\n> +\tint fd = memfd_create(name_.c_str(), MFD_CLOEXEC);\n> +\tif (fd < 0)\n> +\t\treturn;\n> +\n> +\tfd_ = SharedFD(std::move(fd));\n> +\tif (!fd_.isValid())\n> +\t\treturn;\n> +\n> +\tif (ftruncate(fd_.get(), size_) < 0)\n> +\t\treturn;\n> +\n> +\tmem_ = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED,\n> +\t\t    fd_.get(), 0);\n> +\tif (mem_ == MAP_FAILED)\n> +\t\tmem_ = nullptr;\n> +}\n> +\n> +/**\n> + * \\class SharedMemObject\n> + * \\brief Helper class for allocating objects in shared memory\n> + *\n> + * Memory is allocated and exposed as a SharedFD for use across IPC boundaries.\n> + *\n> + * Given the type of the object to be created in shared memory and the arguments\n> + * to pass to this object's constructor, SharedMemObject allocates the shared memory\n> + * of the size of the object and constructs the object in this memory. To check that\n> + * the SharedMemObject was created successfully, one needs to verify that the\n> + * underlying SharedFD (the reference to it is returned by SharedMemObject::fd() member\n> + * function) is valid. The object created in the shared memory can be accessed using\n> + * the SharedMemObject::operator*() indirection operator. Its members can be accessed\n> + * with the SharedMemObject::operator->() member of pointer operator.\n\nBut it can still happen that SharedMemObject::fd() is all right but the object\nreturned from the operators is nullptr, right?  It would be good to clarify this\nand refer to the bool operator here.\n\n> \n> + *\n> + * To access the object from another process the SharedFD should be passed to that\n> + * process, and the shared memory should be mapped by calling mmap().\n> + *\n> + * A single memfd is created for every SharedMemObject. If there is a need to allocate\n> + * a large number of objects in shared memory, these objects should be grouped into a\n> + * single large object to keep the number of created memfd's reasonably small.\n> + */\n> +\n> +/**\n> + * \\var SharedMemObject::SIZE\n> + * \\brief The size of the object that is going to be stored here\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject< T >::SharedMemObject(const std::string &name, Args &&...args)\n> + * \\brief Contstructor for the SharedMemObject\n             ^^^^^^^^^^^^\n\nConstructor\n\n> + * \\param[in] name Name of the SharedMemObject\n> + * \\param[in] args Args to pass to the constructor of the object in shared memory\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject::SharedMemObject(SharedMemObject<T> &&rhs)\n> + * \\brief Move constructor for SharedMemObject\n> + * \\param[in] rhs The object to move\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject::~SharedMemObject()\n> + * \\brief SharedMemObject destructor\n> + *\n> + * Destroys the object created in the shared memory and then unmaps the shared memory.\n> + * Decrements the shared memory descriptor use count.\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject::operator=(SharedMemObject<T> &&rhs)\n> + * \\brief Operator= for SharedMemObject\n> + * \\param[in] rhs The SharedMemObject object to take the data from\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject::operator->()\n> + * \\brief Operator-> for SharedMemObject\n> + * \\return The pointer to the object\n> + */\n> +\n> +/**\n> + * \\fn const T *SharedMemObject::operator->() const\n> + * \\brief Operator-> for SharedMemObject\n> + * \\return The pointer to the const object\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject::operator*()\n> + * \\brief Operator* for SharedMemObject\n> + * \\return The reference to the object\n> + */\n> +\n> +/**\n> + * \\fn const T &SharedMemObject::operator*() const\n> + * \\brief Operator* for SharedMemObject\n> + * \\return Const reference to the object\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject::fd()\n> + * \\brief Gets the file descriptor for the underlaying storage file\n> + * \\return The shared memory file descriptor (as SharedFD)\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject::operator bool()\n> + * \\brief Operator bool() for SharedMemObject\n> + * \\return True if the object was created OK in the shared memory, false otherwise\n> + */\n> +\n> +} // namespace libcamera","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id B67F7BDE17\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 15 Feb 2024 13:30:48 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2744562805;\n\tThu, 15 Feb 2024 14:30:48 +0100 (CET)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.133.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 93FA461CB0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 15 Feb 2024 14:30:46 +0100 (CET)","from mail-wm1-f72.google.com (mail-wm1-f72.google.com\n\t[209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-184-G_pIg4JRPVexXeULB3JuSg-1; Thu, 15 Feb 2024 08:30:44 -0500","by mail-wm1-f72.google.com with SMTP id\n\t5b1f17b1804b1-410dfd0e1caso4730695e9.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 15 Feb 2024 05:30:44 -0800 (PST)","from nuthatch (nat-pool-brq-t.redhat.com. [213.175.37.10])\n\tby smtp.gmail.com with ESMTPSA id\n\tt18-20020a1c7712000000b004122fbf9253sm162283wmi.39.2024.02.15.05.30.41\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tThu, 15 Feb 2024 05:30:41 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"hyKd+8xZ\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1708003845;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=PgYO9WY7D9gOKnBxFnEQW5C0vJ3oYsH5udUohFd2kjk=;\n\tb=hyKd+8xZ2lHe5AnMMpK/s+66nLeOIwvrxTIP6jOd322OAvhx4vnfzkyTn1oHA3STHugDGy\n\tZF0bYI0VzwBn2DIXDphKPrh2pV1gsjKutT8aV+Aw1ADVAegIzJu1NFtGMjg+G51tpfj9XQ\n\t2meS6G4JvussMTovS8moQK3HeZ9mAdo=","X-MC-Unique":"G_pIg4JRPVexXeULB3JuSg-1","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1708003843; x=1708608643;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=PgYO9WY7D9gOKnBxFnEQW5C0vJ3oYsH5udUohFd2kjk=;\n\tb=YyUJrZt84Ts/4ZwIKDrgW75aOLM0YZsBmDBxKHo8JMkvDT1h4WoM0crCEIH+cN6yc/\n\tBoDECB3SsUA0G5fVyjJSixoF9TnZRTdVT/y0lMf8PQ5hAR2hXvdRY6x2UA1fUvCGa1Ez\n\tfPsq6yLKFiV5IZJTZxNeeyY/ZLmDU1QiMSOZ8H0+ALEon2/qbpWiY6/bD3SLl9BbfXlx\n\tdbOpzRadvgUva/3DHj143GmSRCJaypUk+4RF+ZPEGtUSZ4pBTS9nbl+w4KlXIFiv2NEW\n\t+bRY7qro/BmSxVy0YP0uY9N8ptcjX3i2ijevBtNIFR2KdKJp5pFYFyfN4z9jA2Du8fbt\n\tbJfg==","X-Gm-Message-State":"AOJu0Yxz/QznTDOG0BXbBw2MUFj+ewiNsy5aplodBz77FMBoKBPGOILZ\n\tb7VEhg7r1T7/mfhkcylxS3809vl4F/s6nLjvTnzeTRFsnlfB/LhA3n+opO4tsi34kcqmPt3WWNW\n\tVIvHWBs5ZUFpBqH53I3bwugstrguK1KiEYwnslsfKNJg5U7dMbwUpCQWqo1EsMWl/ieoYvew=","X-Received":["by 2002:a05:600c:260e:b0:410:6a8b:6937 with SMTP id\n\th14-20020a05600c260e00b004106a8b6937mr1460943wma.37.1708003842989; \n\tThu, 15 Feb 2024 05:30:42 -0800 (PST)","by 2002:a05:600c:260e:b0:410:6a8b:6937 with SMTP id\n\th14-20020a05600c260e00b004106a8b6937mr1460922wma.37.1708003842587; \n\tThu, 15 Feb 2024 05:30:42 -0800 (PST)"],"X-Google-Smtp-Source":"AGHT+IFLWl4jkRBUZy+s7rVngEcb3gesz1el5/8ei+NeU4KrCWDlokvkd3vYD2MfhXBdVyTuNpshZg==","From":"Milan Zamazal <mzamazal@redhat.com>","To":"Hans de Goede <hdegoede@redhat.com>","Subject":"Re: [PATCH v3 05/16] libcamera: shared_mem_object: reorganize the\n\tcode and document the SharedMemObject class","In-Reply-To":"<20240214170122.60754-6-hdegoede@redhat.com> (Hans de Goede's\n\tmessage of \"Wed, 14 Feb 2024 18:01:09 +0100\")","References":"<20240214170122.60754-1-hdegoede@redhat.com>\n\t<20240214170122.60754-6-hdegoede@redhat.com>","Date":"Thu, 15 Feb 2024 14:30:41 +0100","Message-ID":"<87plwxdfcu.fsf@redhat.com>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"Maxime Ripard <mripard@redhat.com>, libcamera-devel@lists.libcamera.org, \n\tPavel Machek <pavel@ucw.cz>,\n\tBryan O'Donoghue <bryan.odonoghue@linaro.org>, \n\tDennis Bonke <admin@dennisbonke.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":28672,"web_url":"https://patchwork.libcamera.org/comment/28672/","msgid":"<CAEmqJPoUDq50Z3Xw7oi+=TWq5X9BVgBEQTHG=wn_G2SLnFKPBQ@mail.gmail.com>","date":"2024-02-15T13:39:09","subject":"Re: [PATCH v3 05/16] libcamera: shared_mem_object: reorganize the\n\tcode and document the SharedMemObject class","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/people/34/","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"content":"Hi Hans,\n\nOn Wed, 14 Feb 2024 at 17:01, Hans de Goede <hdegoede@redhat.com> wrote:\n>\n> From: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>\n>\n> Split the parts which doesn't otherwise depend on the type T or\n> arguments Args out of the SharedMemObject class into a new\n> SharedMem class.\n>\n> Doxygen documentation by Dennis Bonke and Andrei Konovalov.\n>\n> Reviewed-by: Pavel Machek <pavel@ucw.cz>\n> Co-developed-by: Dennis Bonke <admin@dennisbonke.com>\n> Signed-off-by: Dennis Bonke <admin@dennisbonke.com>\n> Signed-off-by: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>\n> ---\n>  .../libcamera/internal/shared_mem_object.h    |  92 ++++++---\n>  src/libcamera/meson.build                     |   1 +\n>  src/libcamera/shared_mem_object.cpp           | 191 ++++++++++++++++++\n>  3 files changed, 253 insertions(+), 31 deletions(-)\n>  create mode 100644 src/libcamera/shared_mem_object.cpp\n>\n> diff --git a/include/libcamera/internal/shared_mem_object.h b/include/libcamera/internal/shared_mem_object.h\n> index bfb639ee..a4de6500 100644\n> --- a/include/libcamera/internal/shared_mem_object.h\n> +++ b/include/libcamera/internal/shared_mem_object.h\n> @@ -7,11 +7,8 @@\n>  #pragma once\n>\n>  #include <cstddef>\n> -#include <fcntl.h>\n>  #include <string>\n>  #include <sys/mman.h>\n> -#include <sys/stat.h>\n> -#include <unistd.h>\n>  #include <utility>\n>\n>  #include <libcamera/base/class.h>\n> @@ -19,6 +16,59 @@\n>\n>  namespace libcamera {\n>\n> +class SharedMem\n> +{\n> +public:\n> +       SharedMem()\n> +               : mem_(nullptr)\n> +       {\n> +       }\n> +\n> +       SharedMem(const std::string &name, std::size_t size);\n> +\n> +       SharedMem(SharedMem &&rhs)\n> +       {\n> +               this->name_ = std::move(rhs.name_);\n> +               this->fd_ = std::move(rhs.fd_);\n> +               this->mem_ = rhs.mem_;\n> +               rhs.mem_ = nullptr;\n> +       }\n> +\n> +       ~SharedMem()\n> +       {\n> +               if (mem_)\n> +                       munmap(mem_, size_);\n> +       }\n> +\n> +       /* Make SharedMem non-copyable for now. */\n> +       LIBCAMERA_DISABLE_COPY(SharedMem)\n> +\n> +       SharedMem &operator=(SharedMem &&rhs)\n> +       {\n> +               this->name_ = std::move(rhs.name_);\n> +               this->fd_ = std::move(rhs.fd_);\n> +               this->mem_ = rhs.mem_;\n> +               rhs.mem_ = nullptr;\n> +               return *this;\n> +       }\n> +\n> +       const SharedFD &fd() const\n> +       {\n> +               return fd_;\n> +       }\n> +\n> +       void *mem() const\n> +       {\n> +               return mem_;\n> +       }\n> +\n> +private:\n> +       std::string name_;\n> +       SharedFD fd_;\n> +       size_t size_;\n> +       void *mem_;\n> +};\n> +\n>  template<class T>\n>  class SharedMemObject\n\nWould it make sense to have SharedMemObject derived from SharedMem?\nThen you would only need a constructor and destructor implemented for\nSharedMemObject, and all other accessors can be through the base\nclass... i think?\n\n>  {\n> @@ -32,26 +82,11 @@ public:\n>\n>         template<class... Args>\n>         SharedMemObject(const std::string &name, Args &&...args)\n> -               : name_(name), obj_(nullptr)\n> +               : shMem_(name, SIZE), obj_(nullptr)\n>         {\n> -               void *mem;\n> -               int ret;\n> +               void *mem = shMem_.mem();\n>\n> -               ret = memfd_create(name_.c_str(), MFD_CLOEXEC);\n> -               if (ret < 0)\n> -                       return;\n> -\n> -               fd_ = SharedFD(std::move(ret));\n> -               if (!fd_.isValid())\n> -                       return;\n> -\n> -               ret = ftruncate(fd_.get(), SIZE);\n> -               if (ret < 0)\n> -                       return;\n> -\n> -               mem = mmap(nullptr, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,\n> -                          fd_.get(), 0);\n> -               if (mem == MAP_FAILED)\n> +               if (mem == nullptr)\n>                         return;\n>\n>                 obj_ = new (mem) T(std::forward<Args>(args)...);\n> @@ -59,18 +94,15 @@ public:\n>\n>         SharedMemObject(SharedMemObject<T> &&rhs)\n>         {\n> -               this->name_ = std::move(rhs.name_);\n> -               this->fd_ = std::move(rhs.fd_);\n> +               this->shMem_ = std::move(rhs.shMem_);\n>                 this->obj_ = rhs.obj_;\n>                 rhs.obj_ = nullptr;\n>         }\n>\n>         ~SharedMemObject()\n>         {\n> -               if (obj_) {\n> +               if (obj_)\n>                         obj_->~T();\n> -                       munmap(obj_, SIZE);\n> -               }\n>         }\n>\n>         /* Make SharedMemObject non-copyable for now. */\n> @@ -78,8 +110,7 @@ public:\n>\n>         SharedMemObject<T> &operator=(SharedMemObject<T> &&rhs)\n>         {\n> -               this->name_ = std::move(rhs.name_);\n> -               this->fd_ = std::move(rhs.fd_);\n> +               this->shMem_ = std::move(rhs.shMem_);\n>                 this->obj_ = rhs.obj_;\n>                 rhs.obj_ = nullptr;\n>                 return *this;\n> @@ -107,7 +138,7 @@ public:\n>\n>         const SharedFD &fd() const\n>         {\n> -               return fd_;\n> +               return shMem_.fd();\n>         }\n>\n>         explicit operator bool() const\n> @@ -116,8 +147,7 @@ public:\n>         }\n>\n>  private:\n> -       std::string name_;\n> -       SharedFD fd_;\n> +       SharedMem shMem_;\n>         T *obj_;\n>  };\n>\n> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n> index 3c5e43df..94a95ae3 100644\n> --- a/src/libcamera/meson.build\n> +++ b/src/libcamera/meson.build\n> @@ -41,6 +41,7 @@ libcamera_sources = files([\n>      'process.cpp',\n>      'pub_key.cpp',\n>      'request.cpp',\n> +    'shared_mem_object.cpp',\n>      'source_paths.cpp',\n>      'stream.cpp',\n>      'sysfs.cpp',\n> diff --git a/src/libcamera/shared_mem_object.cpp b/src/libcamera/shared_mem_object.cpp\n> new file mode 100644\n> index 00000000..06bbee38\n> --- /dev/null\n> +++ b/src/libcamera/shared_mem_object.cpp\n> @@ -0,0 +1,191 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2023, Raspberry Pi Ltd\n> + *\n> + * shared_mem_object.cpp - Helper class for shared memory allocations\n> + */\n> +\n> +#include \"libcamera/internal/shared_mem_object.h\"\n> +\n> +#include <sys/types.h>\n> +#include <unistd.h>\n> +\n> +/**\n> + * \\file shared_mem_object.cpp\n> + * \\brief Helper class for shared memory allocations\n> + */\n> +\n> +namespace libcamera {\n> +\n> +/**\n> + * \\class SharedMem\n> + * \\brief Helper class for allocating shared memory\n> + *\n> + * Memory is allocated and exposed as a SharedFD for use across IPC boundaries.\n> + *\n> + * SharedMem allocates the shared memory of the given size and maps it.\n> + * To check that the shared memory was allocated and mapped successfully, one\n> + * needs to verify that the pointer to the shared memory returned by SharedMem::mem()\n> + * is not nullptr.\n> + *\n> + * To access the shared memory from another process the SharedFD should be passed\n> + * to that process, and then the shared memory should be mapped into that process\n> + * address space by calling mmap().\n> + *\n> + * A single memfd is created for every SharedMem. If there is a need to allocate\n> + * a large number of objects in shared memory, these objects should be grouped\n> + * together and use the shared memory allocated by a single SharedMem object if\n> + * possible. This will help to minimize the number of created memfd's.\n> + */\n> +\n> +/**\n> + * \\fn SharedMem::SharedMem(const std::string &name, std::size_t size)\n> + * \\brief Contstructor for the SharedMem\n\ns/Contstructor/Constructor/\n\n> + * \\param[in] name Name of the SharedMem\n> + * \\param[in] size Size of the shared memory to allocate and map\n> + */\n> +\n> +/**\n> + * \\fn SharedMem::SharedMem(SharedMem &&rhs)\n> + * \\brief Move constructor for SharedMem\n> + * \\param[in] rhs The object to move\n> + */\n> +\n> +/**\n> + * \\fn SharedMem::~SharedMem()\n> + * \\brief SharedMem destructor\n> + *\n> + * Unmaps the allocated shared memory. Decrements the shared memory descriptor use\n> + * count.\n> + */\n> +\n> +/**\n> + * \\fn SharedMem &SharedMem::operator=(SharedMem &&rhs)\n> + * \\brief Move constructor for SharedMem\n> + * \\param[in] rhs The object to move\n> + */\n> +\n> +/**\n> + * \\fn const SharedFD &SharedMem::fd() const\n> + * \\brief Gets the file descriptor for the underlaying shared memory\n\ns/underlaying/underlying/?\n\n> + * \\return The file descriptor\n> + */\n> +\n> +/**\n> + * \\fn void *SharedMem::mem() const\n> + * \\brief Gets the pointer to the underlaying shared memory\n\ns/underlaying/underlying/?\n\n> + * \\return The pointer to the shared memory\n> + */\n> +\n> +SharedMem::SharedMem(const std::string &name, std::size_t size)\n> +       : name_(name), size_(size), mem_(nullptr)\n> +{\n> +       int fd = memfd_create(name_.c_str(), MFD_CLOEXEC);\n> +       if (fd < 0)\n> +               return;\n> +\n> +       fd_ = SharedFD(std::move(fd));\n> +       if (!fd_.isValid())\n> +               return;\n> +\n> +       if (ftruncate(fd_.get(), size_) < 0)\n> +               return;\n> +\n> +       mem_ = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED,\n> +                   fd_.get(), 0);\n> +       if (mem_ == MAP_FAILED)\n> +               mem_ = nullptr;\n> +}\n> +\n> +/**\n> + * \\class SharedMemObject\n> + * \\brief Helper class for allocating objects in shared memory\n> + *\n> + * Memory is allocated and exposed as a SharedFD for use across IPC boundaries.\n> + *\n> + * Given the type of the object to be created in shared memory and the arguments\n> + * to pass to this object's constructor, SharedMemObject allocates the shared memory\n> + * of the size of the object and constructs the object in this memory. To check that\n> + * the SharedMemObject was created successfully, one needs to verify that the\n> + * underlying SharedFD (the reference to it is returned by SharedMemObject::fd() member\n> + * function) is valid. The object created in the shared memory can be accessed using\n> + * the SharedMemObject::operator*() indirection operator. Its members can be accessed\n> + * with the SharedMemObject::operator->() member of pointer operator.\n> + *\n> + * To access the object from another process the SharedFD should be passed to that\n> + * process, and the shared memory should be mapped by calling mmap().\n> + *\n> + * A single memfd is created for every SharedMemObject. If there is a need to allocate\n> + * a large number of objects in shared memory, these objects should be grouped into a\n> + * single large object to keep the number of created memfd's reasonably small.\n> + */\n> +\n> +/**\n> + * \\var SharedMemObject::SIZE\n> + * \\brief The size of the object that is going to be stored here\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject< T >::SharedMemObject(const std::string &name, Args &&...args)\n> + * \\brief Contstructor for the SharedMemObject\n\ns/Contstructor/Constructor/\n\n> + * \\param[in] name Name of the SharedMemObject\n> + * \\param[in] args Args to pass to the constructor of the object in shared memory\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject::SharedMemObject(SharedMemObject<T> &&rhs)\n> + * \\brief Move constructor for SharedMemObject\n> + * \\param[in] rhs The object to move\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject::~SharedMemObject()\n> + * \\brief SharedMemObject destructor\n> + *\n> + * Destroys the object created in the shared memory and then unmaps the shared memory.\n> + * Decrements the shared memory descriptor use count.\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject::operator=(SharedMemObject<T> &&rhs)\n> + * \\brief Operator= for SharedMemObject\n> + * \\param[in] rhs The SharedMemObject object to take the data from\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject::operator->()\n> + * \\brief Operator-> for SharedMemObject\n> + * \\return The pointer to the object\n> + */\n> +\n> +/**\n> + * \\fn const T *SharedMemObject::operator->() const\n> + * \\brief Operator-> for SharedMemObject\n> + * \\return The pointer to the const object\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject::operator*()\n> + * \\brief Operator* for SharedMemObject\n> + * \\return The reference to the object\n> + */\n> +\n> +/**\n> + * \\fn const T &SharedMemObject::operator*() const\n> + * \\brief Operator* for SharedMemObject\n> + * \\return Const reference to the object\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject::fd()\n> + * \\brief Gets the file descriptor for the underlaying storage file\n\ns/underlaying/underlying/\n\nThanks,\nNaush\n\n\n> + * \\return The shared memory file descriptor (as SharedFD)\n> + */\n> +\n> +/**\n> + * \\fn SharedMemObject::operator bool()\n> + * \\brief Operator bool() for SharedMemObject\n> + * \\return True if the object was created OK in the shared memory, false otherwise\n> + */\n> +\n> +} // namespace libcamera\n> --\n> 2.43.0\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 2CACFC3257\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 15 Feb 2024 13:39:49 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 619F562805;\n\tThu, 15 Feb 2024 14:39:48 +0100 (CET)","from mail-yw1-x1132.google.com (mail-yw1-x1132.google.com\n\t[IPv6:2607:f8b0:4864:20::1132])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3EEDF61CB0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 15 Feb 2024 14:39:46 +0100 (CET)","by mail-yw1-x1132.google.com with SMTP id\n\t00721157ae682-607bfa4c913so8412297b3.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 15 Feb 2024 05:39:46 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"mZGxyT41\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google; t=1708004384; x=1708609184;\n\tdarn=lists.libcamera.org; \n\th=cc:to:subject:message-id:date:from:in-reply-to:references\n\t:mime-version:from:to:cc:subject:date:message-id:reply-to;\n\tbh=nkk8Jq+suVW+f5Cygl7N5D0Efu40qd5INDp7nKLJmkU=;\n\tb=mZGxyT416UJU+nsY1BKxYcOhVYyf3pfwuoJzHg9BtW4jJpQyDSbJfP7o3Xsc43rQIk\n\tDJFjBqyWBFjqNOmmuODZXaTKOjTDahpoutUJDTwKuMdt96/DxgV+HxbzC8Va5B+roFJ6\n\t+hxBkLRCI3a8v5fK8XM8e2Wi3im223/P7ugO6rvI65aDmqrasLfQYaxYiKGd442B5Rjy\n\tU3uhftxeTjBHPlkVWmdjs378pkf0EdaeXOLA6eBH1gUutsCyRAvMsJScOsdhFF3l2Ohw\n\tS4D6WTUQjNi07aMekqWxnyaZqSRBmZA0A5OkEFtQ2wnjY4/b3ueMnVIJjNXayibRppkV\n\tcZxg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1708004385; x=1708609185;\n\th=cc:to:subject:message-id:date:from:in-reply-to:references\n\t:mime-version:x-gm-message-state:from:to:cc:subject:date:message-id\n\t:reply-to;\n\tbh=nkk8Jq+suVW+f5Cygl7N5D0Efu40qd5INDp7nKLJmkU=;\n\tb=r0e4FYhu9QzDZUTkeap7yHx/HJJIjKfnZGiDtB2WqE8OaW0lIIrkDk0kolBNEEVA/A\n\tAL5K+0B9K5ya9sHN8bBC3Hq0LmYnQHk6UfBaqmGUsu1URM5FIX15Y+vQKKRzHy78hlYB\n\t+zKCh8i8pzYlzb10DMyLpsgVCD4XRzB17rsw/qzACgQlXHQaA/IWh3IWBBobNK6pOGFw\n\tAbx4m97zJk6UN7uat2dgOrV4bcCbrCKeOS2BOE9zCgvewkbmlym8sX2zWkj96Kt5AQ52\n\tOkb7Ogw5ManMyrWkhUOIZMe+C0u2IfEtt0e66QEJxeSHiS7kV7WFRZV6+V3j+FvY4ZZg\n\tupqQ==","X-Gm-Message-State":"AOJu0Yw2yLJIcsxSgF9aAw95vhkYrz9ISYOW58pwCxjUWOYel304kNgz\n\tgSr1/Olxel8Q9H9iicKHNIeIjqU0lpl6c5MkEJoHT3ggBz0ln6iLxbltwdsPGX8B0nLkeMj0vLG\n\tgd8l6hTjJZMA6UGSyIzP4+eZoKDPgPC+UebZJHQ==","X-Google-Smtp-Source":"AGHT+IHPtCw1DDlx8hPKSZGcb2QDZsd9EjafveMt+ag5EViq20T9p1bPQQxwV/73a0DIhQjSYdvTi1Ty/caFYstTyok=","X-Received":"by 2002:a25:b907:0:b0:dc7:5a73:184e with SMTP id\n\tx7-20020a25b907000000b00dc75a73184emr1591405ybj.14.1708004384703;\n\tThu, 15 Feb 2024 05:39:44 -0800 (PST)","MIME-Version":"1.0","References":"<20240214170122.60754-1-hdegoede@redhat.com>\n\t<20240214170122.60754-6-hdegoede@redhat.com>","In-Reply-To":"<20240214170122.60754-6-hdegoede@redhat.com>","From":"Naushir Patuck <naush@raspberrypi.com>","Date":"Thu, 15 Feb 2024 13:39:09 +0000","Message-ID":"<CAEmqJPoUDq50Z3Xw7oi+=TWq5X9BVgBEQTHG=wn_G2SLnFKPBQ@mail.gmail.com>","Subject":"Re: [PATCH v3 05/16] libcamera: shared_mem_object: reorganize the\n\tcode and document the SharedMemObject class","To":"Hans de Goede <hdegoede@redhat.com>","Content-Type":"text/plain; charset=\"UTF-8\"","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"Bryan O'Donoghue <bryan.odonoghue@linaro.org>,\n\tlibcamera-devel@lists.libcamera.org, Maxime Ripard <mripard@redhat.com>, \n\tPavel Machek <pavel@ucw.cz>, Dennis Bonke <admin@dennisbonke.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":28692,"web_url":"https://patchwork.libcamera.org/comment/28692/","msgid":"<dc2572f1-d116-405c-9170-611173db6748@gmail.com>","date":"2024-02-18T19:22:54","subject":"Re: [PATCH v3 05/16] libcamera: shared_mem_object: reorganize the\n\tcode and document the SharedMemObject class","submitter":{"id":179,"url":"https://patchwork.libcamera.org/api/people/179/","name":"Andrei Konovalov","email":"andrey.konovalov.ynk@gmail.com"},"content":"Hi Milan,\n\nThank you for the review!\n\nOn 15.02.2024 16:30, Milan Zamazal wrote:\n> Hans de Goede <hdegoede@redhat.com> writes:\n> \n>> From: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>\n>>\n>> Split the parts which doesn't otherwise depend on the type T or\n>> arguments Args out of the SharedMemObject class into a new\n>> SharedMem class.\n>>\n>> Doxygen documentation by Dennis Bonke and Andrei Konovalov.\n>>\n>> Reviewed-by: Pavel Machek <pavel@ucw.cz>\n>> Co-developed-by: Dennis Bonke <admin@dennisbonke.com>\n>> Signed-off-by: Dennis Bonke <admin@dennisbonke.com>\n>> Signed-off-by: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>\n>> ---\n>>   .../libcamera/internal/shared_mem_object.h    |  92 ++++++---\n>>   src/libcamera/meson.build                     |   1 +\n>>   src/libcamera/shared_mem_object.cpp           | 191 ++++++++++++++++++\n>>   3 files changed, 253 insertions(+), 31 deletions(-)\n>>   create mode 100644 src/libcamera/shared_mem_object.cpp\n>>\n>> diff --git a/include/libcamera/internal/shared_mem_object.h b/include/libcamera/internal/shared_mem_object.h\n>> index bfb639ee..a4de6500 100644\n>> --- a/include/libcamera/internal/shared_mem_object.h\n>> +++ b/include/libcamera/internal/shared_mem_object.h\n>> @@ -7,11 +7,8 @@\n>>   #pragma once\n>>   \n>>   #include <cstddef>\n>> -#include <fcntl.h>\n>>   #include <string>\n>>   #include <sys/mman.h>\n>> -#include <sys/stat.h>\n>> -#include <unistd.h>\n>>   #include <utility>\n>>   \n>>   #include <libcamera/base/class.h>\n>> @@ -19,6 +16,59 @@\n>>   \n>>   namespace libcamera {\n>>   \n>> +class SharedMem\n>> +{\n>> +public:\n>> +\tSharedMem()\n>> +\t\t: mem_(nullptr)\n>> +\t{\n>> +\t}\n>> +\n>> +\tSharedMem(const std::string &name, std::size_t size);\n>> +\n>> +\tSharedMem(SharedMem &&rhs)\n>> +\t{\n>> +\t\tthis->name_ = std::move(rhs.name_);\n>> +\t\tthis->fd_ = std::move(rhs.fd_);\n>> +\t\tthis->mem_ = rhs.mem_;\n>> +\t\trhs.mem_ = nullptr;\n>> +\t}\n>> +\n>> +\t~SharedMem()\n>> +\t{\n>> +\t\tif (mem_)\n>> +\t\t\tmunmap(mem_, size_);\n>> +\t}\n>> +\n>> +\t/* Make SharedMem non-copyable for now. */\n>> +\tLIBCAMERA_DISABLE_COPY(SharedMem)\n>> +\n>> +\tSharedMem &operator=(SharedMem &&rhs)\n>> +\t{\n>> +\t\tthis->name_ = std::move(rhs.name_);\n>> +\t\tthis->fd_ = std::move(rhs.fd_);\n>> +\t\tthis->mem_ = rhs.mem_;\n>> +\t\trhs.mem_ = nullptr;\n>> +\t\treturn *this;\n>> +\t}\n>> +\n>> +\tconst SharedFD &fd() const\n>> +\t{\n>> +\t\treturn fd_;\n>> +\t}\n>> +\n>> +\tvoid *mem() const\n>> +\t{\n>> +\t\treturn mem_;\n>> +\t}\n>> +\n>> +private:\n>> +\tstd::string name_;\n>> +\tSharedFD fd_;\n>> +\tsize_t size_;\n>> +\tvoid *mem_;\n>> +};\n>> +\n>>   template<class T>\n>>   class SharedMemObject\n>>   {\n>> @@ -32,26 +82,11 @@ public:\n>>   \n>>   \ttemplate<class... Args>\n>>   \tSharedMemObject(const std::string &name, Args &&...args)\n>> -\t\t: name_(name), obj_(nullptr)\n>> +\t\t: shMem_(name, SIZE), obj_(nullptr)\n>>   \t{\n>> -\t\tvoid *mem;\n>> -\t\tint ret;\n>> +\t\tvoid *mem = shMem_.mem();\n>>   \n>> -\t\tret = memfd_create(name_.c_str(), MFD_CLOEXEC);\n>> -\t\tif (ret < 0)\n>> -\t\t\treturn;\n>> -\n>> -\t\tfd_ = SharedFD(std::move(ret));\n>> -\t\tif (!fd_.isValid())\n>> -\t\t\treturn;\n>> -\n>> -\t\tret = ftruncate(fd_.get(), SIZE);\n>> -\t\tif (ret < 0)\n>> -\t\t\treturn;\n>> -\n>> -\t\tmem = mmap(nullptr, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,\n>> -\t\t\t   fd_.get(), 0);\n>> -\t\tif (mem == MAP_FAILED)\n>> +\t\tif (mem == nullptr)\n>>   \t\t\treturn;\n>>   \n>>   \t\tobj_ = new (mem) T(std::forward<Args>(args)...);\n>> @@ -59,18 +94,15 @@ public:\n>>   \n>>   \tSharedMemObject(SharedMemObject<T> &&rhs)\n>>   \t{\n>> -\t\tthis->name_ = std::move(rhs.name_);\n>> -\t\tthis->fd_ = std::move(rhs.fd_);\n>> +\t\tthis->shMem_ = std::move(rhs.shMem_);\n>>   \t\tthis->obj_ = rhs.obj_;\n>>   \t\trhs.obj_ = nullptr;\n>>   \t}\n>>   \n>>   \t~SharedMemObject()\n>>   \t{\n>> -\t\tif (obj_) {\n>> +\t\tif (obj_)\n>>   \t\t\tobj_->~T();\n>> -\t\t\tmunmap(obj_, SIZE);\n>> -\t\t}\n>>   \t}\n>>   \n>>   \t/* Make SharedMemObject non-copyable for now. */\n>> @@ -78,8 +110,7 @@ public:\n>>   \n>>   \tSharedMemObject<T> &operator=(SharedMemObject<T> &&rhs)\n>>   \t{\n>> -\t\tthis->name_ = std::move(rhs.name_);\n>> -\t\tthis->fd_ = std::move(rhs.fd_);\n>> +\t\tthis->shMem_ = std::move(rhs.shMem_);\n>>   \t\tthis->obj_ = rhs.obj_;\n>>   \t\trhs.obj_ = nullptr;\n>>   \t\treturn *this;\n>> @@ -107,7 +138,7 @@ public:\n>>   \n>>   \tconst SharedFD &fd() const\n>>   \t{\n>> -\t\treturn fd_;\n>> +\t\treturn shMem_.fd();\n>>   \t}\n>>   \n>>   \texplicit operator bool() const\n>> @@ -116,8 +147,7 @@ public:\n>>   \t}\n>>   \n>>   private:\n>> -\tstd::string name_;\n>> -\tSharedFD fd_;\n>> +\tSharedMem shMem_;\n>>   \tT *obj_;\n>>   };\n>>   \n>> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n>> index 3c5e43df..94a95ae3 100644\n>> --- a/src/libcamera/meson.build\n>> +++ b/src/libcamera/meson.build\n>> @@ -41,6 +41,7 @@ libcamera_sources = files([\n>>       'process.cpp',\n>>       'pub_key.cpp',\n>>       'request.cpp',\n>> +    'shared_mem_object.cpp',\n>>       'source_paths.cpp',\n>>       'stream.cpp',\n>>       'sysfs.cpp',\n>> diff --git a/src/libcamera/shared_mem_object.cpp b/src/libcamera/shared_mem_object.cpp\n>> new file mode 100644\n>> index 00000000..06bbee38\n>> --- /dev/null\n>> +++ b/src/libcamera/shared_mem_object.cpp\n>> @@ -0,0 +1,191 @@\n>> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n>> +/*\n>> + * Copyright (C) 2023, Raspberry Pi Ltd\n>> + *\n>> + * shared_mem_object.cpp - Helper class for shared memory allocations\n>> + */\n>> +\n>> +#include \"libcamera/internal/shared_mem_object.h\"\n>> +\n>> +#include <sys/types.h>\n>> +#include <unistd.h>\n>> +\n>> +/**\n>> + * \\file shared_mem_object.cpp\n>> + * \\brief Helper class for shared memory allocations\n>> + */\n>> +\n>> +namespace libcamera {\n>> +\n>> +/**\n>> + * \\class SharedMem\n>> + * \\brief Helper class for allocating shared memory\n>> + *\n>> + * Memory is allocated and exposed as a SharedFD for use across IPC boundaries.\n>> + *\n>> + * SharedMem allocates the shared memory of the given size and maps it.\n>> + * To check that the shared memory was allocated and mapped successfully, one\n>> + * needs to verify that the pointer to the shared memory returned by SharedMem::mem()\n>> + * is not nullptr.\n>> + *\n>> + * To access the shared memory from another process the SharedFD should be passed\n>> + * to that process, and then the shared memory should be mapped into that process\n>> + * address space by calling mmap().\n>> + *\n>> + * A single memfd is created for every SharedMem. If there is a need to allocate\n>> + * a large number of objects in shared memory, these objects should be grouped\n>> + * together and use the shared memory allocated by a single SharedMem object if\n>> + * possible. This will help to minimize the number of created memfd's.\n>> + */\n>> +\n>> +/**\n>> + * \\fn SharedMem::SharedMem(const std::string &name, std::size_t size)\n>> + * \\brief Contstructor for the SharedMem\n>> + * \\param[in] name Name of the SharedMem\n>> + * \\param[in] size Size of the shared memory to allocate and map\n>> + */\n>> +\n>> +/**\n>> + * \\fn SharedMem::SharedMem(SharedMem &&rhs)\n>> + * \\brief Move constructor for SharedMem\n>> + * \\param[in] rhs The object to move\n>> + */\n>> +\n>> +/**\n>> + * \\fn SharedMem::~SharedMem()\n>> + * \\brief SharedMem destructor\n>> + *\n>> + * Unmaps the allocated shared memory. Decrements the shared memory descriptor use\n>> + * count.\n>> + */\n>> +\n>> +/**\n>> + * \\fn SharedMem &SharedMem::operator=(SharedMem &&rhs)\n>> + * \\brief Move constructor for SharedMem\n>> + * \\param[in] rhs The object to move\n>> + */\n>> +\n>> +/**\n>> + * \\fn const SharedFD &SharedMem::fd() const\n>> + * \\brief Gets the file descriptor for the underlaying shared memory\n>> + * \\return The file descriptor\n>> + */\n>> +\n>> +/**\n>> + * \\fn void *SharedMem::mem() const\n>> + * \\brief Gets the pointer to the underlaying shared memory\n>> + * \\return The pointer to the shared memory\n>> + */\n>> +\n>> +SharedMem::SharedMem(const std::string &name, std::size_t size)\n>> +\t: name_(name), size_(size), mem_(nullptr)\n>> +{\n>> +\tint fd = memfd_create(name_.c_str(), MFD_CLOEXEC);\n>> +\tif (fd < 0)\n>> +\t\treturn;\n>> +\n>> +\tfd_ = SharedFD(std::move(fd));\n>> +\tif (!fd_.isValid())\n>> +\t\treturn;\n>> +\n>> +\tif (ftruncate(fd_.get(), size_) < 0)\n>> +\t\treturn;\n>> +\n>> +\tmem_ = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED,\n>> +\t\t    fd_.get(), 0);\n>> +\tif (mem_ == MAP_FAILED)\n>> +\t\tmem_ = nullptr;\n>> +}\n>> +\n>> +/**\n>> + * \\class SharedMemObject\n>> + * \\brief Helper class for allocating objects in shared memory\n>> + *\n>> + * Memory is allocated and exposed as a SharedFD for use across IPC boundaries.\n>> + *\n>> + * Given the type of the object to be created in shared memory and the arguments\n>> + * to pass to this object's constructor, SharedMemObject allocates the shared memory\n>> + * of the size of the object and constructs the object in this memory. To check that\n>> + * the SharedMemObject was created successfully, one needs to verify that the\n>> + * underlying SharedFD (the reference to it is returned by SharedMemObject::fd() member\n>> + * function) is valid. The object created in the shared memory can be accessed using\n>> + * the SharedMemObject::operator*() indirection operator. Its members can be accessed\n>> + * with the SharedMemObject::operator->() member of pointer operator.\n> \n> But it can still happen that SharedMemObject::fd() is all right but the object\n> returned from the operators is nullptr, right?\n\nRight (if the memory is allocated and truncated OK, but mmap fails).\n\n> It would be good to clarify this and refer to the bool operator here.\n\nI will.\nI'll also modify the SoftwareIsp constructor to use 'if (!sharedParams_)' instead of\n'if (!sharedParams_.fd().isValid())'.\n\n>> + *\n>> + * To access the object from another process the SharedFD should be passed to that\n>> + * process, and the shared memory should be mapped by calling mmap().\n>> + *\n>> + * A single memfd is created for every SharedMemObject. If there is a need to allocate\n>> + * a large number of objects in shared memory, these objects should be grouped into a\n>> + * single large object to keep the number of created memfd's reasonably small.\n>> + */\n>> +\n>> +/**\n>> + * \\var SharedMemObject::SIZE\n>> + * \\brief The size of the object that is going to be stored here\n>> + */\n>> +\n>> +/**\n>> + * \\fn SharedMemObject< T >::SharedMemObject(const std::string &name, Args &&...args)\n>> + * \\brief Contstructor for the SharedMemObject\n>               ^^^^^^^^^^^^\n> \n> Constructor\n\nOK, I'll fix these misprints (they are two).\n\nThanks,\nAndrei\n\n>> + * \\param[in] name Name of the SharedMemObject\n>> + * \\param[in] args Args to pass to the constructor of the object in shared memory\n>> + */\n>> +\n>> +/**\n>> + * \\fn SharedMemObject::SharedMemObject(SharedMemObject<T> &&rhs)\n>> + * \\brief Move constructor for SharedMemObject\n>> + * \\param[in] rhs The object to move\n>> + */\n>> +\n>> +/**\n>> + * \\fn SharedMemObject::~SharedMemObject()\n>> + * \\brief SharedMemObject destructor\n>> + *\n>> + * Destroys the object created in the shared memory and then unmaps the shared memory.\n>> + * Decrements the shared memory descriptor use count.\n>> + */\n>> +\n>> +/**\n>> + * \\fn SharedMemObject::operator=(SharedMemObject<T> &&rhs)\n>> + * \\brief Operator= for SharedMemObject\n>> + * \\param[in] rhs The SharedMemObject object to take the data from\n>> + */\n>> +\n>> +/**\n>> + * \\fn SharedMemObject::operator->()\n>> + * \\brief Operator-> for SharedMemObject\n>> + * \\return The pointer to the object\n>> + */\n>> +\n>> +/**\n>> + * \\fn const T *SharedMemObject::operator->() const\n>> + * \\brief Operator-> for SharedMemObject\n>> + * \\return The pointer to the const object\n>> + */\n>> +\n>> +/**\n>> + * \\fn SharedMemObject::operator*()\n>> + * \\brief Operator* for SharedMemObject\n>> + * \\return The reference to the object\n>> + */\n>> +\n>> +/**\n>> + * \\fn const T &SharedMemObject::operator*() const\n>> + * \\brief Operator* for SharedMemObject\n>> + * \\return Const reference to the object\n>> + */\n>> +\n>> +/**\n>> + * \\fn SharedMemObject::fd()\n>> + * \\brief Gets the file descriptor for the underlaying storage file\n>> + * \\return The shared memory file descriptor (as SharedFD)\n>> + */\n>> +\n>> +/**\n>> + * \\fn SharedMemObject::operator bool()\n>> + * \\brief Operator bool() for SharedMemObject\n>> + * \\return True if the object was created OK in the shared memory, false otherwise\n>> + */\n>> +\n>> +} // namespace libcamera\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id E8179C3257\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun, 18 Feb 2024 19:22:58 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3D91E62805;\n\tSun, 18 Feb 2024 20:22:58 +0100 (CET)","from mail-lf1-x136.google.com (mail-lf1-x136.google.com\n\t[IPv6:2a00:1450:4864:20::136])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 5D74062802\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 18 Feb 2024 20:22:57 +0100 (CET)","by mail-lf1-x136.google.com with SMTP id\n\t2adb3069b0e04-512acc1a881so667342e87.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 18 Feb 2024 11:22:57 -0800 (PST)","from [192.168.118.26] ([87.116.164.107])\n\tby smtp.gmail.com with ESMTPSA id\n\ts1-20020a056402164100b00563f918c76asm2006584edx.52.2024.02.18.11.22.55\n\t(version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n\tSun, 18 Feb 2024 11:22:55 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"nJNLs89T\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=gmail.com; s=20230601; t=1708284176; x=1708888976;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:in-reply-to:from:content-language\n\t:references:cc:to:subject:user-agent:mime-version:date:message-id\n\t:from:to:cc:subject:date:message-id:reply-to;\n\tbh=jkG3ma6x51HIq9RJ/Cyp9/Sa4uKa2qgJS3/yKBwI9N8=;\n\tb=nJNLs89T3ByD/SXRYW7cqigh9jt4K21vA6mlkysGrdaVYV53OmrX0B+G/pxR/XHwR7\n\tzJg6p5a844noCxI8WHmbNg2llc7iYaKO/2JXAgNLNEpIsg1etUE9gYsVMWHeq7fP82Xn\n\tcbFFdFQuwmhdiikDIZpFVTO57LPxCqJdHEiWzoL1u7YSMcyHKkb9yWB6NC2nYNwSTlCQ\n\ty9DN9US1ZA1CR+rXdKPcRy22gSu+SNYGRFKBnAz4GuQAzQp45x6s+i3/eGIORAOh59tX\n\tsLbIGBDnVxvvkkCGg8TaVOC1bB2y8T8AfrC2zVc8IBQZR657PiQ+GABiUaZReg4nCzyY\n\tyDbg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1708284176; x=1708888976;\n\th=content-transfer-encoding:in-reply-to:from:content-language\n\t:references:cc:to:subject:user-agent:mime-version:date:message-id\n\t:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n\tbh=jkG3ma6x51HIq9RJ/Cyp9/Sa4uKa2qgJS3/yKBwI9N8=;\n\tb=e9h5tDVIBmTg0UNmu+gxBjqslADap4xx3wSrUMnTTnrAAGa5M20qhGEe4F4zwNAhtz\n\tPoj3Ue3QuaWdrPgbHftFC9OUPZwhRZgUNGS+IhSYvZxoJxrHWxU/5HCkyrqU804YhWR7\n\tnJ7pBOkRSVAvJIVkLF9z/gtC0apXiF/sMalHW83yLSaNKT9Pagb6SAIxMEK0sdXm9AGY\n\tThHGFO1nRBJCqFV+O2SysuXvDyg7BelP5GhCSjYJpJOBskG8MWJaK/b02ZM6D1mQ59S1\n\tSWxecAPPrrKCEiSu1e9lljbduE7MGEcX+jlMMkpp6K3vYrw29Wt4lBIVw8udOrWPSp2P\n\tOOEQ==","X-Gm-Message-State":"AOJu0YwQ8xcrwpuO7jToIjvullgUvBV20tZBT0aoxrpU0tLYApvq15Ax\n\tZEF8aOrSfMY7EPjfAHu+YOyHie8QdFK0nEFYlboRmuuBGk3rMBJP","X-Google-Smtp-Source":"AGHT+IH2kPKZTx9upQB6/4ThUKBQy5H4emyXkrdUmLw/DYs1HD8kNUd18f1IBBn1u7OGzf0mn17GhQ==","X-Received":"by 2002:ac2:4e8b:0:b0:512:b069:2dde with SMTP id\n\to11-20020ac24e8b000000b00512b0692ddemr975901lfr.10.1708284176108; \n\tSun, 18 Feb 2024 11:22:56 -0800 (PST)","Message-ID":"<dc2572f1-d116-405c-9170-611173db6748@gmail.com>","Date":"Sun, 18 Feb 2024 22:22:54 +0300","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v3 05/16] libcamera: shared_mem_object: reorganize the\n\tcode and document the SharedMemObject class","To":"Milan Zamazal <mzamazal@redhat.com>, Hans de Goede <hdegoede@redhat.com>","References":"<20240214170122.60754-1-hdegoede@redhat.com>\n\t<20240214170122.60754-6-hdegoede@redhat.com>\n\t<87plwxdfcu.fsf@redhat.com>","Content-Language":"en-US","From":"Andrei Konovalov <andrey.konovalov.ynk@gmail.com>","In-Reply-To":"<87plwxdfcu.fsf@redhat.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"Bryan O'Donoghue <bryan.odonoghue@linaro.org>,\n\tlibcamera-devel@lists.libcamera.org, Maxime Ripard <mripard@redhat.com>, \n\tPavel Machek <pavel@ucw.cz>, Dennis Bonke <admin@dennisbonke.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":28693,"web_url":"https://patchwork.libcamera.org/comment/28693/","msgid":"<8fcf18ff-e855-4763-979d-eb40f2df350f@gmail.com>","date":"2024-02-19T12:18:57","subject":"Re: [PATCH v3 05/16] libcamera: shared_mem_object: reorganize the\n\tcode and document the SharedMemObject class","submitter":{"id":179,"url":"https://patchwork.libcamera.org/api/people/179/","name":"Andrei Konovalov","email":"andrey.konovalov.ynk@gmail.com"},"content":"Hi Naushir,\n\nOn 15.02.2024 16:39, Naushir Patuck wrote:\n> Hi Hans,\n> \n> On Wed, 14 Feb 2024 at 17:01, Hans de Goede <hdegoede@redhat.com> wrote:\n>>\n>> From: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>\n>>\n>> Split the parts which doesn't otherwise depend on the type T or\n>> arguments Args out of the SharedMemObject class into a new\n>> SharedMem class.\n>>\n>> Doxygen documentation by Dennis Bonke and Andrei Konovalov.\n>>\n>> Reviewed-by: Pavel Machek <pavel@ucw.cz>\n>> Co-developed-by: Dennis Bonke <admin@dennisbonke.com>\n>> Signed-off-by: Dennis Bonke <admin@dennisbonke.com>\n>> Signed-off-by: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>\n>> ---\n>>   .../libcamera/internal/shared_mem_object.h    |  92 ++++++---\n>>   src/libcamera/meson.build                     |   1 +\n>>   src/libcamera/shared_mem_object.cpp           | 191 ++++++++++++++++++\n>>   3 files changed, 253 insertions(+), 31 deletions(-)\n>>   create mode 100644 src/libcamera/shared_mem_object.cpp\n>>\n>> diff --git a/include/libcamera/internal/shared_mem_object.h b/include/libcamera/internal/shared_mem_object.h\n>> index bfb639ee..a4de6500 100644\n>> --- a/include/libcamera/internal/shared_mem_object.h\n>> +++ b/include/libcamera/internal/shared_mem_object.h\n>> @@ -7,11 +7,8 @@\n>>   #pragma once\n>>\n>>   #include <cstddef>\n>> -#include <fcntl.h>\n>>   #include <string>\n>>   #include <sys/mman.h>\n>> -#include <sys/stat.h>\n>> -#include <unistd.h>\n>>   #include <utility>\n>>\n>>   #include <libcamera/base/class.h>\n>> @@ -19,6 +16,59 @@\n>>\n>>   namespace libcamera {\n>>\n>> +class SharedMem\n>> +{\n>> +public:\n>> +       SharedMem()\n>> +               : mem_(nullptr)\n>> +       {\n>> +       }\n>> +\n>> +       SharedMem(const std::string &name, std::size_t size);\n>> +\n>> +       SharedMem(SharedMem &&rhs)\n>> +       {\n>> +               this->name_ = std::move(rhs.name_);\n>> +               this->fd_ = std::move(rhs.fd_);\n>> +               this->mem_ = rhs.mem_;\n>> +               rhs.mem_ = nullptr;\n>> +       }\n>> +\n>> +       ~SharedMem()\n>> +       {\n>> +               if (mem_)\n>> +                       munmap(mem_, size_);\n>> +       }\n>> +\n>> +       /* Make SharedMem non-copyable for now. */\n>> +       LIBCAMERA_DISABLE_COPY(SharedMem)\n>> +\n>> +       SharedMem &operator=(SharedMem &&rhs)\n>> +       {\n>> +               this->name_ = std::move(rhs.name_);\n>> +               this->fd_ = std::move(rhs.fd_);\n>> +               this->mem_ = rhs.mem_;\n>> +               rhs.mem_ = nullptr;\n>> +               return *this;\n>> +       }\n>> +\n>> +       const SharedFD &fd() const\n>> +       {\n>> +               return fd_;\n>> +       }\n>> +\n>> +       void *mem() const\n>> +       {\n>> +               return mem_;\n>> +       }\n>> +\n>> +private:\n>> +       std::string name_;\n>> +       SharedFD fd_;\n>> +       size_t size_;\n>> +       void *mem_;\n>> +};\n>> +\n>>   template<class T>\n>>   class SharedMemObject\n> \n> Would it make sense to have SharedMemObject derived from SharedMem?\n> Then you would only need a constructor and destructor implemented for\n> SharedMemObject, and all other accessors can be through the base\n> class... i think?\n\nDoes this updated patch (attached) looks OK for you?\n\nThanks,\nAndrei","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 8AB3CBF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 19 Feb 2024 12:19:02 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C95EE62807;\n\tMon, 19 Feb 2024 13:19:01 +0100 (CET)","from mail-ej1-x631.google.com (mail-ej1-x631.google.com\n\t[IPv6:2a00:1450:4864:20::631])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B1DED61C9E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 19 Feb 2024 13:18:59 +0100 (CET)","by mail-ej1-x631.google.com with SMTP id\n\ta640c23a62f3a-a3ddc13bbb3so528260966b.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 19 Feb 2024 04:18:59 -0800 (PST)","from [192.168.118.26] ([87.116.165.182])\n\tby smtp.gmail.com with ESMTPSA id\n\tvo8-20020a170907a80800b00a3ce3c5b2a4sm2861454ejc.195.2024.02.19.04.18.57\n\t(version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n\tMon, 19 Feb 2024 04:18:58 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"V/JC4fpr\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=gmail.com; s=20230601; t=1708345139; x=1708949939;\n\tdarn=lists.libcamera.org; \n\th=in-reply-to:from:references:cc:to:content-language:subject\n\t:user-agent:mime-version:date:message-id:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=m7PUvpOuxm4oeV/UTD/WCqmluEDw183n5Nlmdw4aC1I=;\n\tb=V/JC4fprdF96Ax7jztkp58ydBBqq6hfbf+rPNtVJbEOJQmJcT1bJN0Ju9qAJJAa/yo\n\tA4z6EzEqd1TinOc5XaklAgprxNMXWvenetHXLsf+J/gSRaOkRo0UJMRBG9i+E9v6pg5C\n\tJKWN37TplvquVWSR/ojVGVdaNeZgXsdH/INQtZK8ZzoXqcIKJDXwyS9NJXfi2fQBuSHx\n\tpcslmF5aScdxH0yZe9amTTC8aGLmu5xheo847D6JLK4mTEZL9V8Efut+3xB/TbsGoq3C\n\tftMgIXnlJc2f9DhKJtCZZy8c9NxS0FII4WLfMIRCLVJ4wfdkdM0ZuJP53Y15gkJkN5C5\n\tbKaA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1708345139; x=1708949939;\n\th=in-reply-to:from:references:cc:to:content-language:subject\n\t:user-agent:mime-version:date:message-id:x-gm-message-state:from:to\n\t:cc:subject:date:message-id:reply-to;\n\tbh=m7PUvpOuxm4oeV/UTD/WCqmluEDw183n5Nlmdw4aC1I=;\n\tb=OJXy88UTO/uZBcAWEN88DSWait+sOIvOXUYsCJKHEVE3bJT4YVKZH4nMQWM9XzqI7y\n\ty2ivTp1b2C8/+EsaSU4dtEpAkVsAEIskOJXrxydqFeCbB8PeLRZDAH0nGfPrYdjSJsew\n\t2Tf210wG1w8FFXJ/Bq+x3IeKErn24s/Nw7ovcpZy0Xj+OzfcZYAjr5KMVT8q4qHtupzh\n\tR/tA3wZKPz2epnM7uudFlv3gnTyKxN0tezZ75EilxJkXlQiFHRAzqDaB6axbJxN8Nc4D\n\tb5Q6Fi2FvwAXENAlrtfj5peDx9h+1+xDpz81Qd8ccjxYVBtjhw1EQJ+1VZ8Uvq/QsWL/\n\tf9Ug==","X-Forwarded-Encrypted":"i=1;\n\tAJvYcCXbP/lRXod5hBOVnMOlDd+k/kPxVNcCFB9ROYLRkQJnUXOTebA+l8zOWu0u47+EYHVRySTUTwTxxE9uTc957C8fp5np+NqUL70ZR1GVIMrTMLNvBA==","X-Gm-Message-State":"AOJu0YwPYUp2wviZfAqJhrfQpDvHTNGX7YmsrQb8LNmpBCDQvn6T6d8Z\n\t5qJZHo+p1A+5n6ifu9XgGid4Lw2R4q3AiBQpUTDjJ5tcokdxPy55","X-Google-Smtp-Source":"AGHT+IF4KKe13Jo4kSKFiAEifBK9Me+bsTrUOOFTz0CxIFBKJcSH6+gidA9X6hWCvCxSx/DIerMYXw==","X-Received":"by 2002:a17:906:7150:b0:a3e:75b2:4ffa with SMTP id\n\tz16-20020a170906715000b00a3e75b24ffamr3180943ejj.13.1708345138909; \n\tMon, 19 Feb 2024 04:18:58 -0800 (PST)","Content-Type":"multipart/mixed;\n\tboundary=\"------------xnQyVrm2naB2eeXo4OKj1AAG\"","Message-ID":"<8fcf18ff-e855-4763-979d-eb40f2df350f@gmail.com>","Date":"Mon, 19 Feb 2024 15:18:57 +0300","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v3 05/16] libcamera: shared_mem_object: reorganize the\n\tcode and document the SharedMemObject class","Content-Language":"en-US","To":"Naushir Patuck <naush@raspberrypi.com>","References":"<20240214170122.60754-1-hdegoede@redhat.com>\n\t<20240214170122.60754-6-hdegoede@redhat.com>\n\t<CAEmqJPoUDq50Z3Xw7oi+=TWq5X9BVgBEQTHG=wn_G2SLnFKPBQ@mail.gmail.com>","From":"Andrei Konovalov <andrey.konovalov.ynk@gmail.com>","In-Reply-To":"<CAEmqJPoUDq50Z3Xw7oi+=TWq5X9BVgBEQTHG=wn_G2SLnFKPBQ@mail.gmail.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"Maxime Ripard <mripard@redhat.com>, libcamera-devel@lists.libcamera.org, \n\tPavel Machek <pavel@ucw.cz>,\n\tBryan O'Donoghue <bryan.odonoghue@linaro.org>, \n\tDennis Bonke <admin@dennisbonke.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":28694,"web_url":"https://patchwork.libcamera.org/comment/28694/","msgid":"<e61756a8-51d5-4d40-b5f2-e0737ef39623@gmail.com>","date":"2024-02-19T12:25:42","subject":"Re: [PATCH v3 05/16] libcamera: shared_mem_object: reorganize the\n\tcode and document the SharedMemObject class","submitter":{"id":179,"url":"https://patchwork.libcamera.org/api/people/179/","name":"Andrei Konovalov","email":"andrey.konovalov.ynk@gmail.com"},"content":"On 19.02.2024 15:18, Andrei Konovalov wrote:\n> Hi Naushir,\n> \n> On 15.02.2024 16:39, Naushir Patuck wrote:\n>> Hi Hans,\n>>\n>> On Wed, 14 Feb 2024 at 17:01, Hans de Goede <hdegoede@redhat.com> wrote:\n>>>\n>>> From: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>\n>>>\n>>> Split the parts which doesn't otherwise depend on the type T or\n>>> arguments Args out of the SharedMemObject class into a new\n>>> SharedMem class.\n>>>\n>>> Doxygen documentation by Dennis Bonke and Andrei Konovalov.\n>>>\n>>> Reviewed-by: Pavel Machek <pavel@ucw.cz>\n>>> Co-developed-by: Dennis Bonke <admin@dennisbonke.com>\n>>> Signed-off-by: Dennis Bonke <admin@dennisbonke.com>\n>>> Signed-off-by: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>\n>>> ---\n>>>   .../libcamera/internal/shared_mem_object.h    |  92 ++++++---\n>>>   src/libcamera/meson.build                     |   1 +\n>>>   src/libcamera/shared_mem_object.cpp           | 191 ++++++++++++++++++\n>>>   3 files changed, 253 insertions(+), 31 deletions(-)\n>>>   create mode 100644 src/libcamera/shared_mem_object.cpp\n>>>\n>>> diff --git a/include/libcamera/internal/shared_mem_object.h b/include/libcamera/internal/shared_mem_object.h\n<snip>\n>> Would it make sense to have SharedMemObject derived from SharedMem?\n>> Then you would only need a constructor and destructor implemented for\n>> SharedMemObject, and all other accessors can be through the base\n>> class... i think?\n> \n> Does this updated patch (attached) looks OK for you?\n\nOops.. The attachment wasn't inlined. Resending the patch in an easier to comment on\nform.\n\nThanks,\nAndrei\n\n\nFrom: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>\nDate: Wed, 31 Jan 2024 02:17:34 +0300\nSubject: [PATCH 05/16] libcamera: shared_mem_object: reorganize the code and\n  document the SharedMemObject class\n\nSplit the parts which doesn't otherwise depend on the type T or\narguments Args out of the SharedMemObject class into a new\nSharedMem class.\n\nDoxygen documentation by Dennis Bonke and Andrei Konovalov.\n\nReviewed-by: Pavel Machek <pavel@ucw.cz>\nCo-developed-by: Dennis Bonke <admin@dennisbonke.com>\nSigned-off-by: Dennis Bonke <admin@dennisbonke.com>\nSigned-off-by: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>\n---\n  .../libcamera/internal/shared_mem_object.h    | 101 ++++++----\n  src/libcamera/meson.build                     |   1 +\n  src/libcamera/shared_mem_object.cpp           | 189 ++++++++++++++++++\n  3 files changed, 252 insertions(+), 39 deletions(-)\n  create mode 100644 src/libcamera/shared_mem_object.cpp\n\ndiff --git a/include/libcamera/internal/shared_mem_object.h b/include/libcamera/internal/shared_mem_object.h\nindex bfb639ee..bb9cddcd 100644\n--- a/include/libcamera/internal/shared_mem_object.h\n+++ b/include/libcamera/internal/shared_mem_object.h\n@@ -7,11 +7,8 @@\n  #pragma once\n\n  #include <cstddef>\n-#include <fcntl.h>\n  #include <string>\n  #include <sys/mman.h>\n-#include <sys/stat.h>\n-#include <unistd.h>\n  #include <utility>\n\n  #include <libcamera/base/class.h>\n@@ -19,58 +16,92 @@\n\n  namespace libcamera {\n\n+class SharedMem\n+{\n+public:\n+\tSharedMem()\n+\t\t: mem_(nullptr)\n+\t{\n+\t}\n+\n+\tSharedMem(const std::string &name, std::size_t size);\n+\n+\tSharedMem(SharedMem &&rhs)\n+\t{\n+\t\tthis->name_ = std::move(rhs.name_);\n+\t\tthis->fd_ = std::move(rhs.fd_);\n+\t\tthis->mem_ = rhs.mem_;\n+\t\trhs.mem_ = nullptr;\n+\t}\n+\n+\tvirtual ~SharedMem()\n+\t{\n+\t\tif (mem_)\n+\t\t\tmunmap(mem_, size_);\n+\t}\n+\n+\t/* Make SharedMem non-copyable for now. */\n+\tLIBCAMERA_DISABLE_COPY(SharedMem)\n+\n+\tSharedMem &operator=(SharedMem &&rhs)\n+\t{\n+\t\tthis->name_ = std::move(rhs.name_);\n+\t\tthis->fd_ = std::move(rhs.fd_);\n+\t\tthis->mem_ = rhs.mem_;\n+\t\trhs.mem_ = nullptr;\n+\t\treturn *this;\n+\t}\n+\n+\tconst SharedFD &fd() const\n+\t{\n+\t\treturn fd_;\n+\t}\n+\n+\tvoid *mem() const\n+\t{\n+\t\treturn mem_;\n+\t}\n+\n+private:\n+\tstd::string name_;\n+\tSharedFD fd_;\n+\tsize_t size_;\n+protected:\n+\tvoid *mem_;\n+};\n+\n  template<class T>\n-class SharedMemObject\n+class SharedMemObject : public SharedMem\n  {\n  public:\n  \tstatic constexpr std::size_t SIZE = sizeof(T);\n\n  \tSharedMemObject()\n-\t\t: obj_(nullptr)\n+\t\t: SharedMem(), obj_(nullptr)\n  \t{\n  \t}\n\n  \ttemplate<class... Args>\n  \tSharedMemObject(const std::string &name, Args &&...args)\n-\t\t: name_(name), obj_(nullptr)\n+\t\t: SharedMem(name, SIZE), obj_(nullptr)\n  \t{\n-\t\tvoid *mem;\n-\t\tint ret;\n-\n-\t\tret = memfd_create(name_.c_str(), MFD_CLOEXEC);\n-\t\tif (ret < 0)\n-\t\t\treturn;\n-\n-\t\tfd_ = SharedFD(std::move(ret));\n-\t\tif (!fd_.isValid())\n-\t\t\treturn;\n-\n-\t\tret = ftruncate(fd_.get(), SIZE);\n-\t\tif (ret < 0)\n+\t\tif (mem_ == nullptr)\n  \t\t\treturn;\n\n-\t\tmem = mmap(nullptr, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,\n-\t\t\t   fd_.get(), 0);\n-\t\tif (mem == MAP_FAILED)\n-\t\t\treturn;\n-\n-\t\tobj_ = new (mem) T(std::forward<Args>(args)...);\n+\t\tobj_ = new (mem_) T(std::forward<Args>(args)...);\n  \t}\n\n  \tSharedMemObject(SharedMemObject<T> &&rhs)\n+\t\t: SharedMem(std::move(rhs))\n  \t{\n-\t\tthis->name_ = std::move(rhs.name_);\n-\t\tthis->fd_ = std::move(rhs.fd_);\n  \t\tthis->obj_ = rhs.obj_;\n  \t\trhs.obj_ = nullptr;\n  \t}\n\n  \t~SharedMemObject()\n  \t{\n-\t\tif (obj_) {\n+\t\tif (obj_)\n  \t\t\tobj_->~T();\n-\t\t\tmunmap(obj_, SIZE);\n-\t\t}\n  \t}\n\n  \t/* Make SharedMemObject non-copyable for now. */\n@@ -78,8 +109,7 @@ public:\n\n  \tSharedMemObject<T> &operator=(SharedMemObject<T> &&rhs)\n  \t{\n-\t\tthis->name_ = std::move(rhs.name_);\n-\t\tthis->fd_ = std::move(rhs.fd_);\n+\t\tSharedMem::operator=(std::move(rhs));\n  \t\tthis->obj_ = rhs.obj_;\n  \t\trhs.obj_ = nullptr;\n  \t\treturn *this;\n@@ -105,19 +135,12 @@ public:\n  \t\treturn *obj_;\n  \t}\n\n-\tconst SharedFD &fd() const\n-\t{\n-\t\treturn fd_;\n-\t}\n-\n  \texplicit operator bool() const\n  \t{\n  \t\treturn !!obj_;\n  \t}\n\n  private:\n-\tstd::string name_;\n-\tSharedFD fd_;\n  \tT *obj_;\n  };\n\ndiff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\nindex 3c5e43df..94a95ae3 100644\n--- a/src/libcamera/meson.build\n+++ b/src/libcamera/meson.build\n@@ -41,6 +41,7 @@ libcamera_sources = files([\n      'process.cpp',\n      'pub_key.cpp',\n      'request.cpp',\n+    'shared_mem_object.cpp',\n      'source_paths.cpp',\n      'stream.cpp',\n      'sysfs.cpp',\ndiff --git a/src/libcamera/shared_mem_object.cpp b/src/libcamera/shared_mem_object.cpp\nnew file mode 100644\nindex 00000000..dbaa7351\n--- /dev/null\n+++ b/src/libcamera/shared_mem_object.cpp\n@@ -0,0 +1,189 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2023, Raspberry Pi Ltd\n+ *\n+ * shared_mem_object.cpp - Helper class for shared memory allocations\n+ */\n+\n+#include \"libcamera/internal/shared_mem_object.h\"\n+\n+#include <sys/types.h>\n+#include <unistd.h>\n+\n+/**\n+ * \\file shared_mem_object.cpp\n+ * \\brief Helper class for shared memory allocations\n+ */\n+\n+namespace libcamera {\n+\n+/**\n+ * \\class SharedMem\n+ * \\brief Helper class for allocating shared memory\n+ *\n+ * Memory is allocated and exposed as a SharedFD for use across IPC boundaries.\n+ *\n+ * SharedMem allocates the shared memory of the given size and maps it.\n+ * To ensure that the shared memory was allocated and mapped successfully, one\n+ * needs to verify that the overloaded bool() operator returns true.\n+ *\n+ * To access the shared memory from another process the SharedFD should be passed\n+ * to that process, and then the shared memory should be mapped into that process\n+ * address space by calling mmap().\n+ *\n+ * A single memfd is created for every SharedMem. If there is a need to allocate\n+ * a large number of objects in shared memory, these objects should be grouped\n+ * together and use the shared memory allocated by a single SharedMem object if\n+ * possible. This will help to minimize the number of created memfd's.\n+ */\n+\n+/**\n+ * \\fn SharedMem::SharedMem(const std::string &name, std::size_t size)\n+ * \\brief Constructor for the SharedMem\n+ * \\param[in] name Name of the SharedMem\n+ * \\param[in] size Size of the shared memory to allocate and map\n+ */\n+\n+/**\n+ * \\fn SharedMem::SharedMem(SharedMem &&rhs)\n+ * \\brief Move constructor for SharedMem\n+ * \\param[in] rhs The object to move\n+ */\n+\n+/**\n+ * \\fn SharedMem::~SharedMem()\n+ * \\brief SharedMem destructor\n+ *\n+ * Unmaps the allocated shared memory. Decrements the shared memory descriptor use\n+ * count.\n+ */\n+\n+/**\n+ * \\fn SharedMem &SharedMem::operator=(SharedMem &&rhs)\n+ * \\brief Move constructor for SharedMem\n+ * \\param[in] rhs The object to move\n+ */\n+\n+/**\n+ * \\fn const SharedFD &SharedMem::fd() const\n+ * \\brief Gets the file descriptor for the underlying shared memory\n+ * \\return The file descriptor\n+ */\n+\n+/**\n+ * \\fn void *SharedMem::mem() const\n+ * \\brief Gets the pointer to the underlying shared memory\n+ * \\return The pointer to the shared memory\n+ */\n+\n+SharedMem::SharedMem(const std::string &name, std::size_t size)\n+\t: name_(name), size_(size), mem_(nullptr)\n+{\n+\tint fd = memfd_create(name_.c_str(), MFD_CLOEXEC);\n+\tif (fd < 0)\n+\t\treturn;\n+\n+\tfd_ = SharedFD(std::move(fd));\n+\tif (!fd_.isValid())\n+\t\treturn;\n+\n+\tif (ftruncate(fd_.get(), size_) < 0)\n+\t\treturn;\n+\n+\tmem_ = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED,\n+\t\t    fd_.get(), 0);\n+\tif (mem_ == MAP_FAILED)\n+\t\tmem_ = nullptr;\n+}\n+\n+/**\n+ * \\var SharedMem::mem_\n+ * \\brief Pointer to the shared memory allocated\n+ */\n+\n+/**\n+ * \\class SharedMemObject\n+ * \\brief Helper class for allocating objects in shared memory\n+ *\n+ * Memory is allocated and exposed as a SharedFD for use across IPC boundaries.\n+ *\n+ * Given the type of the object to be created in shared memory and the arguments\n+ * to pass to this object's constructor, SharedMemObject allocates the shared memory\n+ * of the size of the object and constructs the object in this memory. To check that\n+ * the SharedMemObject was created successfully, one needs to verify that the\n+ * underlying SharedFD (the reference to it is returned by SharedMemObject::fd() member\n+ * function) is valid. The object created in the shared memory can be accessed using\n+ * the SharedMemObject::operator*() indirection operator. Its members can be accessed\n+ * with the SharedMemObject::operator->() member of pointer operator.\n+ *\n+ * To access the object from another process the SharedFD should be passed to that\n+ * process, and the shared memory should be mapped by calling mmap().\n+ *\n+ * A single memfd is created for every SharedMemObject. If there is a need to allocate\n+ * a large number of objects in shared memory, these objects should be grouped into a\n+ * single large object to keep the number of created memfd's reasonably small.\n+ */\n+\n+/**\n+ * \\var SharedMemObject::SIZE\n+ * \\brief The size of the object that is going to be stored here\n+ */\n+\n+/**\n+ * \\fn SharedMemObject< T >::SharedMemObject(const std::string &name, Args &&...args)\n+ * \\brief Constructor for the SharedMemObject\n+ * \\param[in] name Name of the SharedMemObject\n+ * \\param[in] args Args to pass to the constructor of the object in shared memory\n+ */\n+\n+/**\n+ * \\fn SharedMemObject::SharedMemObject(SharedMemObject<T> &&rhs)\n+ * \\brief Move constructor for SharedMemObject\n+ * \\param[in] rhs The object to move\n+ */\n+\n+/**\n+ * \\fn SharedMemObject::~SharedMemObject()\n+ * \\brief SharedMemObject destructor\n+ *\n+ * Destroys the object created in the shared memory and then unmaps the shared memory.\n+ * Decrements the shared memory descriptor use count.\n+ */\n+\n+/**\n+ * \\fn SharedMemObject::operator=(SharedMemObject<T> &&rhs)\n+ * \\brief Operator= for SharedMemObject\n+ * \\param[in] rhs The SharedMemObject object to take the data from\n+ */\n+\n+/**\n+ * \\fn SharedMemObject::operator->()\n+ * \\brief Operator-> for SharedMemObject\n+ * \\return The pointer to the object\n+ */\n+\n+/**\n+ * \\fn const T *SharedMemObject::operator->() const\n+ * \\brief Operator-> for SharedMemObject\n+ * \\return The pointer to the const object\n+ */\n+\n+/**\n+ * \\fn SharedMemObject::operator*()\n+ * \\brief Operator* for SharedMemObject\n+ * \\return The reference to the object\n+ */\n+\n+/**\n+ * \\fn const T &SharedMemObject::operator*() const\n+ * \\brief Operator* for SharedMemObject\n+ * \\return Const reference to the object\n+ */\n+\n+/**\n+ * \\fn SharedMemObject::operator bool()\n+ * \\brief Operator bool() for SharedMemObject\n+ * \\return True if the object was created OK in the shared memory, false otherwise\n+ */\n+\n+} // namespace libcamera","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id D4FABC3257\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 19 Feb 2024 12:25:46 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0AEAD62807;\n\tMon, 19 Feb 2024 13:25:46 +0100 (CET)","from mail-ed1-x534.google.com (mail-ed1-x534.google.com\n\t[IPv6:2a00:1450:4864:20::534])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 65BA761C9E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 19 Feb 2024 13:25:44 +0100 (CET)","by mail-ed1-x534.google.com with SMTP id\n\t4fb4d7f45d1cf-55a179f5fa1so5741239a12.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 19 Feb 2024 04:25:44 -0800 (PST)","from [192.168.118.26] ([87.116.165.182])\n\tby smtp.gmail.com with ESMTPSA id\n\tef3-20020a05640228c300b005640022af58sm2649420edb.83.2024.02.19.04.25.42\n\t(version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n\tMon, 19 Feb 2024 04:25:43 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"Sd52rpiT\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=gmail.com; s=20230601; t=1708345544; x=1708950344;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:in-reply-to:references:cc:to:from\n\t:content-language:subject:user-agent:mime-version:date:message-id\n\t:from:to:cc:subject:date:message-id:reply-to;\n\tbh=iLved3aPR78Cih3ajCtTrfNkZl0k6MXdQz6UZWS4ViQ=;\n\tb=Sd52rpiTohAIv4eRAc9H19bsMfwL8sbPjb4j5RBofS4iylez6Fv8xzfrSxKs+Yz8yO\n\tBRpcm4ToK/thmS4hSn1QHd0bqeIDl+pvXoyJpn02Llgn72g8gdZRGISFjxUTeecaBZ+i\n\txK1I0ZPV02dQMQSTM/GTFUBrpAXAoWF7qxv73YRmgPOtrcylOvNoud9/0G0PuSZc3TvA\n\t8fY3HXeV3HP4x0fgx/gsB+GgMBuZEUfUh1q2gzdlcu7XldRSCM9EbkEOijR6pI3a+G7O\n\tjqXIIgxgi2MrVGICm3nNoR0N0L2M6zhYGeZ1hQmOkFl/egj/R56WXMOToZDge3bssGlY\n\tMNow==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1708345544; x=1708950344;\n\th=content-transfer-encoding:in-reply-to:references:cc:to:from\n\t:content-language:subject:user-agent:mime-version:date:message-id\n\t:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n\tbh=iLved3aPR78Cih3ajCtTrfNkZl0k6MXdQz6UZWS4ViQ=;\n\tb=gYOdUeNXqTqAsP9oZux4j1GBQmEEd7+igtUs7zOrAkpOoMuedrA0+frRODjy6YKyFa\n\tKcwcdShvyavYvF0iMMvQQaJes+vU8yKGKzTojMWAL/vByrlcLtriHCh9TnS6CbFrP32v\n\tvzoGt249Uk7l405ACYI84Cfm5mkRdKxgJN4ObN0PqkwTeAp7wDSfU8kjunk9cxwLtaQq\n\t87B4kHuVkKP/VW7gLSCRsVjYaOF0Vh+3BJDDSq1i/B/nTX0Wbb2uiRl/1gtO5OkmyomS\n\totNiUhtIjq/+xFSV9onMUv+baivFsxh8ppl7dwhag9QKhXT1rWZgAu5mXBjDJgHfKyTp\n\taDLA==","X-Forwarded-Encrypted":"i=1;\n\tAJvYcCUoQNiox1m47tPf2WkVdUEVhXRnuU1fzymPfs4Ax6yXmG77RdUxxxgq4bThTPdLRjg/Cd3doqCLfH65fWYeZ8v00UPJA62yh1A0l8u9IV95y9UeVA==","X-Gm-Message-State":"AOJu0YzRoJY/G49vTi6o/b5XyxuCy9dpIqkTgLWwlMNt4P2S0Nol1aLF\n\tW1dSKSj/SXWZQGaaUtShj9CwpNADsGYiiKRhy/zPO3bdl/LSzo03","X-Google-Smtp-Source":"AGHT+IHvQASF2pVZHGuI3qZT6VWkiZsitlESJU+qaGjSv6OL45TR7yEO3WCwtSJMJmBHB3FCO5RIzQ==","X-Received":"by 2002:aa7:c0d7:0:b0:564:3fe7:5843 with SMTP id\n\tj23-20020aa7c0d7000000b005643fe75843mr2897188edp.27.1708345543637; \n\tMon, 19 Feb 2024 04:25:43 -0800 (PST)","Message-ID":"<e61756a8-51d5-4d40-b5f2-e0737ef39623@gmail.com>","Date":"Mon, 19 Feb 2024 15:25:42 +0300","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v3 05/16] libcamera: shared_mem_object: reorganize the\n\tcode and document the SharedMemObject class","Content-Language":"en-US","From":"Andrei Konovalov <andrey.konovalov.ynk@gmail.com>","To":"Naushir Patuck <naush@raspberrypi.com>","References":"<20240214170122.60754-1-hdegoede@redhat.com>\n\t<20240214170122.60754-6-hdegoede@redhat.com>\n\t<CAEmqJPoUDq50Z3Xw7oi+=TWq5X9BVgBEQTHG=wn_G2SLnFKPBQ@mail.gmail.com>\n\t<8fcf18ff-e855-4763-979d-eb40f2df350f@gmail.com>","In-Reply-To":"<8fcf18ff-e855-4763-979d-eb40f2df350f@gmail.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"Maxime Ripard <mripard@redhat.com>, libcamera-devel@lists.libcamera.org, \n\tPavel Machek <pavel@ucw.cz>,\n\tBryan O'Donoghue <bryan.odonoghue@linaro.org>, \n\tDennis Bonke <admin@dennisbonke.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]