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
+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)
{