Author: flackr Date: Wed Mar 25 07:51:31 2015 New Revision: 233185 URL: http://llvm.org/viewvc/llvm-project?rev=233185&view=rev Log: Allow multiple simultaneous connections to platform.
Adds the --server argument to lldb-server platform which when specified will allow multiple simultaneous connections by forking off to handle each individual connection. This will allow us to run the remote tests in parallel. Test Plan: Run: lldb-server platform --listen *:1234 --server Connect from multiple lldb clients simultaneously. I will also test running the test suite remotely with multiple simultaneous jobs. Differential Revision: http://reviews.llvm.org/D8452 Modified: lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp lldb/trunk/tools/lldb-server/lldb-platform.cpp Modified: lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h?rev=233185&r1=233184&r2=233185&view=diff ============================================================================== --- lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h (original) +++ lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h Wed Mar 25 07:51:31 2015 @@ -38,6 +38,8 @@ class ConnectionFileDescriptor : public ConnectionFileDescriptor(int fd, bool owns_fd); + ConnectionFileDescriptor(Socket* socket); + virtual ~ConnectionFileDescriptor(); bool IsConnected() const override; @@ -104,6 +106,8 @@ class ConnectionFileDescriptor : public std::string m_uri; private: + void InitializeSocket(Socket* socket); + DISALLOW_COPY_AND_ASSIGN(ConnectionFileDescriptor); }; Modified: lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp?rev=233185&r1=233184&r2=233185&view=diff ============================================================================== --- lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp (original) +++ lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp Wed Mar 25 07:51:31 2015 @@ -81,6 +81,17 @@ ConnectionFileDescriptor::ConnectionFile OpenCommandPipe(); } +ConnectionFileDescriptor::ConnectionFileDescriptor(Socket* socket) + : Connection() + , m_pipe() + , m_mutex(Mutex::eMutexTypeRecursive) + , m_shutting_down(false) + , m_waiting_for_accept(false) + , m_child_processes_inherit(false) +{ + InitializeSocket(socket); +} + ConnectionFileDescriptor::~ConnectionFileDescriptor() { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT)); @@ -758,15 +769,7 @@ ConnectionFileDescriptor::SocketListenAn if (error.Fail()) return eConnectionStatusError; - m_write_sp.reset(socket); - m_read_sp = m_write_sp; - if (error.Fail()) - { - return eConnectionStatusError; - } - StreamString strm; - strm.Printf("connect://%s:%u",socket->GetRemoteIPAddress().c_str(), socket->GetRemotePortNumber()); - m_uri.swap(strm.GetString()); + InitializeSocket(socket); return eConnectionStatusSuccess; } @@ -831,3 +834,13 @@ ConnectionFileDescriptor::SetChildProces { m_child_processes_inherit = child_processes_inherit; } + +void +ConnectionFileDescriptor::InitializeSocket(Socket* socket) +{ + m_write_sp.reset(socket); + m_read_sp = m_write_sp; + StreamString strm; + strm.Printf("connect://%s:%u",socket->GetRemoteIPAddress().c_str(), socket->GetRemotePortNumber()); + m_uri.swap(strm.GetString()); +} Modified: lldb/trunk/tools/lldb-server/lldb-platform.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-server/lldb-platform.cpp?rev=233185&r1=233184&r2=233185&view=diff ============================================================================== --- lldb/trunk/tools/lldb-server/lldb-platform.cpp (original) +++ lldb/trunk/tools/lldb-server/lldb-platform.cpp Wed Mar 25 07:51:31 2015 @@ -19,6 +19,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/wait.h> // C++ Includes @@ -30,6 +31,7 @@ #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/HostGetOpt.h" #include "lldb/Host/OptionParser.h" +#include "lldb/Host/Socket.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h" @@ -44,19 +46,19 @@ using namespace lldb_private; static int g_debug = 0; static int g_verbose = 0; -static int g_stay_alive = 0; +static int g_server = 0; static struct option g_long_options[] = { { "debug", no_argument, &g_debug, 1 }, { "verbose", no_argument, &g_verbose, 1 }, - { "stay-alive", no_argument, &g_stay_alive, 1 }, { "listen", required_argument, NULL, 'L' }, { "port-offset", required_argument, NULL, 'p' }, { "gdbserver-port", required_argument, NULL, 'P' }, { "min-gdbserver-port", required_argument, NULL, 'm' }, { "max-gdbserver-port", required_argument, NULL, 'M' }, { "lldb-command", required_argument, NULL, 'c' }, + { "server", no_argument, &g_server, 1 }, { NULL, 0, NULL, 0 } }; @@ -125,6 +127,7 @@ main_platform (int argc, char *argv[]) std::vector<std::string> lldb_commands; bool show_usage = false; int option_error = 0; + int socket_error = -1; std::string short_options(OptionParser::GetShortOptionString(g_long_options)); @@ -246,6 +249,17 @@ main_platform (int argc, char *argv[]) puts(output); } + std::unique_ptr<Socket> listening_socket_up; + Socket *socket = nullptr; + printf ("Listening for a connection from %s...\n", listen_host_port.c_str()); + const bool children_inherit_listen_socket = false; + error = Socket::TcpListen(listen_host_port.c_str(), children_inherit_listen_socket, socket, NULL); + if (error.Fail()) + { + printf("error: %s\n", error.AsCString()); + exit(socket_error); + } + listening_socket_up.reset(socket); do { GDBRemoteCommunicationServerPlatform platform; @@ -258,51 +272,64 @@ main_platform (int argc, char *argv[]) platform.SetPortMap(std::move(gdbserver_portmap)); } - if (!listen_host_port.empty()) + const bool children_inherit_accept_socket = true; + socket = nullptr; + error = listening_socket_up->BlockingAccept(listen_host_port.c_str(), children_inherit_accept_socket, socket); + if (error.Fail()) + { + printf ("error: %s\n", error.AsCString()); + exit(socket_error); + } + printf ("Connection established.\n"); + if (g_server) { - std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor()); - if (conn_ap.get()) + // Collect child zombie processes. + while (waitpid(-1, nullptr, WNOHANG) > 0); + if (fork()) { - std::string connect_url ("listen://"); - connect_url.append(listen_host_port.c_str()); - - printf ("Listening for a connection from %s...\n", listen_host_port.c_str()); - if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess) - { - printf ("Connection established.\n"); - platform.SetConnection (conn_ap.release()); - } - else - { - printf ("error: %s\n", error.AsCString()); - } + // Parent will continue to listen for new connections. + continue; + } + else + { + // Child process will handle the connection and exit. + g_server = 0; + // Listening socket is owned by parent process. + listening_socket_up.release(); } + } + else + { + // If not running as a server, this process will not accept + // connections while a connection is active. + listening_socket_up.reset(); + } + platform.SetConnection (new ConnectionFileDescriptor(socket)); - if (platform.IsConnected()) + if (platform.IsConnected()) + { + // After we connected, we need to get an initial ack from... + if (platform.HandshakeWithClient(&error)) { - // After we connected, we need to get an initial ack from... - if (platform.HandshakeWithClient(&error)) + bool interrupt = false; + bool done = false; + while (!interrupt && !done) { - bool interrupt = false; - bool done = false; - while (!interrupt && !done) - { - if (platform.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done) != GDBRemoteCommunication::PacketResult::Success) - break; - } - - if (error.Fail()) - { - fprintf(stderr, "error: %s\n", error.AsCString()); - } + if (platform.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done) != GDBRemoteCommunication::PacketResult::Success) + break; } - else + + if (error.Fail()) { - fprintf(stderr, "error: handshake with client failed\n"); + fprintf(stderr, "error: %s\n", error.AsCString()); } } + else + { + fprintf(stderr, "error: handshake with client failed\n"); + } } - } while (g_stay_alive); + } while (g_server); fprintf(stderr, "lldb-server exiting...\n"); _______________________________________________ lldb-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
