io/UniqueFileDescriptor: use AdoptTag in the constructors that adopt ownership

This commit is contained in:
Max Kellermann 2025-01-23 16:47:13 +01:00 committed by Max Kellermann
parent 765a6a2f20
commit 35dc1fc589
9 changed files with 115 additions and 9 deletions

@ -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)

@ -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

@ -4,6 +4,7 @@
#pragma once
#include "FileDescriptor.hxx" // IWYU pragma: export
#include "util/TagStructs.hxx"
#include <cassert>
#include <utility>
@ -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;

@ -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__

@ -58,7 +58,7 @@ public:
#ifndef _WIN32
UniqueFileDescriptor MoveToFileDescriptor() && noexcept {
return UniqueFileDescriptor{Release().ToFileDescriptor()};
return UniqueFileDescriptor{AdoptTag{}, Release().ToFileDescriptor()};
}
#endif

@ -0,0 +1,105 @@
// SPDX-License-Identifier: BSD-2-Clause
// author: Max Kellermann <max.kellermann@gmail.com>
#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
};

@ -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");

@ -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");

@ -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());