[Lldb-commits] [lldb] r233185 - Allow multiple simultaneous connections to platform.

Robert Flack flackr at gmail.com
Wed Mar 25 05:51:32 PDT 2015


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");
 





More information about the lldb-commits mailing list