Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
thaystg committed Jul 3, 2023
1 parent 2251e9f commit 30163db
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 60 deletions.
86 changes: 86 additions & 0 deletions src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -407,6 +408,7 @@ public ExecutionContext(MonoSDBHelper sdbAgent, int id, object auxData, PauseOnE
AuxData = auxData;
SdbAgent = sdbAgent;
PauseOnExceptions = pauseOnExceptions;
Destroyed = false;
}

public string DebugId { get; set; }
Expand Down Expand Up @@ -440,6 +442,8 @@ public ExecutionContext(MonoSDBHelper sdbAgent, int id, object auxData, PauseOnE
internal int TempBreakpointForSetNextIP { get; set; }
internal bool FirstBreakpoint { get; set; }

internal bool Destroyed { get; set; }

public DebugStore Store
{
get
Expand Down Expand Up @@ -486,4 +490,86 @@ public PerScopeCache()
{
}
}

internal sealed class ConcurrentExecutionContextDictionary
{
private ConcurrentDictionary<SessionId, ConcurrentBag<ExecutionContext>> contexts = new ();
public ExecutionContext GetCurrentContext(SessionId sessionId)
=> TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context)
? context
: throw new KeyNotFoundException($"No execution context found for session {sessionId}");

public bool TryGetCurrentExecutionContextValue(SessionId id, out ExecutionContext executionContext, bool ignoreDestroyedContext = true)
{
executionContext = null;
if (!contexts.TryGetValue(id, out ConcurrentBag<ExecutionContext> contextBag))
return false;
if (contextBag.IsEmpty)
return false;
IEnumerable<ExecutionContext> validContexts = null;
if (ignoreDestroyedContext)
validContexts = contextBag.Where(context => context.Destroyed == false);
else
validContexts = contextBag;
if (!validContexts.Any())
return false;
int maxId = validContexts.Max(context => context.Id);
executionContext = contextBag.FirstOrDefault(context => context.Id == maxId);
return executionContext != null;
}

public void OnDefaultContextUpdate(SessionId sessionId, ExecutionContext newContext)
{
if (TryGetAndAddContext(sessionId, newContext, out ExecutionContext previousContext))
{
foreach (KeyValuePair<string, BreakpointRequest> kvp in previousContext.BreakpointRequests)
{
newContext.BreakpointRequests[kvp.Key] = kvp.Value.Clone();
}
newContext.PauseOnExceptions = previousContext.PauseOnExceptions;
}
}

public bool TryGetAndAddContext(SessionId sessionId, ExecutionContext newExecutionContext, out ExecutionContext previousExecutionContext)
{
bool hasExisting = TryGetCurrentExecutionContextValue(sessionId, out previousExecutionContext, ignoreDestroyedContext: false);
ConcurrentBag<ExecutionContext> bag = contexts.GetOrAdd(sessionId, _ => new ConcurrentBag<ExecutionContext>());
bag.Add(newExecutionContext);
return hasExisting;
}

public void CreateWorkerExecutionContext(SessionId workerSessionId, SessionId originSessionId, ILogger logger)
{
if (!TryGetCurrentExecutionContextValue(originSessionId, out ExecutionContext context))
{
logger.LogDebug($"Origin sessionId does not exist - {originSessionId}");
return;
}
if (contexts.ContainsKey(workerSessionId))
{
logger.LogDebug($"Worker sessionId already exists - {originSessionId}");
return;
}
contexts[workerSessionId] = new();
contexts[workerSessionId].Add(context.CreateChildAsyncExecutionContext(workerSessionId));
}

public void DestroyContext(SessionId sessionId, int id)
{
if (!contexts.TryGetValue(sessionId, out ConcurrentBag<ExecutionContext> contextBag))
return;
foreach (ExecutionContext context in contextBag.Where(x => x.Id == id).ToList())
context.Destroyed = true;
}

public void ClearContexts(SessionId sessionId)
{
if (!contexts.TryGetValue(sessionId, out ConcurrentBag<ExecutionContext> contextBag))
return;
foreach (ExecutionContext context in contextBag)
context.Destroyed = true;
}

public bool ContainsKey(SessionId sessionId) => contexts.ContainsKey(sessionId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public FirefoxMonoProxy(ILogger logger, string loggerId = null, ProxyOptions opt

public FirefoxExecutionContext GetContextFixefox(SessionId sessionId)
{
if (contexts.TryGetValue(sessionId, out ExecutionContext context))
if (Contexts.TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
return context as FirefoxExecutionContext;
throw new ArgumentException($"Invalid Session: \"{sessionId}\"", nameof(sessionId));
}
Expand Down Expand Up @@ -254,7 +254,7 @@ protected override async Task<bool> AcceptEvent(SessionId sessionId, JObject arg
}
if (args["frame"] != null && args["type"] == null)
{
OnDefaultContextUpdate(sessionId, new FirefoxExecutionContext(new MonoSDBHelper (this, logger, sessionId), 0, args["frame"]["consoleActor"].Value<string>()));
Contexts.OnDefaultContextUpdate(sessionId, new FirefoxExecutionContext(new MonoSDBHelper (this, logger, sessionId), 0, args["frame"]["consoleActor"].Value<string>()));
return false;
}

Expand Down Expand Up @@ -317,7 +317,7 @@ await Task.WhenAll(
}
case "target-available-form":
{
OnDefaultContextUpdate(sessionId, new FirefoxExecutionContext(new MonoSDBHelper (this, logger, sessionId), 0, args["target"]["consoleActor"].Value<string>()));
Contexts.OnDefaultContextUpdate(sessionId, new FirefoxExecutionContext(new MonoSDBHelper (this, logger, sessionId), 0, args["target"]["consoleActor"].Value<string>()));
break;
}
}
Expand All @@ -334,7 +334,7 @@ protected override async Task<bool> AcceptCommand(MessageId sessionId, JObject a
{
case "resume":
{
if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
if (!Contexts.TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
return false;
context.PausedOnWasm = false;
if (context.CallStack == null)
Expand Down Expand Up @@ -396,7 +396,7 @@ protected override async Task<bool> AcceptCommand(MessageId sessionId, JObject a
}
case "setBreakpoint":
{
if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
if (!Contexts.TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
return false;
var req = JObject.FromObject(new
{
Expand Down Expand Up @@ -436,7 +436,7 @@ protected override async Task<bool> AcceptCommand(MessageId sessionId, JObject a
}
case "removeBreakpoint":
{
if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
if (!Contexts.TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
return false;
Result resp = await SendCommand(sessionId, "", args, token);

Expand Down
Loading

0 comments on commit 30163db

Please sign in to comment.