From afcd7c33e72666494b8f6ed354ac6ad5a6222a25 Mon Sep 17 00:00:00 2001 From: Martin Haefner Date: Mon, 23 Aug 2021 11:47:28 +0200 Subject: [PATCH] std::ref support for FileDescriptor to reduce dup() calls --- include/simppl/filedescriptor.h | 13 ++++++ src/filedescriptor.cpp | 81 +++++++++++++++++++++++---------- 2 files changed, 71 insertions(+), 23 deletions(-) diff --git a/include/simppl/filedescriptor.h b/include/simppl/filedescriptor.h index 38b4e76..9ac2175 100644 --- a/include/simppl/filedescriptor.h +++ b/include/simppl/filedescriptor.h @@ -4,6 +4,9 @@ #include "simppl/serialization.h" +#include +#include + namespace simppl { @@ -21,9 +24,18 @@ class FileDescriptor FileDescriptor(); + /** + * RAII behaviour: destroys the fd by calling close on object destruction. + */ explicit FileDescriptor(int fd); + /** + * Non-RAII behaviour: keeps fd open on object destruction. + */ + explicit + FileDescriptor(std::reference_wrapper fd); + ~FileDescriptor(); FileDescriptor(const FileDescriptor& rhs); @@ -38,6 +50,7 @@ class FileDescriptor private: int fd_; + int (*destructor_)(int); }; diff --git a/src/filedescriptor.cpp b/src/filedescriptor.cpp index c693db4..cfef731 100644 --- a/src/filedescriptor.cpp +++ b/src/filedescriptor.cpp @@ -2,18 +2,30 @@ #include -#include + +namespace { + + int noop(int) + { + // NOOP + return 0; + } +} + + +// --------------------------------------------------------------------- namespace simppl { - + namespace dbus { FileDescriptor::FileDescriptor() : fd_(-1) + , destructor_(&close) { // NOOP } @@ -21,23 +33,38 @@ FileDescriptor::FileDescriptor() FileDescriptor::FileDescriptor(int fd) : fd_(fd) + , destructor_(&close) +{ + assert(fd >= 0); +} + + +FileDescriptor::FileDescriptor(std::reference_wrapper fd) + : fd_(fd) + , destructor_(&noop) { assert(fd >= 0); } - + FileDescriptor::~FileDescriptor() { if (fd_ != -1) - close(fd_); + (*destructor_)(fd_); } - + FileDescriptor::FileDescriptor(const FileDescriptor& rhs) : fd_(-1) + , destructor_(rhs.destructor_) { if (rhs.fd_ != -1) - fd_ = dup(rhs.fd_); + { + if (destructor_ == &noop) + fd_ = rhs.fd_; + else + fd_ = dup(rhs.fd_); + } } @@ -46,22 +73,28 @@ FileDescriptor& FileDescriptor::operator=(const FileDescriptor& rhs) if (this != &rhs) { if (fd_ != -1) - close(fd_); - + (*destructor_)(fd_); + if (rhs.fd_ != -1) { - fd_ = dup(rhs.fd_); + if (rhs.destructor_ == &noop) + fd_ = rhs.fd_; + else + fd_ = dup(rhs.fd_); } else fd_ = -1; + + destructor_ = rhs.destructor_; } - + return *this; } FileDescriptor::FileDescriptor(FileDescriptor&& rhs) : fd_(rhs.fd_) + , destructor_(rhs.destructor_) { rhs.fd_ = -1; } @@ -70,13 +103,13 @@ FileDescriptor::FileDescriptor(FileDescriptor&& rhs) FileDescriptor& FileDescriptor::operator=(int fd) { if (fd_ != -1) - close(fd_); - + (*destructor_)(fd_); + fd_ = fd; - + if (fd_ < 0) fd_ = -1; - + return *this; } @@ -84,11 +117,13 @@ FileDescriptor& FileDescriptor::operator=(int fd) FileDescriptor& FileDescriptor::operator=(FileDescriptor&& rhs) { if (fd_ != -1) - close(fd_); - + (*destructor_)(fd_); + fd_ = rhs.fd_; rhs.fd_ = -1; - + + destructor_ = rhs.destructor_; + return *this; } @@ -103,12 +138,12 @@ int FileDescriptor::release() { int fd = fd_; fd_ = -1; - + return fd; } -/*static*/ +/*static*/ void FileDescriptorCodec::encode(DBusMessageIter& iter, const FileDescriptor& fd) { int _fd = fd.native_handle(); @@ -116,7 +151,7 @@ void FileDescriptorCodec::encode(DBusMessageIter& iter, const FileDescriptor& fd } -/*static*/ +/*static*/ void FileDescriptorCodec::decode(DBusMessageIter& iter, FileDescriptor& fd) { int _fd; @@ -125,13 +160,13 @@ void FileDescriptorCodec::decode(DBusMessageIter& iter, FileDescriptor& fd) } -/*static*/ +/*static*/ std::ostream& FileDescriptorCodec::make_type_signature(std::ostream& os) { return os << DBUS_TYPE_UNIX_FD_AS_STRING; } - - + + } // namespace dbus } // namespace simppl