[libcamera-devel] [RFC PATCH 01/10] libcamera: ScopedFD: Introduce ScopedFD
Hirokazu Honda
hiroh at chromium.org
Thu Apr 15 10:38:34 CEST 2021
This introduces ScopedFD. It acts like unique_ptr to a file
descriptor.
Signed-off-by: Hirokazu Honda <hiroh at chromium.org>
---
include/libcamera/meson.build | 1 +
include/libcamera/scoped_file_descriptor.h | 38 +++++++
src/libcamera/meson.build | 1 +
src/libcamera/scoped_file_descriptor.cpp | 119 +++++++++++++++++++++
4 files changed, 159 insertions(+)
create mode 100644 include/libcamera/scoped_file_descriptor.h
create mode 100644 src/libcamera/scoped_file_descriptor.cpp
diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build
index c7b8ee8e..a56f2d26 100644
--- a/include/libcamera/meson.build
+++ b/include/libcamera/meson.build
@@ -15,6 +15,7 @@ libcamera_public_headers = files([
'object.h',
'pixel_format.h',
'request.h',
+ 'scoped_file_descriptor.h',
'signal.h',
'span.h',
'stream.h',
diff --git a/include/libcamera/scoped_file_descriptor.h b/include/libcamera/scoped_file_descriptor.h
new file mode 100644
index 00000000..baff366a
--- /dev/null
+++ b/include/libcamera/scoped_file_descriptor.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021, Google Inc.
+ *
+ * scoped_file_descriptor.h - File descriptor wrapper that owns a file descriptor.
+ */
+#ifndef __LIBCAMERA_SCOPED_FILE_DESCRIPTOR_H__
+#define __LIBCAMERA_SCOPED_FILE_DESCRIPTOR_H__
+
+#include <libcamera/compiler.h>
+
+namespace libcamera {
+
+class ScopedFD final
+{
+ constexpr static int kInvalidFD = -1;
+public:
+ explicit ScopedFD(const int fd = kInvalidFD);
+ ~ScopedFD();
+ ScopedFD(ScopedFD &&other);
+ ScopedFD &operator=(ScopedFD &&other);
+
+ // Move-only.
+ ScopedFD(const ScopedFD &) = delete;
+ ScopedFD &operator=(const ScopedFD &) = delete;
+
+ bool isValid() const { return fd_ != kInvalidFD; }
+ int get() const { return fd_; }
+ void reset(const int fd = kInvalidFD);
+ __nodiscard int release();
+
+private:
+ int fd_;
+};
+
+} /* namespace libcamera */
+
+#endif /* __LIBCAMERA_SCOPED_FILE_DESCRIPTOR_H__ */
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index e0a48aa2..6306730a 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -43,6 +43,7 @@ libcamera_sources = files([
'process.cpp',
'pub_key.cpp',
'request.cpp',
+ 'scoped_file_descriptor.cpp',
'semaphore.cpp',
'signal.cpp',
'stream.cpp',
diff --git a/src/libcamera/scoped_file_descriptor.cpp b/src/libcamera/scoped_file_descriptor.cpp
new file mode 100644
index 00000000..1a5b1f9f
--- /dev/null
+++ b/src/libcamera/scoped_file_descriptor.cpp
@@ -0,0 +1,119 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021, Google Inc.
+ *
+ * scoped_file_descriptor.cpp - File descriptor wrapper that owns a file descriptor.
+ */
+
+#include <libcamera/scoped_file_descriptor.h>
+
+#include <algorithm>
+#include <unistd.h>
+
+#include "libcamera/internal/log.h"
+
+namespace libcamera {
+
+LOG_DECLARE_CATEGORY(ScopedFileDescriptor)
+
+/**
+ * \class ScopedFD
+ * \brief unique_ptr like wrapper for a file descriptor.
+ *
+ * The ScopedFD provies RAII-style lifetime management of a file descriptor.
+ * It doesn't allow the shared ownership unlike FileDescriptor. It constructs
+ * with a numerical file descriptor and takes over the file descriptor.
+ */
+
+/**
+ * \brief Create a ScopedFD taking over a given \a fd.
+ * \param[in] fd a numerical file descriptor.
+ *
+ * Construct a ScopedFD from a numerical file descriptor and take ownership of
+ * the file descriptor. So a caller must not close it. The given file descriptor
+ * is automatically closed when the ScopedFD is destructed.
+ */
+ScopedFD::ScopedFD(const int fd)
+ : fd_(fd)
+{
+}
+
+/**
+ * \brief Destroy the ScopedFD instance
+ *
+ * Destroying a ScopedFD instance. The owned file descriptor is automatically
+ * closed if it is valid.
+ */
+ScopedFD::~ScopedFD()
+{
+ reset();
+}
+
+/**
+ * \brief Move constructor, create a ScopedFD by taking over \a other
+ * \param[in] other The other ScopedFD.
+ *
+ * Create a ScopedFD with taking the ownership of a file descriptor owned by \a
+ * other.
+ */
+ScopedFD::ScopedFD(ScopedFD &&other)
+ : fd_(other.release())
+{
+}
+
+/**
+ * \brief Move assignment operator, replace a ScopedFD by taking over \a other
+ * \param[in] other The other ScopedFD.
+ *
+ * If a moving ScopedFD has a valid file descriptor, the file descriptor is
+ * closed and then replaced with a file descriptor owned by \a other. As a
+ * result, \a other no longer owns a valid file descriptor.
+ *
+ * \return A reference to this ScopedFD.
+ */
+ScopedFD &ScopedFD::operator=(ScopedFD &&other)
+{
+ reset(other.release());
+
+ return *this;
+}
+
+/**
+ * \fn ScopedFD::isValid()
+ * \brief Check if the ScopedFD has a valid file descriptor.
+ * \return True if the ScopedFD has a valid file descriptor, false otherwise
+ */
+
+/**
+ * \fn ScopedFD::get()
+ * \brief Retrieve the numerical file descriptor
+ * \return The numerical file descriptor.
+ */
+
+/**
+ * \fn ScopedFD::reset()
+ * \param[in] int a numerical file descriptor.
+ * \brief Swap the owned file descriptor with \a fd. The originally owned file
+ * descriptor is closed.
+ */
+void ScopedFD::reset(const int fd)
+{
+ ASSERT(!isValid() || fd != fd_);
+ if (isValid())
+ close(fd_);
+ fd_ = fd;
+}
+
+/**
+ * \fn ScopedFD::release()
+ * \brief Retrieve a numerical file descriptor. ScopedFD releases the ownership
+ * of it and the caller takes the ownership of it.
+ * \return A numerical file descriptor.
+ */
+int ScopedFD::release()
+{
+ int fd = fd_;
+ fd_ = kInvalidFD;
+ return fd;
+}
+} /* namespace libcamera */
--
2.31.1.368.gbe11c130af-goog
More information about the libcamera-devel
mailing list