Skip to content

Commit 35dc1fc

Browse files
committed
io/UniqueFileDescriptor: use AdoptTag in the constructors that adopt ownership
1 parent 765a6a2 commit 35dc1fc

9 files changed

+115
-9
lines changed

src/event/InotifyEvent.cxx

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ CreateInotify()
1818
if (fd < 0)
1919
throw MakeErrno("inotify_init1() failed");
2020

21-
return UniqueFileDescriptor(fd);
21+
return UniqueFileDescriptor(AdoptTag{}, fd);
2222
}
2323

2424
InotifyEvent::InotifyEvent(EventLoop &event_loop, InotifyHandler &_handler)

src/io/FileDescriptor.cxx

+1-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ FileDescriptor::SetPipeCapacity(unsigned capacity) const noexcept
225225
UniqueFileDescriptor
226226
FileDescriptor::Duplicate() const noexcept
227227
{
228-
return UniqueFileDescriptor{::dup(Get())};
228+
return UniqueFileDescriptor{AdoptTag{}, ::dup(Get())};
229229
}
230230

231231
bool

src/io/UniqueFileDescriptor.hxx

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#pragma once
55

66
#include "FileDescriptor.hxx" // IWYU pragma: export
7+
#include "util/TagStructs.hxx"
78

89
#include <cassert>
910
#include <utility>
@@ -16,10 +17,10 @@ public:
1617
UniqueFileDescriptor() noexcept
1718
:FileDescriptor(FileDescriptor::Undefined()) {}
1819

19-
explicit UniqueFileDescriptor(int _fd) noexcept
20+
explicit UniqueFileDescriptor(AdoptTag, int _fd) noexcept
2021
:FileDescriptor(_fd) {}
2122

22-
explicit UniqueFileDescriptor(FileDescriptor _fd) noexcept
23+
explicit UniqueFileDescriptor(AdoptTag, FileDescriptor _fd) noexcept
2324
:FileDescriptor(_fd) {}
2425

2526
UniqueFileDescriptor(const UniqueFileDescriptor &) = delete;

src/net/SocketDescriptor.cxx

+1-1
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ SocketDescriptor::GetPeerPidfd() const noexcept
252252
if (GetOption(SOL_SOCKET, SO_PEERPIDFD, &pidfd, sizeof(pidfd)) < sizeof(pidfd))
253253
return {};
254254

255-
return UniqueFileDescriptor{pidfd};
255+
return UniqueFileDescriptor{AdoptTag{}, pidfd};
256256
}
257257

258258
#endif // __linux__

src/net/UniqueSocketDescriptor.hxx

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public:
5858

