Greatly speed up 'attach to running instance' dialog in the 99% case

* 99% of the time, you'll only have localhost and the application will
  be running on the first ident checked which will return a valid socket
  almost immediately.
* Instead of continuing to search through each valid port before
  returning valid data, we change the enumerate function to just find
  the next valid port and return - so we can update the UI as soon as
  we have the first result.
This commit is contained in:
baldurk
2016-06-01 11:31:57 +02:00
parent 4b149abdbd
commit 094e79dee2
5 changed files with 63 additions and 77 deletions
+2 -2
View File
@@ -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);
+13 -12
View File
@@ -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)
+15 -12
View File
@@ -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)
+21 -35
View File
@@ -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<UInt32, AvailableRemote>();
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();
});
}
+12 -16
View File
@@ -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)
{