Skip to content

Commit 3376cbd

Browse files
authored
[browser][ws] fix race condition during message and close events (#118887)
- delay setting close to receive_status_ptr to not conflict with on-message event - fix status for wasm_ws_close_sent
1 parent 1765399 commit 3376cbd

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

src/mono/browser/runtime/web-socket.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import WasmEnableThreads from "consts:wasmEnableThreads";
55

66
import { prevent_timer_throttling } from "./scheduling";
77
import { Queue } from "./queue";
8-
import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, createPromiseController, loaderHelpers, mono_assert } from "./globals";
8+
import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, createPromiseController, loaderHelpers, mono_assert, Module } from "./globals";
99
import { setI32, localHeapViewU8, forceThreadMemoryViewRefresh } from "./memory";
1010
import { VoidPtr } from "./types/emscripten";
1111
import { PromiseController } from "./types/internal";
@@ -51,7 +51,7 @@ export function ws_get_state (ws: WebSocketExtension): number {
5151
const queued_events_count = receive_event_queue.getLength();
5252
if (queued_events_count == 0)
5353
return ws.readyState ?? -1;
54-
return WebSocket.OPEN;
54+
return ws[wasm_ws_close_sent] ? WebSocket.CLOSING : WebSocket.OPEN;
5555
}
5656

5757
export function ws_wasm_create (uri: string, sub_protocols: string[] | null, receive_status_ptr: VoidPtr): WebSocketExtension {
@@ -116,13 +116,15 @@ export function ws_wasm_create (uri: string, sub_protocols: string[] | null, rec
116116
}
117117

118118
// send close to any pending receivers, to wake them
119-
const receive_promise_queue = ws[wasm_ws_pending_receive_promise_queue];
120-
receive_promise_queue.drain((receive_promise_control) => {
121-
setI32(receive_status_ptr, 0); // count
122-
setI32(<any>receive_status_ptr + 4, 2); // type:close
123-
setI32(<any>receive_status_ptr + 8, 1);// end_of_message: true
124-
receive_promise_control.resolve();
125-
});
119+
Module.safeSetTimeout(() => {
120+
const receive_promise_queue = ws[wasm_ws_pending_receive_promise_queue];
121+
receive_promise_queue.drain((receive_promise_control) => {
122+
setI32(receive_status_ptr, 0); // count
123+
setI32(<any>receive_status_ptr + 4, 2); // type:close
124+
setI32(<any>receive_status_ptr + 8, 1);// end_of_message: true
125+
receive_promise_control.resolve();
126+
});
127+
}, 0);
126128
} catch (error: any) {
127129
mono_log_warn("failed to propagate WebSocket close event: " + error.toString());
128130
}

0 commit comments

Comments
 (0)