[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