5959
#ifndef _WIN32
6060
UniqueFileDescriptor MoveToFileDescriptor() && noexcept {
61-
return UniqueFileDescriptor{Release().ToFileDescriptor()};
61+
return UniqueFileDescriptor{AdoptTag{}, Release().ToFileDescriptor()};
6262
}
6363
#endif
6464

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// SPDX-License-Identifier: BSD-2-Clause
2+
// author: Max Kellermann <[email protected]>
3+
4+
#pragma once
5+
6+
#include "SocketDescriptor.hxx"
7+
8+
#ifndef _WIN32
9+
#include "io/UniqueFileDescriptor.hxx"
10+
#endif
11+
12+
#include <utility>
13+
14+
class StaticSocketAddress;
15+
16+
/**
17+
* Wrapper for a socket file descriptor.
18+
*/
19+
class UniqueSocketDescriptor : public SocketDescriptor {
20+
public:
21+
UniqueSocketDescriptor() noexcept
22+
:SocketDescriptor(SocketDescriptor::Undefined()) {}
23+
24+
explicit UniqueSocketDescriptor(SocketDescriptor _fd) noexcept
25+
:SocketDescriptor(_fd) {}
26+
#ifndef _WIN32
27+
explicit UniqueSocketDescriptor(FileDescriptor _fd) noexcept
28+
:SocketDescriptor(_fd) {}
29+
30+
explicit UniqueSocketDescriptor(UniqueFileDescriptor &&_fd) noexcept
31+
:SocketDescriptor(_fd.Release()) {}
32+
#endif // !_WIN32
33+
34+
explicit UniqueSocketDescriptor(int _fd) noexcept
35+
:SocketDescriptor(_fd) {}
36+
37+
#ifdef _WIN32
38+
UniqueSocketDescriptor(UniqueSocketDescriptor &&other) noexcept
39+
:SocketDescriptor(std::exchange(other.fd, INVALID_SOCKET)) {}
40+
#else // !_WIN32
41+
UniqueSocketDescriptor(UniqueSocketDescriptor &&other) noexcept
42+
:SocketDescriptor(std::exchange(other.fd, -1)) {}
43+
#endif // !_WIN32
44+
45+
~UniqueSocketDescriptor() noexcept {
46+
if (IsDefined())
47+
Close();
48+
}
49+
50+
/**
51+
* Release ownership and return the descriptor as an unmanaged
52+
* #SocketDescriptor instance.
53+
*/
54+
SocketDescriptor Release() noexcept {
55+
return std::exchange(*(SocketDescriptor *)this, Undefined());
56+
}
57+
58+
#ifndef _WIN32
59+
UniqueFileDescriptor MoveToFileDescriptor() && noexcept {
60+
return UniqueFileDescriptor{Release().ToFileDescriptor()};
61+
}
62+
#endif
63+
64+
UniqueSocketDescriptor &operator=(UniqueSocketDescriptor &&src) noexcept {
65+
using std::swap;
66+
swap(fd, src.fd);
67+
return *this;
68+
}
69+
70+
bool operator==(const UniqueSocketDescriptor &other) const noexcept {
71+
return fd == other.fd;
72+
}
73+
74+
/**
75+
* @return an "undefined" instance on error
76+
*/
77+
UniqueSocketDescriptor AcceptNonBlock() const noexcept {
78+
return UniqueSocketDescriptor(SocketDescriptor::AcceptNonBlock());
79+
}
80+
81+
/**
82+
* @return an "undefined" instance on error
83+
*/
84+
UniqueSocketDescriptor AcceptNonBlock(StaticSocketAddress &address) const noexcept {
85+
return UniqueSocketDescriptor(SocketDescriptor::AcceptNonBlock(address));
86+
}
87+
88+
#ifndef _WIN32
89+
static bool CreateSocketPair(int domain, int type, int protocol,
90+
UniqueSocketDescriptor &a,
91+
UniqueSocketDescriptor &b) noexcept {
92+
return SocketDescriptor::CreateSocketPair(domain, type,
93+
protocol,
94+
a, b);
95+
}
96+
97+
static bool CreateSocketPairNonBlock(int domain, int type, int protocol,
98+
UniqueSocketDescriptor &a,
99+
UniqueSocketDescriptor &b) noexcept {
100+
return SocketDescriptor::CreateSocketPairNonBlock(domain, type,
101+
protocol,
102+
a, b);
103+
}
104+
#endif
105+
};

src/system/EpollFD.cxx

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include "Error.hxx"
66

77
EpollFD::EpollFD()
8-
:fd(::epoll_create1(EPOLL_CLOEXEC))
8+
:fd(AdoptTag{}, ::epoll_create1(EPOLL_CLOEXEC))
99
{
1010
if (!fd.IsDefined())
1111
throw MakeErrno("epoll_create1() failed");

src/system/EventFD.cxx

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include <sys/eventfd.h>
1111

1212
EventFD::EventFD()
13-
:fd(::eventfd(0, EFD_NONBLOCK|EFD_CLOEXEC))
13+
:fd(AdoptTag{}, ::eventfd(0, EFD_NONBLOCK|EFD_CLOEXEC))
1414
{
1515
if (!fd.IsDefined())
1616
throw MakeErrno("eventfd() failed");

src/system/SignalFD.cxx

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ SignalFD::Create(const sigset_t &mask)
1717
throw MakeErrno("signalfd() failed");
1818

1919
if (!fd.IsDefined()) {
20-
fd = UniqueFileDescriptor{new_fd};
20+
fd = UniqueFileDescriptor{AdoptTag{}, new_fd};
2121
}
2222

2323
assert(new_fd == fd.Get());

0 commit comments

Comments
 (0)