Skip to content

Commit 0ff2b32

Browse files
labathJDevlieghere
authored andcommitted
[lldb] Add a MainLoop version of DomainSocket::Accept (llvm#108188)
To go along with the existing TCPSocket implementation. (cherry picked from commit ebbc9ed)
1 parent e156778 commit 0ff2b32

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
@@ -13,6 +13,7 @@
1313
#include <string>
1414
#include <vector>
1515

16+
#include "lldb/Host/MainLoopBase.h"
1617
#include "lldb/lldb-private.h"
1718

1819
#include "lldb/Host/SocketAddress.h"
@@ -98,7 +99,17 @@ class Socket : public IOObject {
9899

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

103114
// Initialize a Tcp Socket object in listening mode. listen and accept are
104115
// 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
@@ -44,16 +44,10 @@ class TCPSocket : public Socket {
4444
Status Connect(llvm::StringRef name) override;
4545
Status Listen(llvm::StringRef name, int backlog) override;
4646

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

5852
Status CreateSocket(int domain);
5953

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
@@ -16,11 +16,17 @@
1616
namespace lldb_private {
1717
class DomainSocket : public Socket {
1818
public:
19+
DomainSocket(NativeSocket socket, bool should_close,
20+
bool child_processes_inherit);
1921
DomainSocket(bool should_close, bool child_processes_inherit);
2022

2123
Status Connect(llvm::StringRef name) override;
2224
Status Listen(llvm::StringRef name, int backlog) override;
23-
Status Accept(Socket *&socket) override;
25+
26+
using Socket::Accept;
27+
llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>>
28+
Accept(MainLoopBase &loop,
29+
std::function<void(std::unique_ptr<Socket> socket)> sock_cb) override;
2430

2531
std::string GetRemoteConnectionURI() const override;
2632

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"
@@ -443,6 +444,19 @@ NativeSocket Socket::CreateSocket(const int domain, const int type,
443444
return sock;
444445
}
445446

447+
Status Socket::Accept(Socket *&socket) {
448+
MainLoop accept_loop;
449+
llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>> expected_handles =
450+
Accept(accept_loop,
451+
[&accept_loop, &socket](std::unique_ptr<Socket> sock) {
452+
socket = sock.release();
453+
accept_loop.RequestTermination();
454+
});
455+
if (!expected_handles)
456+
return Status::FromError(expected_handles.takeError());
457+
return accept_loop.Run();
458+
}
459+
446460
NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr,
447461
socklen_t *addrlen,
448462
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
@@ -263,9 +263,9 @@ void TCPSocket::CloseListenSockets() {
263263
m_listen_sockets.clear();
264264
}
265265

266-
llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>> TCPSocket::Accept(
267-
MainLoopBase &loop,
268-
std::function<void(std::unique_ptr<TCPSocket> socket)> sock_cb) {
266+
llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>>
267+
TCPSocket::Accept(MainLoopBase &loop,
268+
std::function<void(std::unique_ptr<Socket> socket)> sock_cb) {
269269
if (m_listen_sockets.size() == 0)
270270
return llvm::createStringError("No open listening sockets!");
271271

@@ -309,19 +309,6 @@ llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>> TCPSocket::Accept(
309309
return handles;
310310
}
311311

312-
Status TCPSocket::Accept(Socket *&conn_socket) {
313-
MainLoop accept_loop;
314-
llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>> expected_handles =
315-
Accept(accept_loop,
316-
[&accept_loop, &conn_socket](std::unique_ptr<TCPSocket> sock) {
317-
conn_socket = sock.release();
318-
accept_loop.RequestTermination();
319-
});
320-
if (!expected_handles)
321-
return Status::FromError(expected_handles.takeError());
322-
return accept_loop.Run();
323-
}
324-
325312
int TCPSocket::SetOptionNoDelay() {
326313
return SetOption(IPPROTO_TCP, TCP_NODELAY, 1);
327314
}

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)