Skip to content

Commit

Permalink
io/UniqueFileDescriptor: use AdoptTag in the constructors that adopt …
Browse files Browse the repository at this point in the history
…ownership
  • Loading branch information
MaxKellermann committed Jan 23, 2025
1 parent 765a6a2 commit 35dc1fc
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/event/InotifyEvent.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ CreateInotify()
if (fd < 0)
throw MakeErrno("inotify_init1() failed");

return UniqueFileDescriptor(fd);
return UniqueFileDescriptor(AdoptTag{}, fd);
}

InotifyEvent::InotifyEvent(EventLoop &event_loop, InotifyHandler &_handler)
Expand Down
2 changes: 1 addition & 1 deletion src/io/FileDescriptor.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ FileDescriptor::SetPipeCapacity(unsigned capacity) const noexcept
UniqueFileDescriptor
FileDescriptor::Duplicate() const noexcept
{
return UniqueFileDescriptor{::dup(Get())};
return UniqueFileDescriptor{AdoptTag{}, ::dup(Get())};
}

bool
Expand Down
5 changes: 3 additions & 2 deletions src/io/UniqueFileDescriptor.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#pragma once

#include "FileDescriptor.hxx" // IWYU pragma: export
#include "util/TagStructs.hxx"

#include <cassert>
#include <utility>
Expand All @@ -16,10 +17,10 @@ public:
UniqueFileDescriptor() noexcept
:FileDescriptor(FileDescriptor::Undefined()) {}

explicit UniqueFileDescriptor(int _fd) noexcept
explicit UniqueFileDescriptor(AdoptTag, int _fd) noexcept
:FileDescriptor(_fd) {}

explicit UniqueFileDescriptor(FileDescriptor _fd) noexcept
explicit UniqueFileDescriptor(AdoptTag, FileDescriptor _fd) noexcept
:FileDescriptor(_fd) {}

UniqueFileDescriptor(const UniqueFileDescriptor &) = delete;
Expand Down
2 changes: 1 addition & 1 deletion src/net/SocketDescriptor.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ SocketDescriptor::GetPeerPidfd() const noexcept
if (GetOption(SOL_SOCKET, SO_PEERPIDFD, &pidfd, sizeof(pidfd)) < sizeof(pidfd))
return {};

return UniqueFileDescriptor{pidfd};
return UniqueFileDescriptor{AdoptTag{}, pidfd};
}

#endif // __linux__
Expand Down
2 changes: 1 addition & 1 deletion src/net/UniqueSocketDescriptor.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public:

#ifndef _WIN32
UniqueFileDescriptor MoveToFileDescriptor() && noexcept {
return UniqueFileDescriptor{Release().ToFileDescriptor()};
return UniqueFileDescriptor{AdoptTag{}, Release().ToFileDescriptor()};
}
#endif

Expand Down
105 changes: 105 additions & 0 deletions src/net/UniqueSocketDescriptor.hxx.orig
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// SPDX-License-Identifier: BSD-2-Clause
// author: Max Kellermann <[email protected]>

#pragma once

#include "SocketDescriptor.hxx"

#ifndef _WIN32
#include "io/UniqueFileDescriptor.hxx"
#endif

#include <utility>

class StaticSocketAddress;

/**
* Wrapper for a socket file descriptor.
*/
class UniqueSocketDescriptor : public SocketDescriptor {
public:
UniqueSocketDescriptor() noexcept
:SocketDescriptor(SocketDescriptor::Undefined()) {}

explicit UniqueSocketDescriptor(SocketDescriptor _fd) noexcept
:SocketDescriptor(_fd) {}
#ifndef _WIN32
explicit UniqueSocketDescriptor(FileDescriptor _fd) noexcept
:SocketDescriptor(_fd) {}

explicit UniqueSocketDescriptor(UniqueFileDescriptor &&_fd) noexcept
:SocketDescriptor(_fd.Release()) {}
#endif // !_WIN32

explicit UniqueSocketDescriptor(int _fd) noexcept
:SocketDescriptor(_fd) {}

#ifdef _WIN32
UniqueSocketDescriptor(UniqueSocketDescriptor &&other) noexcept
:SocketDescriptor(std::exchange(other.fd, INVALID_SOCKET)) {}
#else // !_WIN32
UniqueSocketDescriptor(UniqueSocketDescriptor &&other) noexcept
:SocketDescriptor(std::exchange(other.fd, -1)) {}
#endif // !_WIN32

~UniqueSocketDescriptor() noexcept {
if (IsDefined())
Close();
}

/**
* Release ownership and return the descriptor as an unmanaged
* #SocketDescriptor instance.
*/
SocketDescriptor Release() noexcept {
return std::exchange(*(SocketDescriptor *)this, Undefined());
}

#ifndef _WIN32
UniqueFileDescriptor MoveToFileDescriptor() && noexcept {
return UniqueFileDescriptor{Release().ToFileDescriptor()};
}
#endif

UniqueSocketDescriptor &operator=(UniqueSocketDescriptor &&src) noexcept {
using std::swap;
swap(fd, src.fd);
return *this;
}

bool operator==(const UniqueSocketDescriptor &other) const noexcept {
return fd == other.fd;
}

/**
* @return an "undefined" instance on error
*/
UniqueSocketDescriptor AcceptNonBlock() const noexcept {
return UniqueSocketDescriptor(SocketDescriptor::AcceptNonBlock());
}

/**
* @return an "undefined" instance on error
*/
UniqueSocketDescriptor AcceptNonBlock(StaticSocketAddress &address) const noexcept {
return UniqueSocketDescriptor(SocketDescriptor::AcceptNonBlock(address));
}

#ifndef _WIN32
static bool CreateSocketPair(int domain, int type, int protocol,
UniqueSocketDescriptor &a,
UniqueSocketDescriptor &b) noexcept {
return SocketDescriptor::CreateSocketPair(domain, type,
protocol,
a, b);
}

static bool CreateSocketPairNonBlock(int domain, int type, int protocol,
UniqueSocketDescriptor &a,
UniqueSocketDescriptor &b) noexcept {
return SocketDescriptor::CreateSocketPairNonBlock(domain, type,
protocol,
a, b);
}
#endif
};
2 changes: 1 addition & 1 deletion src/system/EpollFD.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "Error.hxx"

EpollFD::EpollFD()
:fd(::epoll_create1(EPOLL_CLOEXEC))
:fd(AdoptTag{}, ::epoll_create1(EPOLL_CLOEXEC))
{
if (!fd.IsDefined())
throw MakeErrno("epoll_create1() failed");
Expand Down
2 changes: 1 addition & 1 deletion src/system/EventFD.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <sys/eventfd.h>

EventFD::EventFD()
:fd(::eventfd(0, EFD_NONBLOCK|EFD_CLOEXEC))
:fd(AdoptTag{}, ::eventfd(0, EFD_NONBLOCK|EFD_CLOEXEC))
{
if (!fd.IsDefined())
throw MakeErrno("eventfd() failed");
Expand Down
2 changes: 1 addition & 1 deletion src/system/SignalFD.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ SignalFD::Create(const sigset_t &mask)
throw MakeErrno("signalfd() failed");

if (!fd.IsDefined()) {
fd = UniqueFileDescriptor{new_fd};
fd = UniqueFileDescriptor{AdoptTag{}, new_fd};
}

assert(new_fd == fd.Get());
Expand Down

0 comments on commit 35dc1fc

Please sign in to comment.