|
19 | 19 |
|
20 | 20 | #include "llvm/Config/llvm-config.h"
|
21 | 21 | #include "llvm/Support/Errno.h"
|
| 22 | +#include "llvm/Support/Error.h" |
22 | 23 | #include "llvm/Support/WindowsError.h"
|
23 | 24 | #include "llvm/Support/raw_ostream.h"
|
24 | 25 |
|
@@ -254,67 +255,63 @@ void TCPSocket::CloseListenSockets() {
|
254 | 255 | m_listen_sockets.clear();
|
255 | 256 | }
|
256 | 257 |
|
257 |
| -Status TCPSocket::Accept(Socket *&conn_socket) { |
258 |
| - Status error; |
259 |
| - if (m_listen_sockets.size() == 0) { |
260 |
| - error = Status::FromErrorString("No open listening sockets!"); |
261 |
| - return error; |
262 |
| - } |
| 258 | +llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>> TCPSocket::Accept( |
| 259 | + MainLoopBase &loop, |
| 260 | + std::function<void(std::unique_ptr<TCPSocket> socket)> sock_cb) { |
| 261 | + if (m_listen_sockets.size() == 0) |
| 262 | + return llvm::createStringError("No open listening sockets!"); |
263 | 263 |
|
264 |
| - NativeSocket sock = kInvalidSocketValue; |
265 |
| - NativeSocket listen_sock = kInvalidSocketValue; |
266 |
| - lldb_private::SocketAddress AcceptAddr; |
267 |
| - MainLoop accept_loop; |
268 | 264 | std::vector<MainLoopBase::ReadHandleUP> handles;
|
269 | 265 | for (auto socket : m_listen_sockets) {
|
270 | 266 | auto fd = socket.first;
|
271 |
| - auto inherit = this->m_child_processes_inherit; |
272 |
| - auto io_sp = IOObjectSP(new TCPSocket(socket.first, false, inherit)); |
273 |
| - handles.emplace_back(accept_loop.RegisterReadObject( |
274 |
| - io_sp, [fd, inherit, &sock, &AcceptAddr, &error, |
275 |
| - &listen_sock](MainLoopBase &loop) { |
276 |
| - socklen_t sa_len = AcceptAddr.GetMaxLength(); |
277 |
| - sock = AcceptSocket(fd, &AcceptAddr.sockaddr(), &sa_len, inherit, |
278 |
| - error); |
279 |
| - listen_sock = fd; |
280 |
| - loop.RequestTermination(); |
281 |
| - }, error)); |
282 |
| - if (error.Fail()) |
283 |
| - return error; |
284 |
| - } |
285 |
| - |
286 |
| - bool accept_connection = false; |
287 |
| - std::unique_ptr<TCPSocket> accepted_socket; |
288 |
| - // Loop until we are happy with our connection |
289 |
| - while (!accept_connection) { |
290 |
| - accept_loop.Run(); |
291 |
| - |
292 |
| - if (error.Fail()) |
293 |
| - return error; |
| 267 | + auto io_sp = |
| 268 | + std::make_shared<TCPSocket>(fd, false, this->m_child_processes_inherit); |
| 269 | + auto cb = [this, fd, sock_cb](MainLoopBase &loop) { |
| 270 | + lldb_private::SocketAddress AcceptAddr; |
| 271 | + socklen_t sa_len = AcceptAddr.GetMaxLength(); |
| 272 | + Status error; |
| 273 | + NativeSocket sock = AcceptSocket(fd, &AcceptAddr.sockaddr(), &sa_len, |
| 274 | + m_child_processes_inherit, error); |
| 275 | + Log *log = GetLog(LLDBLog::Host); |
| 276 | + if (error.Fail()) { |
| 277 | + LLDB_LOG(log, "AcceptSocket({0}): {1}", fd, error); |
| 278 | + return; |
| 279 | + } |
294 | 280 |
|
295 |
| - lldb_private::SocketAddress &AddrIn = m_listen_sockets[listen_sock]; |
296 |
| - if (!AddrIn.IsAnyAddr() && AcceptAddr != AddrIn) { |
297 |
| - if (sock != kInvalidSocketValue) { |
| 281 | + const lldb_private::SocketAddress &AddrIn = m_listen_sockets[fd]; |
| 282 | + if (!AddrIn.IsAnyAddr() && AcceptAddr != AddrIn) { |
298 | 283 | CLOSE_SOCKET(sock);
|
299 |
| - sock = kInvalidSocketValue; |
| 284 | + LLDB_LOG(log, "rejecting incoming connection from {0} (expecting {1})", |
| 285 | + AcceptAddr.GetIPAddress(), AddrIn.GetIPAddress()); |
| 286 | + return; |
300 | 287 | }
|
301 |
| - llvm::errs() << llvm::formatv( |
302 |
| - "error: rejecting incoming connection from {0} (expecting {1})", |
303 |
| - AcceptAddr.GetIPAddress(), AddrIn.GetIPAddress()); |
304 |
| - continue; |
305 |
| - } |
306 |
| - accept_connection = true; |
307 |
| - accepted_socket.reset(new TCPSocket(sock, *this)); |
| 288 | + std::unique_ptr<TCPSocket> sock_up(new TCPSocket(sock, *this)); |
| 289 | + |
| 290 | + // Keep our TCP packets coming without any delays. |
| 291 | + sock_up->SetOptionNoDelay(); |
| 292 | + |
| 293 | + sock_cb(std::move(sock_up)); |
| 294 | + }; |
| 295 | + Status error; |
| 296 | + handles.emplace_back(loop.RegisterReadObject(io_sp, cb, error)); |
| 297 | + if (error.Fail()) |
| 298 | + return error.ToError(); |
308 | 299 | }
|
309 | 300 |
|
310 |
| - if (!accepted_socket) |
311 |
| - return error; |
| 301 | + return handles; |
| 302 | +} |
312 | 303 |
|
313 |
| - // Keep our TCP packets coming without any delays. |
314 |
| - accepted_socket->SetOptionNoDelay(); |
315 |
| - error.Clear(); |
316 |
| - conn_socket = accepted_socket.release(); |
317 |
| - return error; |
| 304 | +Status TCPSocket::Accept(Socket *&conn_socket) { |
| 305 | + MainLoop accept_loop; |
| 306 | + llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>> expected_handles = |
| 307 | + Accept(accept_loop, |
| 308 | + [&accept_loop, &conn_socket](std::unique_ptr<TCPSocket> sock) { |
| 309 | + conn_socket = sock.release(); |
| 310 | + accept_loop.RequestTermination(); |
| 311 | + }); |
| 312 | + if (!expected_handles) |
| 313 | + return Status(expected_handles.takeError()); |
| 314 | + return accept_loop.Run(); |
318 | 315 | }
|
319 | 316 |
|
320 | 317 | int TCPSocket::SetOptionNoDelay() {
|
|
0 commit comments