Skip to content

Commit ebbc9ed

Browse files
authored
[lldb] Add a MainLoop version of DomainSocket::Accept (#108188)
To go along with the existing TCPSocket implementation.
1 parent 6c0b1e7 commit ebbc9ed

File tree

9 files changed

+118
-41
lines changed

9 files changed

+118
-41
lines changed

lldb/include/lldb/Host/Socket.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <memory>
1313
#include <string>
1414

15+
#include "lldb/Host/MainLoopBase.h"
1516
#include "lldb/lldb-private.h"
1617

1718
#include "lldb/Host/SocketAddress.h"
@@ -97,7 +98,17 @@ class Socket : public IOObject {
9798

9899
virtual Status Connect(llvm::StringRef name) = 0;
99100
virtual Status Listen(llvm::StringRef name, int backlog) = 0;
100-
virtual Status Accept(Socket *&socket) = 0;
101+
102+
// Use the provided main loop instance to accept new connections. The callback
103+
// will be called (from MainLoop::Run) for each new connection. This function
104+
// does not block.
105+
virtual llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>>
106+
Accept(MainLoopBase &loop,
107+
std::function<void(std::unique_ptr<Socket> socket)> sock_cb) = 0;
108+
109+
// Accept a single connection and "return" it in the pointer argument. This
110+
// function blocks until the connection arrives.
111+
virtual Status Accept(Socket *&socket);
101112

102113
// Initialize a Tcp Socket object in listening mode. listen and accept are
103114
// implemented separately because the caller may wish to manipulate or query

lldb/include/lldb/Host/common/TCPSocket.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,10 @@ class TCPSocket : public Socket {
4242
Status Connect(llvm::StringRef name) override;
4343
Status Listen(llvm::StringRef name, int backlog) override;
4444

45-
// Use the provided main loop instance to accept new connections. The callback
46-
// will be called (from MainLoop::Run) for each new connection. This function
47-
// does not block.
45+
using Socket::Accept;
4846
llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>>
4947
Accept(MainLoopBase &loop,
50-
std::function<void(std::unique_ptr<TCPSocket> socket)> sock_cb);
51-
52-
// Accept a single connection and "return" it in the pointer argument. This
53-
// function blocks until the connection arrives.
54-
Status Accept(Socket *&conn_socket) override;
48+
std::function<void(std::unique_ptr<Socket> socket)> sock_cb) override;
5549

5650
Status CreateSocket(int domain);
5751

lldb/include/lldb/Host/common/UDPSocket.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,13 @@ class UDPSocket : public Socket {
2727
size_t Send(const void *buf, const size_t num_bytes) override;
2828
Status Connect(llvm::StringRef name) override;
2929
Status Listen(llvm::StringRef name, int backlog) override;
30-
Status Accept(Socket *&socket) override;
30+
31+
llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>>
32+
Accept(MainLoopBase &loop,
33+
std::function<void(std::unique_ptr<Socket> socket)> sock_cb) override {
34+
return llvm::errorCodeToError(
35+
std::make_error_code(std::errc::operation_not_supported));
36+
}
3137

3238
SocketAddress m_sockaddr;
3339
};

lldb/include/lldb/Host/posix/DomainSocket.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,17 @@
1414
namespace lldb_private {
1515
class DomainSocket : public Socket {
1616
public:
17+
DomainSocket(NativeSocket socket, bool should_close,
18+
bool child_processes_inherit);
1719
DomainSocket(bool should_close, bool child_processes_inherit);
1820

1921
Status Connect(llvm::StringRef name) override;
2022
Status Listen(llvm::StringRef name, int backlog) override;
21-
Status Accept(Socket *&socket) override;
23+
24+
using Socket::Accept;
25+
llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>>
26+
Accept(MainLoopBase &loop,
27+
std::function<void(std::unique_ptr<Socket> socket)> sock_cb) override;
2228

2329
std::string GetRemoteConnectionURI() const override;
2430

lldb/source/Host/common/Socket.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "lldb/Host/Config.h"
1212
#include "lldb/Host/Host.h"
13+
#include "lldb/Host/MainLoop.h"
1314
#include "lldb/Host/SocketAddress.h"
1415
#include "lldb/Host/common/TCPSocket.h"
1516
#include "lldb/Host/common/UDPSocket.h"
@@ -459,6 +460,19 @@ NativeSocket Socket::CreateSocket(const int domain, const int type,
459460
return sock;
460461
}
461462

463+
Status Socket::Accept(Socket *&socket) {
464+
MainLoop accept_loop;
465+
llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>> expected_handles =
466+
Accept(accept_loop,
467+
[&accept_loop, &socket](std::unique_ptr<Socket> sock) {
468+
socket = sock.release();
469+
accept_loop.RequestTermination();
470+
});
471+
if (!expected_handles)
472+
return Status::FromError(expected_handles.takeError());
473+
return accept_loop.Run();
474+
}
475+
462476
NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr,
463477
socklen_t *addrlen,
464478
bool child_processes_inherit, Status &error) {

lldb/source/Host/common/TCPSocket.cpp

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,9 @@ void TCPSocket::CloseListenSockets() {
232232
m_listen_sockets.clear();
233233
}
234234

235-
llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>> TCPSocket::Accept(
236-
MainLoopBase &loop,
237-
std::function<void(std::unique_ptr<TCPSocket> socket)> sock_cb) {
235+
llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>>
236+
TCPSocket::Accept(MainLoopBase &loop,
237+
std::function<void(std::unique_ptr<Socket> socket)> sock_cb) {
238238
if (m_listen_sockets.size() == 0)
239239
return llvm::createStringError("No open listening sockets!");
240240

@@ -278,19 +278,6 @@ llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>> TCPSocket::Accept(
278278
return handles;
279279
}
280280

281-
Status TCPSocket::Accept(Socket *&conn_socket) {
282-
MainLoop accept_loop;
283-
llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>> expected_handles =
284-
Accept(accept_loop,
285-
[&accept_loop, &conn_socket](std::unique_ptr<TCPSocket> sock) {
286-
conn_socket = sock.release();
287-
accept_loop.RequestTermination();
288-
});
289-
if (!expected_handles)
290-
return Status::FromError(expected_handles.takeError());
291-
return accept_loop.Run();
292-
}
293-
294281
int TCPSocket::SetOptionNoDelay() {
295282
return SetOption(IPPROTO_TCP, TCP_NODELAY, 1);
296283
}

lldb/source/Host/common/UDPSocket.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,6 @@ Status UDPSocket::Listen(llvm::StringRef name, int backlog) {
4747
return Status::FromErrorStringWithFormat("%s", g_not_supported_error);
4848
}
4949

50-
Status UDPSocket::Accept(Socket *&socket) {
51-
return Status::FromErrorStringWithFormat("%s", g_not_supported_error);
52-
}
53-
5450
llvm::Expected<std::unique_ptr<UDPSocket>>
5551
UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit) {
5652
std::unique_ptr<UDPSocket> socket;

lldb/source/Host/posix/DomainSocket.cpp

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "lldb/Host/posix/DomainSocket.h"
10+
#include "lldb/Utility/LLDBLog.h"
1011

1112
#include "llvm/Support/Errno.h"
1213
#include "llvm/Support/FileSystem.h"
1314

1415
#include <cstddef>
16+
#include <memory>
1517
#include <sys/socket.h>
1618
#include <sys/un.h>
1719

@@ -57,7 +59,14 @@ static bool SetSockAddr(llvm::StringRef name, const size_t name_offset,
5759
}
5860

5961
DomainSocket::DomainSocket(bool should_close, bool child_processes_inherit)
60-
: Socket(ProtocolUnixDomain, should_close, child_processes_inherit) {}
62+
: DomainSocket(kInvalidSocketValue, should_close, child_processes_inherit) {
63+
}
64+
65+
DomainSocket::DomainSocket(NativeSocket socket, bool should_close,
66+
bool child_processes_inherit)
67+
: Socket(ProtocolUnixDomain, should_close, child_processes_inherit) {
68+
m_socket = socket;
69+
}
6170

6271
DomainSocket::DomainSocket(SocketProtocol protocol,
6372
bool child_processes_inherit)
@@ -108,14 +117,31 @@ Status DomainSocket::Listen(llvm::StringRef name, int backlog) {
108117
return error;
109118
}
110119

111-
Status DomainSocket::Accept(Socket *&socket) {
112-
Status error;
113-
auto conn_fd = AcceptSocket(GetNativeSocket(), nullptr, nullptr,
114-
m_child_processes_inherit, error);
115-
if (error.Success())
116-
socket = new DomainSocket(conn_fd, *this);
120+
llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>> DomainSocket::Accept(
121+
MainLoopBase &loop,
122+
std::function<void(std::unique_ptr<Socket> socket)> sock_cb) {
123+
// TODO: Refactor MainLoop to avoid the shared_ptr requirement.
124+
auto io_sp = std::make_shared<DomainSocket>(GetNativeSocket(), false,
125+
m_child_processes_inherit);
126+
auto cb = [this, sock_cb](MainLoopBase &loop) {
127+
Log *log = GetLog(LLDBLog::Host);
128+
Status error;
129+
auto conn_fd = AcceptSocket(GetNativeSocket(), nullptr, nullptr,
130+
m_child_processes_inherit, error);
131+
if (error.Fail()) {
132+
LLDB_LOG(log, "AcceptSocket({0}): {1}", GetNativeSocket(), error);
133+
return;
134+
}
135+
std::unique_ptr<DomainSocket> sock_up(new DomainSocket(conn_fd, *this));
136+
sock_cb(std::move(sock_up));
137+
};
117138

118-
return error;
139+
Status error;
140+
std::vector<MainLoopBase::ReadHandleUP> handles;
141+
handles.emplace_back(loop.RegisterReadObject(io_sp, cb, error));
142+
if (error.Fail())
143+
return error.ToError();
144+
return handles;
119145
}
120146

121147
size_t DomainSocket::GetNameOffset() const { return 0; }

lldb/unittests/Host/SocketTest.cpp

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,43 @@ TEST_P(SocketTest, DomainListenConnectAccept) {
8585
std::unique_ptr<DomainSocket> socket_b_up;
8686
CreateDomainConnectedSockets(Path, &socket_a_up, &socket_b_up);
8787
}
88+
89+
TEST_P(SocketTest, DomainMainLoopAccept) {
90+
llvm::SmallString<64> Path;
91+
std::error_code EC =
92+
llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", Path);
93+
ASSERT_FALSE(EC);
94+
llvm::sys::path::append(Path, "test");
95+
96+
// Skip the test if the $TMPDIR is too long to hold a domain socket.
97+
if (Path.size() > 107u)
98+
return;
99+
100+
auto listen_socket_up = std::make_unique<DomainSocket>(
101+
/*should_close=*/true, /*child_process_inherit=*/false);
102+
Status error = listen_socket_up->Listen(Path, 5);
103+
ASSERT_THAT_ERROR(error.ToError(), llvm::Succeeded());
104+
ASSERT_TRUE(listen_socket_up->IsValid());
105+
106+
MainLoop loop;
107+
std::unique_ptr<Socket> accepted_socket_up;
108+
auto expected_handles = listen_socket_up->Accept(
109+
loop, [&accepted_socket_up, &loop](std::unique_ptr<Socket> sock_up) {
110+
accepted_socket_up = std::move(sock_up);
111+
loop.RequestTermination();
112+
});
113+
ASSERT_THAT_EXPECTED(expected_handles, llvm::Succeeded());
114+
115+
auto connect_socket_up = std::make_unique<DomainSocket>(
116+
/*should_close=*/true, /*child_process_inherit=*/false);
117+
ASSERT_THAT_ERROR(connect_socket_up->Connect(Path).ToError(),
118+
llvm::Succeeded());
119+
ASSERT_TRUE(connect_socket_up->IsValid());
120+
121+
loop.Run();
122+
ASSERT_TRUE(accepted_socket_up);
123+
ASSERT_TRUE(accepted_socket_up->IsValid());
124+
}
88125
#endif
89126

90127
TEST_P(SocketTest, TCPListen0ConnectAccept) {
@@ -109,9 +146,9 @@ TEST_P(SocketTest, TCPMainLoopAccept) {
109146
ASSERT_TRUE(listen_socket_up->IsValid());
110147

111148
MainLoop loop;
112-
std::unique_ptr<TCPSocket> accepted_socket_up;
149+
std::unique_ptr<Socket> accepted_socket_up;
113150
auto expected_handles = listen_socket_up->Accept(
114-
loop, [&accepted_socket_up, &loop](std::unique_ptr<TCPSocket> sock_up) {
151+
loop, [&accepted_socket_up, &loop](std::unique_ptr<Socket> sock_up) {
115152
accepted_socket_up = std::move(sock_up);
116153
loop.RequestTermination();
117154
});

0 commit comments

Comments
 (0)