Patch Detail
Show a patch.
GET /api/1.1/patches/12534/?format=api
{ "id": 12534, "url": "https://patchwork.libcamera.org/api/1.1/patches/12534/?format=api", "web_url": "https://patchwork.libcamera.org/patch/12534/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20210610075027.523672-2-hiroh@chromium.org>", "date": "2021-06-10T07:50:18", "name": "[libcamera-devel,v2,01/10] libcamera: ScopedFD: Introduce ScopedFD", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "53d62daa1e602a6da0e9a8ec63e998216f35c84a", "submitter": { "id": 63, "url": "https://patchwork.libcamera.org/api/1.1/people/63/?format=api", "name": "Hirokazu Honda", "email": "hiroh@chromium.org" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/12534/mbox/", "series": [ { "id": 2115, "url": "https://patchwork.libcamera.org/api/1.1/series/2115/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=2115", "date": "2021-06-10T07:50:17", "name": "Introduce ScopedFD", "version": 2, "mbox": "https://patchwork.libcamera.org/series/2115/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/12534/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/12534/checks/", "tags": {}, "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 97A07BD78E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 10 Jun 2021 07:50:39 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6991568936;\n\tThu, 10 Jun 2021 09:50:38 +0200 (CEST)", "from mail-pf1-x429.google.com (mail-pf1-x429.google.com\n\t[IPv6:2607:f8b0:4864:20::429])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id A57C6602C5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 10 Jun 2021 09:50:36 +0200 (CEST)", "by mail-pf1-x429.google.com with SMTP id u126so904995pfu.13\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 10 Jun 2021 00:50:36 -0700 (PDT)", "from hiroh2.tok.corp.google.com\n\t([2401:fa00:8f:203:98e0:b356:1c8a:25d4])\n\tby smtp.gmail.com with ESMTPSA id\n\td66sm1565161pfa.32.2021.06.10.00.50.33\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tThu, 10 Jun 2021 00:50:34 -0700 (PDT)" ], "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=chromium.org header.i=@chromium.org\n\theader.b=\"IpnhTORn\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org;\n\ts=google; \n\th=from:to:cc:subject:date:message-id:in-reply-to:references\n\t:mime-version:content-transfer-encoding;\n\tbh=VK/FliDppCrFRUYd6LB558bOEJnuwUUhkrgBuRhSYhg=;\n\tb=IpnhTORnWQ7xNYJdxDWxfErZyKzUIklfLh+NBVL4saeC+8WlWLtojYYw5Pg5dL9oqI\n\tEvzJ9JnCZh2zqIKHux65bL8sdrfWGBAEooaKigcYRCyhiDjFaWpweyuOpC52mIB+R9Kx\n\tEoARLxmMJyA6J7NApH3BOqgqw1/dNgv/g7oiE=", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references:mime-version:content-transfer-encoding;\n\tbh=VK/FliDppCrFRUYd6LB558bOEJnuwUUhkrgBuRhSYhg=;\n\tb=cKCYSJeJbro++cE/6ZB1BzDK44NGtt1Z23k0MpXs4Rra+vcPbw23xepkRiCRjwdO8c\n\tx8hOs5bORfdi6RWTiErszNLquqi7/ldi0PJwahElEls/KtvmV2fq1iaLp9xFdcSuFoHG\n\tqlwcddaHRcEytvTQjUIbCd8TGel6l3M9OFNlygBzQ0AicqaMshP05H7CNXBdHz6f6L40\n\tQInk4fqZVAZSD9monYqus40x03kI1JYJCf5sgy+0mzsTHohm5pfep2tYXYcZ63bKPaAW\n\tpxFK3KcfIzusxe38y4vFsTKB7obf1PsbiCoXSlwJ1kzvlylzmG/DJPyNoxvLHsHMuKrA\n\t4dGA==", "X-Gm-Message-State": "AOAM5317xGBsJTGVIAJOWWqjpndshG24WrVjK/e0EmcacTePMvCI7wW8\n\tQ5R/rGXK8ngHF7gut0jKEkH8ialEnP4iqA==", "X-Google-Smtp-Source": "ABdhPJyBF34RPS7l34siTXSNTbWMAvRSu489JUW1rSoRinLZ0ennB9tQeyEzVCRy4Dxczlrmsm9xhg==", "X-Received": "by 2002:a63:ee11:: with SMTP id\n\te17mr3711858pgi.323.1623311434901; \n\tThu, 10 Jun 2021 00:50:34 -0700 (PDT)", "From": "Hirokazu Honda <hiroh@chromium.org>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Thu, 10 Jun 2021 16:50:18 +0900", "Message-Id": "<20210610075027.523672-2-hiroh@chromium.org>", "X-Mailer": "git-send-email 2.32.0.rc1.229.g3e70b5a671-goog", "In-Reply-To": "<20210610075027.523672-1-hiroh@chromium.org>", "References": "<20210610075027.523672-1-hiroh@chromium.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH v2 01/10] libcamera: ScopedFD: Introduce\n\tScopedFD", "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>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "This introduces ScopedFD. It acts like unique_ptr to a file\ndescriptor.\n\nSigned-off-by: Hirokazu Honda <hiroh@chromium.org>\n---\n include/libcamera/file_descriptor.h | 3 +\n include/libcamera/meson.build | 1 +\n include/libcamera/scoped_fd.h | 36 ++++++++\n src/libcamera/file_descriptor.cpp | 20 +++++\n src/libcamera/meson.build | 1 +\n src/libcamera/scoped_fd.cpp | 129 ++++++++++++++++++++++++++++\n 6 files changed, 190 insertions(+)\n create mode 100644 include/libcamera/scoped_fd.h\n create mode 100644 src/libcamera/scoped_fd.cpp", "diff": "diff --git a/include/libcamera/file_descriptor.h b/include/libcamera/file_descriptor.h\nindex d514aac7..1d71d58c 100644\n--- a/include/libcamera/file_descriptor.h\n+++ b/include/libcamera/file_descriptor.h\n@@ -11,11 +11,14 @@\n \n namespace libcamera {\n \n+class ScopedFD;\n+\n class FileDescriptor final\n {\n public:\n \texplicit FileDescriptor(const int &fd = -1);\n \texplicit FileDescriptor(int &&fd);\n+\texplicit FileDescriptor(ScopedFD &&fd);\n \tFileDescriptor(const FileDescriptor &other);\n \tFileDescriptor(FileDescriptor &&other);\n \t~FileDescriptor();\ndiff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\nindex 086c958b..e1c8b253 100644\n--- a/include/libcamera/meson.build\n+++ b/include/libcamera/meson.build\n@@ -15,6 +15,7 @@ libcamera_public_headers = files([\n 'object.h',\n 'pixel_format.h',\n 'request.h',\n+ 'scoped_fd.h',\n 'signal.h',\n 'span.h',\n 'stream.h',\ndiff --git a/include/libcamera/scoped_fd.h b/include/libcamera/scoped_fd.h\nnew file mode 100644\nindex 00000000..d91b53b4\n--- /dev/null\n+++ b/include/libcamera/scoped_fd.h\n@@ -0,0 +1,36 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2021, Google Inc.\n+ *\n+ * scoped_fd.h - File descriptor wrapper that owns a file descriptor.\n+ */\n+#ifndef __LIBCAMERA_SCOPED_FD_H__\n+#define __LIBCAMERA_SCOPED_FD_H__\n+\n+#include <libcamera/class.h>\n+#include <libcamera/compiler.h>\n+\n+namespace libcamera {\n+\n+class ScopedFD final\n+{\n+public:\n+\texplicit ScopedFD(const int fd = -1);\n+\t~ScopedFD();\n+\tScopedFD(ScopedFD &&other);\n+\tScopedFD &operator=(ScopedFD &&other);\n+\n+\tbool isValid() const { return fd_ == -1; }\n+\tint get() const { return fd_; }\n+\tvoid reset(int fd = -1);\n+\t__nodiscard int release();\n+\n+private:\n+\tint fd_;\n+\n+\tLIBCAMERA_DISABLE_COPY(ScopedFD)\n+};\n+\n+} /* namespace libcamera */\n+\n+#endif /* __LIBCAMERA_SCOPED_FD_H__ */\ndiff --git a/src/libcamera/file_descriptor.cpp b/src/libcamera/file_descriptor.cpp\nindex 8b505ed3..4d30b757 100644\n--- a/src/libcamera/file_descriptor.cpp\n+++ b/src/libcamera/file_descriptor.cpp\n@@ -11,6 +11,8 @@\n #include <unistd.h>\n #include <utility>\n \n+#include <libcamera/scoped_fd.h>\n+\n #include \"libcamera/internal/log.h\"\n \n /**\n@@ -108,6 +110,24 @@ FileDescriptor::FileDescriptor(int &&fd)\n \tfd = -1;\n }\n \n+/**\n+ * \\brief Create a FileDescriptor taking ownership of a given ScopedFD \\a fd\n+ * \\param[in] fd ScopedFD\n+ *\n+ * Construct a FileDescriptor from ScopedFD by taking ownership of the \\a fd.\n+ * The original \\a fd becomes invalid. In particular, the caller shall not close\n+ * the original \\a fd manually. The duplicated file descriptor will be closed\n+ * automatically when all FileDescriptor instances that reference it are\n+ * destroyed.\n+ *\n+ * If the \\a fd is negative, the FileDescriptor is constructed as invalid and\n+ * the fd() method will return -1.\n+ */\n+FileDescriptor::FileDescriptor(ScopedFD &&fd)\n+\t: FileDescriptor(fd.release())\n+{\n+}\n+\n /**\n * \\brief Copy constructor, create a FileDescriptor from a copy of \\a other\n * \\param[in] other The other FileDescriptor\ndiff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\nindex 7e19a177..ed311acf 100644\n--- a/src/libcamera/meson.build\n+++ b/src/libcamera/meson.build\n@@ -44,6 +44,7 @@ libcamera_sources = files([\n 'process.cpp',\n 'pub_key.cpp',\n 'request.cpp',\n+ 'scoped_fd.cpp',\n 'semaphore.cpp',\n 'signal.cpp',\n 'stream.cpp',\ndiff --git a/src/libcamera/scoped_fd.cpp b/src/libcamera/scoped_fd.cpp\nnew file mode 100644\nindex 00000000..106386dd\n--- /dev/null\n+++ b/src/libcamera/scoped_fd.cpp\n@@ -0,0 +1,129 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2021, Google Inc.\n+ *\n+ * scoped_fd.cpp - File descriptor wrapper that owns a file descriptor.\n+ */\n+\n+#include <libcamera/scoped_fd.h>\n+\n+#include <unistd.h>\n+\n+#include \"libcamera/internal/log.h\"\n+\n+/**\n+ * \\file scoped_fd.h\n+ * \\brief File descriptor wrapper that owns a file descriptor\n+ */\n+\n+namespace libcamera {\n+\n+LOG_DEFINE_CATEGORY(ScopedFD)\n+\n+/**\n+ * \\class ScopedFD\n+ * \\brief unique_ptr like wrapper for a file descriptor\n+ *\n+ * The ScopedFD provides RAII-style lifetime management of a file descriptor.\n+ * It doesn't allow the shared ownership unlike FileDescriptor. It is\n+ * constructed from a numerical file descriptor and takes over the ownership of\n+ * the file descriptor. When the ScopedFD is destroyed, the managed file\n+ * descriptor is closed.\n+ */\n+\n+/**\n+ * \\brief Create a ScopedFD taking over a given \\a fd\n+ * \\param[in] fd a numerical file descriptor\n+ *\n+ * Construct a ScopedFD from a numerical file descriptor and take ownership of\n+ * the file descriptor. The given file descriptor is automatically closed when\n+ * the ScopedFD is destructed.\n+ */\n+ScopedFD::ScopedFD(const int fd)\n+\t: fd_(fd >= 0 ? fd : -1)\n+{\n+}\n+\n+/**\n+ * \\brief Destroy the ScopedFD instance\n+ *\n+ * The owned file descriptor is automatically closed if it is valid.\n+ */\n+ScopedFD::~ScopedFD()\n+{\n+\treset();\n+}\n+\n+/**\n+ * \\brief Move constructor, create a ScopedFD by taking over \\a other\n+ * \\param[in] other The other ScopedFD\n+ *\n+ * Create a ScopedFD that takes the ownership of the file descriptor owned by \\a\n+ * other. Upon return, the \\a other ScopedFD is invalid.\n+ */\n+ScopedFD::ScopedFD(ScopedFD &&other)\n+\t: fd_(other.release())\n+{\n+}\n+\n+/**\n+ * \\brief Move assignment operator, replace a ScopedFD by taking over \\a other\n+ * \\param[in] other The other ScopedFD\n+ *\n+ * If this ScopedFD has a valid file descriptor, the file descriptor is closed\n+ * first. The file descriptor is then replaced by the one of \\a other. Upon\n+ * return, \\a other is invalid.\n+ *\n+ * \\return A reference to this ScopedFD\n+ */\n+ScopedFD &ScopedFD::operator=(ScopedFD &&other)\n+{\n+\treset(other.release());\n+\n+\treturn *this;\n+}\n+\n+/**\n+ * \\fn ScopedFD::isValid()\n+ * \\brief Check if the ScopedFD has a valid file descriptor\n+ * \\return True if the ScopedFD has a valid file descriptor, false otherwise\n+ */\n+\n+/**\n+ * \\fn ScopedFD::get()\n+ * \\brief Retrieve the numerical file descriptor\n+ * \\return The numerical file descriptor\n+ */\n+\n+/**\n+ * \\fn ScopedFD::reset()\n+ * \\brief Swap the owned file descriptor with \\a fd. The originally owned file\n+ * descriptor is closed.\n+ * \\param[in] fd a numerical file descriptor\n+ */\n+void ScopedFD::reset(int fd)\n+{\n+\tASSERT(!isValid() || fd != fd_);\n+\tif (isValid())\n+\t\tclose(fd_);\n+\tfd_ = fd;\n+}\n+\n+/**\n+ * \\fn ScopedFD::release()\n+ * \\brief Release ownership of the file descriptor without closing it\n+ *\n+ * This function releases and returns the owned file descriptor without closing\n+ * it. The caller owns the returned value and must take care of handling its\n+ * life time to avoid file descriptor leakages. Upon return the ScopedFD is\n+ * invalid.\n+ *\n+ * \\return The numerical file descriptor\n+ */\n+int ScopedFD::release()\n+{\n+\tint fd = fd_;\n+\tfd_ = -1;\n+\treturn fd;\n+}\n+} /* namespace libcamera */\n", "prefixes": [ "libcamera-devel", "v2", "01/10" ] }