Skip to content

Commit 30163db

Browse files
authored
1 parent 2251e9f commit 30163db

File tree

3 files changed

+125
-60
lines changed

3 files changed

+125
-60
lines changed

src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Collections.Concurrent;
56
using System.Collections.Generic;
67
using System.IO;
78
using System.Linq;
@@ -407,6 +408,7 @@ public ExecutionContext(MonoSDBHelper sdbAgent, int id, object auxData, PauseOnE
407408
AuxData = auxData;
408409
SdbAgent = sdbAgent;
409410
PauseOnExceptions = pauseOnExceptions;
411+
Destroyed = false;
410412
}
411413

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

445+
internal bool Destroyed { get; set; }
446+
443447
public DebugStore Store
444448
{
445449
get
@@ -486,4 +490,86 @@ public PerScopeCache()
486490
{
487491
}
488492
}
493+
494+
internal sealed class ConcurrentExecutionContextDictionary
495+
{
496+
private ConcurrentDictionary<SessionId, ConcurrentBag<ExecutionContext>> contexts = new ();
497+
public ExecutionContext GetCurrentContext(SessionId sessionId)
498+
=> TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context)
499+
? context
500+
: throw new KeyNotFoundException($"No execution context found for session {sessionId}");
501+
502+
public bool TryGetCurrentExecutionContextValue(SessionId id, out ExecutionContext executionContext, bool ignoreDestroyedContext = true)
503+
{
504+
executionContext = null;
505+
if (!contexts.TryGetValue(id, out ConcurrentBag<ExecutionContext> contextBag))
506+
return false;
507+
if (contextBag.IsEmpty)
508+
return false;
509+
IEnumerable<ExecutionContext> validContexts = null;
510+
if (ignoreDestroyedContext)
511+
validContexts = contextBag.Where(context => context.Destroyed == false);
512+
else
513+
validContexts = contextBag;
514+
if (!validContexts.Any())
515+
return false;
516+
int maxId = validContexts.Max(context => context.Id);
517+
executionContext = contextBag.FirstOrDefault(context => context.Id == maxId);
518+
return executionContext != null;
519+
}
520+
521+
public void OnDefaultContextUpdate(SessionId sessionId, ExecutionContext newContext)
522+
{
523+
if (TryGetAndAddContext(sessionId, newContext, out ExecutionContext previousContext))
524+
{
525+
foreach (KeyValuePair<string, BreakpointRequest> kvp in previousContext.BreakpointRequests)
526+
{
527+
newContext.BreakpointRequests[kvp.Key] = kvp.Value.Clone();
528+
}
529+
newContext.PauseOnExceptions = previousContext.PauseOnExceptions;
530+
}
531+
}
532+
533+
public bool TryGetAndAddContext(SessionId sessionId, ExecutionContext newExecutionContext, out ExecutionContext previousExecutionContext)
534+
{
535+
bool hasExisting = TryGetCurrentExecutionContextValue(sessionId, out previousExecutionContext, ignoreDestroyedContext: false);
536+
ConcurrentBag<ExecutionContext> bag = contexts.GetOrAdd(sessionId, _ => new ConcurrentBag<ExecutionContext>());
537+
bag.Add(newExecutionContext);
538+
return hasExisting;
539+
}
540+
541+
public void CreateWorkerExecutionContext(SessionId workerSessionId, SessionId originSessionId, ILogger logger)
542+
{
543+
if (!TryGetCurrentExecutionContextValue(originSessionId, out ExecutionContext context))
544+
{
545+
logger.LogDebug($"Origin sessionId does not exist - {originSessionId}");
546+
return;
547+
}
548+
if (contexts.ContainsKey(workerSessionId))
549+
{
550+
logger.LogDebug($"Worker sessionId already exists - {originSessionId}");
551+
return;
552+
}
553+
contexts[workerSessionId] = new();
554+
contexts[workerSessionId].Add(context.CreateChildAsyncExecutionContext(workerSessionId));
555+
}
556+
557+
public void DestroyContext(SessionId sessionId, int id)
558+
{
559+
if (!contexts.TryGetValue(sessionId, out ConcurrentBag<ExecutionContext> contextBag))
560+
return;
561+
foreach (ExecutionContext context in contextBag.Where(x => x.Id == id).ToList())
562+
context.Destroyed = true;
563+
}
564+
565+
public void ClearContexts(SessionId sessionId)
566+
{
567+
if (!contexts.TryGetValue(sessionId, out ConcurrentBag<ExecutionContext> contextBag))
568+
return;
569+
foreach (ExecutionContext context in contextBag)
570+
context.Destroyed = true;
571+
}
572+
573+
public bool ContainsKey(SessionId sessionId) => contexts.ContainsKey(sessionId);
574+
}
489575
}

src/mono/wasm/debugger/BrowserDebugProxy/Firefox/FirefoxMonoProxy.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public FirefoxMonoProxy(ILogger logger, string loggerId = null, ProxyOptions opt
2323

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

@@ -317,7 +317,7 @@ await Task.WhenAll(
317317
}
318318
case "target-available-form":
319319
{
320-
OnDefaultContextUpdate(sessionId, new FirefoxExecutionContext(new MonoSDBHelper (this, logger, sessionId), 0, args["target"]["consoleActor"].Value<string>()));
320+
Contexts.OnDefaultContextUpdate(sessionId, new FirefoxExecutionContext(new MonoSDBHelper (this, logger, sessionId), 0, args["target"]["consoleActor"].Value<string>()));
321321
break;
322322
}
323323
}
@@ -334,7 +334,7 @@ protected override async Task<bool> AcceptCommand(MessageId sessionId, JObject a
334334
{
335335
case "resume":
336336
{
337-
if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
337+
if (!Contexts.TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
338338
return false;
339339
context.PausedOnWasm = false;
340340
if (context.CallStack == null)
@@ -396,7 +396,7 @@ protected override async Task<bool> AcceptCommand(MessageId sessionId, JObject a
396396
}
397397
case "setBreakpoint":
398398
{
399-
if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
399+
if (!Contexts.TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
400400
return false;
401401
var req = JObject.FromObject(new
402402
{
@@ -436,7 +436,7 @@ protected override async Task<bool> AcceptCommand(MessageId sessionId, JObject a
436436
}
437437
case "removeBreakpoint":
438438
{
439-
if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
439+
if (!Contexts.TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
440440
return false;
441441
Result resp = await SendCommand(sessionId, "", args, token);
442442

0 commit comments

Comments
 (0)