diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index 477788931..fa77e577e 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -507,8 +507,8 @@ RENDERDOC_CreateReplayRenderer(const char *logfile, float *progress, ReplayRende extern "C" RENDERDOC_API RemoteAccess *RENDERDOC_CC RENDERDOC_CreateRemoteAccessConnection( const char *host, uint32_t ident, const char *clientName, bool32 forceConnection); -extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_EnumerateRemoteConnections(const char *host, - uint32_t *idents); +extern "C" RENDERDOC_API uint32_t RENDERDOC_CC +RENDERDOC_EnumerateRemoteConnections(const char *host, uint32_t nextIdent); extern "C" RENDERDOC_API ReplayCreateStatus RENDERDOC_CC RENDERDOC_CreateRemoteReplayConnection(const char *host, RemoteRenderer **rend); extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SpawnReplayHost(volatile bool32 *killReplay); diff --git a/renderdoc/replay/entry_points.cpp b/renderdoc/replay/entry_points.cpp index b61288765..e99b7a36b 100644 --- a/renderdoc/replay/entry_points.cpp +++ b/renderdoc/replay/entry_points.cpp @@ -420,32 +420,33 @@ extern "C" RENDERDOC_API void *RENDERDOC_CC RENDERDOC_AllocArrayMem(uint64_t sz) } extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_EnumerateRemoteConnections(const char *host, - uint32_t *idents) + uint32_t nextIdent) { - if(idents == NULL) - return RenderDoc_LastCaptureNetworkPort - RenderDoc_FirstCaptureNetworkPort + 1; - string s = "localhost"; if(host != NULL && host[0] != '\0') s = host; - uint32_t numIdents = 0; + // initial case is we're called with 0, start with the first port. + // otherwise we're called with the last successful ident, so increment + // before continuing to enumerate. + if(nextIdent == 0) + nextIdent = RenderDoc_FirstCaptureNetworkPort; + else + nextIdent++; - for(uint16_t ident = RenderDoc_FirstCaptureNetworkPort; ident <= RenderDoc_LastCaptureNetworkPort; - ident++) + for(; nextIdent <= RenderDoc_LastCaptureNetworkPort; nextIdent++) { - Network::Socket *sock = Network::CreateClientSocket(s.c_str(), ident, 250); + Network::Socket *sock = Network::CreateClientSocket(s.c_str(), (uint16_t)nextIdent, 250); if(sock) { - *idents = (uint32_t)ident; - idents++; - numIdents++; SAFE_DELETE(sock); + return nextIdent; } } - return numIdents; + // tried all idents remaining and found nothing + return ~0U; } extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SpawnReplayHost(volatile bool32 *killReplay) diff --git a/renderdocui/Interop/StaticExports.cs b/renderdocui/Interop/StaticExports.cs index 5304a5922..268423302 100644 --- a/renderdocui/Interop/StaticExports.cs +++ b/renderdocui/Interop/StaticExports.cs @@ -51,7 +51,7 @@ namespace renderdoc private static extern IntPtr RENDERDOC_CreateRemoteAccessConnection(IntPtr host, UInt32 ident, IntPtr clientName, bool forceConnection); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - private static extern UInt32 RENDERDOC_EnumerateRemoteConnections(IntPtr host, UInt32[] idents); + private static extern UInt32 RENDERDOC_EnumerateRemoteConnections(IntPtr host, UInt32 nextIdent); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] private static extern ReplayCreateStatus RENDERDOC_CreateRemoteReplayConnection(IntPtr host, ref IntPtr outrend); @@ -178,25 +178,28 @@ namespace renderdoc return new RemoteAccess(rendPtr); } - public static UInt32[] EnumerateRemoteConnections(string host) + public delegate void RemoteConnectionFound(UInt32 ident); + + public static void EnumerateRemoteConnections(string host, RemoteConnectionFound callback) { IntPtr host_mem = CustomMarshal.MakeUTF8String(host); - UInt32 numIdents = RENDERDOC_EnumerateRemoteConnections(host_mem, null); + UInt32 nextIdent = 0; - if (numIdents == 0) + while (true) { - CustomMarshal.Free(host_mem); - return null; + // just a sanity check to make sure we don't hit some unexpected case + UInt32 prevIdent = nextIdent; + + nextIdent = RENDERDOC_EnumerateRemoteConnections(host_mem, nextIdent); + + if (nextIdent == UInt32.MaxValue || prevIdent >= nextIdent) + break; + + callback(nextIdent); } - UInt32[] ret = new UInt32[numIdents]; - - RENDERDOC_EnumerateRemoteConnections(host_mem, ret); - CustomMarshal.Free(host_mem); - - return ret; } public static RemoteRenderer CreateRemoteReplayConnection(string host) diff --git a/renderdocui/Windows/Dialogs/RemoteHostSelect.cs b/renderdocui/Windows/Dialogs/RemoteHostSelect.cs index 758cb5370..404b34eef 100644 --- a/renderdocui/Windows/Dialogs/RemoteHostSelect.cs +++ b/renderdocui/Windows/Dialogs/RemoteHostSelect.cs @@ -96,18 +96,6 @@ namespace renderdocui.Windows.Dialogs th.Start(node); } - private class AvailableRemote - { - public AvailableRemote(string t, string a, string b) - { - Target = t; - API = a; - Busy = b; - } - - public string Target, API, Busy; - } - private static int lookupsInProgress = 0; private static Mutex lookupMutex = new Mutex(); @@ -131,31 +119,34 @@ namespace renderdocui.Windows.Dialogs string hostname = node["Hostname"] as string; - var idents = StaticExports.EnumerateRemoteConnections(hostname); - - var remotes = new Dictionary(); - string username = System.Security.Principal.WindowsIdentity.GetCurrent().Name; - foreach (var i in idents) - { - if (i != 0) + StaticExports.EnumerateRemoteConnections(hostname, (UInt32 i) => { + try { - try + var conn = StaticExports.CreateRemoteAccessConnection(hostname, i, username, false); + + if (node.OwnerView.Visible) { - var conn = StaticExports.CreateRemoteAccessConnection(hostname, i, username, false); + string target = conn.Target; + string api = conn.API; + string busy = conn.BusyClient; - var data = new AvailableRemote(conn.Target, conn.API, conn.BusyClient); - - conn.Shutdown(); - - remotes.Add(i, data); - } - catch (ApplicationException) - { + node.OwnerView.BeginInvoke((MethodInvoker)delegate + { + node.OwnerView.BeginUpdate(); + node.Nodes.Add(new TreelistView.Node(new object[] { target, api, busy })).Tag = new RemoteConnect(hostname, i); + node.OwnerView.EndUpdate(); + node.Expand(); + }); } + + conn.Shutdown(); } - } + catch (ApplicationException) + { + } + }); if (node.OwnerView.Visible) { @@ -164,11 +155,6 @@ namespace renderdocui.Windows.Dialogs node.OwnerView.BeginUpdate(); node.Italic = false; node.Image = null; - foreach (var kv in remotes) - { - node.Nodes.Add(new TreelistView.Node(new object[] { kv.Value.Target, kv.Value.API, kv.Value.Busy })).Tag = new RemoteConnect(hostname, kv.Key); - node.Bold = true; - } node.OwnerView.EndUpdate(); }); } diff --git a/renderdocui/Windows/Dialogs/UpdateDialog.cs b/renderdocui/Windows/Dialogs/UpdateDialog.cs index 1cff57240..f00d3404b 100644 --- a/renderdocui/Windows/Dialogs/UpdateDialog.cs +++ b/renderdocui/Windows/Dialogs/UpdateDialog.cs @@ -69,29 +69,25 @@ namespace renderdocui.Windows.Dialogs var updateThread = Helpers.NewThread(new ThreadStart(() => { - var idents = renderdoc.StaticExports.EnumerateRemoteConnections("localhost"); - string runningPrograms = ""; int running = 0; - foreach (var i in idents) + + renderdoc.StaticExports.EnumerateRemoteConnections("localhost", (UInt32 i) => { - if (i != 0) - { - running++; + running++; - var conn = renderdoc.StaticExports.CreateRemoteAccessConnection("localhost", i, "updater", false); + var conn = renderdoc.StaticExports.CreateRemoteAccessConnection("localhost", i, "updater", false); - if (runningPrograms != "") - runningPrograms += "\n"; + if (runningPrograms != "") + runningPrograms += "\n"; - if (conn.API != "") - runningPrograms += String.Format("{0} running {1}", conn.Target, conn.API); - else - runningPrograms += conn.Target; + if (conn.API != "") + runningPrograms += String.Format("{0} running {1}", conn.Target, conn.API); + else + runningPrograms += conn.Target; - conn.Shutdown(); - } - } + conn.Shutdown(); + }); if (running > 0) {