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