Skip to content

Commit

Permalink
std::ref support for FileDescriptor to reduce dup() calls
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Haefner committed Aug 23, 2021
1 parent 24eeb7d commit afcd7c3
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 23 deletions.
13 changes: 13 additions & 0 deletions include/simppl/filedescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

#include "simppl/serialization.h"

#include <unistd.h>
#include <functional>


namespace simppl
{
Expand All @@ -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<int> fd);

~FileDescriptor();

FileDescriptor(const FileDescriptor& rhs);
Expand All @@ -38,6 +50,7 @@ class FileDescriptor

private:
int fd_;
int (*destructor_)(int);
};


Expand Down
81 changes: 58 additions & 23 deletions src/filedescriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,69 @@

#include <cassert>

#include <unistd.h>

namespace {

int noop(int)
{
// NOOP
return 0;
}
}


// ---------------------------------------------------------------------


namespace simppl
{

namespace dbus
{


FileDescriptor::FileDescriptor()
: fd_(-1)
, destructor_(&close)
{
// NOOP
}


FileDescriptor::FileDescriptor(int fd)
: fd_(fd)
, destructor_(&close)
{
assert(fd >= 0);
}


FileDescriptor::FileDescriptor(std::reference_wrapper<int> 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_);
}
}


Expand All @@ -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;
}
Expand All @@ -70,25 +103,27 @@ 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;
}


FileDescriptor& FileDescriptor::operator=(FileDescriptor&& rhs)
{
if (fd_ != -1)
close(fd_);
(*destructor_)(fd_);

fd_ = rhs.fd_;
rhs.fd_ = -1;


destructor_ = rhs.destructor_;

return *this;
}

Expand All @@ -103,20 +138,20 @@ 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();
dbus_message_iter_append_basic(&iter, DBUS_TYPE_UNIX_FD, &_fd);
}


/*static*/
/*static*/
void FileDescriptorCodec::decode(DBusMessageIter& iter, FileDescriptor& fd)
{
int _fd;
Expand All @@ -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

0 comments on commit afcd7c3

Please sign in to comment.