Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/sdks
diff options
context:
space:
mode:
authorKenneth Pouncey <kjpou@pt.lu>2019-12-11 08:37:19 +0300
committerGitHub <noreply@github.com>2019-12-11 08:37:19 +0300
commitd6d74e819f296196ba30421053fda6bf5a098eb6 (patch)
tree1cfacc3134a7424c2f00d971ed0edaf346319691 /sdks
parenta65b7af6d5abf00d7be1f0e85c219657686e33c3 (diff)
[wasm][debugger] Prevent crash on disconnect of client (#18107)
Diffstat (limited to 'sdks')
-rw-r--r--sdks/wasm/Mono.WebAssembly.DebuggerProxy/WsProxy.cs48
1 files changed, 34 insertions, 14 deletions
diff --git a/sdks/wasm/Mono.WebAssembly.DebuggerProxy/WsProxy.cs b/sdks/wasm/Mono.WebAssembly.DebuggerProxy/WsProxy.cs
index 3dc71059f5d..3d90be7b03b 100644
--- a/sdks/wasm/Mono.WebAssembly.DebuggerProxy/WsProxy.cs
+++ b/sdks/wasm/Mono.WebAssembly.DebuggerProxy/WsProxy.cs
@@ -97,6 +97,7 @@ namespace WsProxy {
public class WsProxy {
TaskCompletionSource<bool> side_exception = new TaskCompletionSource<bool> ();
+ TaskCompletionSource<bool> client_initiated_close = new TaskCompletionSource<bool> ();
List<(int, TaskCompletionSource<Result>)> pending_cmds = new List<(int, TaskCompletionSource<Result>)> ();
ClientWebSocket browser;
WebSocket ide;
@@ -119,8 +120,16 @@ namespace WsProxy {
byte [] buff = new byte [4000];
var mem = new MemoryStream ();
while (true) {
+
+ if (socket.State != WebSocketState.Open) {
+ Console.WriteLine ($"WSProxy: Socket is no longer open.");
+ client_initiated_close.TrySetResult (true);
+ return null;
+ }
+
var result = await socket.ReceiveAsync (new ArraySegment<byte> (buff), token);
if (result.MessageType == WebSocketMessageType.Close) {
+ client_initiated_close.TrySetResult (true);
return null;
}
@@ -199,9 +208,10 @@ namespace WsProxy {
void ProcessIdeMessage (string msg, CancellationToken token)
{
- var res = JObject.Parse (msg);
-
- pending_ops.Add (OnCommand (res ["id"].Value<int> (), res ["method"].Value<string> (), res ["params"] as JObject, token));
+ if (!string.IsNullOrEmpty (msg)) {
+ var res = JObject.Parse (msg);
+ pending_ops.Add (OnCommand (res ["id"].Value<int> (), res ["method"].Value<string> (), res ["params"] as JObject, token));
+ }
}
internal async Task<Result> SendCommand (string method, JObject args, CancellationToken token) {
@@ -255,24 +265,25 @@ namespace WsProxy {
Send (this.ide, o, token);
}
- // , HttpContext context)
- public async Task Run (Uri browserUri, WebSocket ideSocket)
+ // , HttpContext context)
+ public async Task Run (Uri browserUri, WebSocket ideSocket)
{
- Debug ("wsproxy start");
+ Debug ($"WsProxy Starting on {browserUri}");
using (this.ide = ideSocket) {
- Debug ("ide connected");
+ Debug ($"WsProxy: IDE waiting for connection on {browserUri}");
queues.Add (new WsQueue (this.ide));
using (this.browser = new ClientWebSocket ()) {
this.browser.Options.KeepAliveInterval = Timeout.InfiniteTimeSpan;
await this.browser.ConnectAsync (browserUri, CancellationToken.None);
queues.Add (new WsQueue (this.browser));
- Debug ("client connected");
+ Debug ($"WsProxy: Client connected on {browserUri}");
var x = new CancellationTokenSource ();
pending_ops.Add (ReadOne (browser, x.Token));
pending_ops.Add (ReadOne (ide, x.Token));
pending_ops.Add (side_exception.Task);
+ pending_ops.Add (client_initiated_close.Task);
try {
while (!x.IsCancellationRequested) {
@@ -280,15 +291,23 @@ namespace WsProxy {
//Console.WriteLine ("pump {0} {1}", task, pending_ops.IndexOf (task));
if (task == pending_ops [0]) {
var msg = ((Task<string>)task).Result;
- pending_ops [0] = ReadOne (browser, x.Token); //queue next read
- ProcessBrowserMessage (msg, x.Token);
+ if (msg != null) {
+ pending_ops [0] = ReadOne (browser, x.Token); //queue next read
+ ProcessBrowserMessage (msg, x.Token);
+ }
} else if (task == pending_ops [1]) {
var msg = ((Task<string>)task).Result;
- pending_ops [1] = ReadOne (ide, x.Token); //queue next read
- ProcessIdeMessage (msg, x.Token);
+ if (msg != null) {
+ pending_ops [1] = ReadOne (ide, x.Token); //queue next read
+ ProcessIdeMessage (msg, x.Token);
+ }
} else if (task == pending_ops [2]) {
var res = ((Task<bool>)task).Result;
throw new Exception ("side task must always complete with an exception, what's going on???");
+ } else if (task == pending_ops [3]) {
+ var res = ((Task<bool>)task).Result;
+ Debug ($"WsProxy: Client initiated close from {browserUri}");
+ x.Cancel ();
} else {
//must be a background task
pending_ops.Remove (task);
@@ -301,10 +320,11 @@ namespace WsProxy {
}
}
} catch (Exception e) {
- Debug ($"got exception {e}");
+ Debug ($"WsProxy::Run: Exception {e}");
//throw;
} finally {
- x.Cancel ();
+ if (!x.IsCancellationRequested)
+ x.Cancel ();
}
}
}