diff --git a/src/lib/libcore.js b/src/lib/libcore.js index 64d153ebbd826..41ffb2a36e24a 100644 --- a/src/lib/libcore.js +++ b/src/lib/libcore.js @@ -2264,6 +2264,15 @@ addToLibrary({ this.allocated[id] = undefined; this.freelist.push(id); } + list() { + var valid_ids = []; + for (var i = 1; i < this.allocated.length; i++) { + if (this.allocated[i] !== undefined) { + valid_ids.push(i); + } + } + return valid_ids; + } }, $wasmTable__docs: '/** @type {WebAssembly.Table} */', diff --git a/src/lib/libwebsocket.js b/src/lib/libwebsocket.js index 3735d78e8a8d9..793c034d1cbe0 100644 --- a/src/lib/libwebsocket.js +++ b/src/lib/libwebsocket.js @@ -409,21 +409,17 @@ var LibraryWebSocket = { emscripten_websocket_is_supported__proxy: 'sync', emscripten_websocket_is_supported: () => typeof WebSocket != 'undefined', - emscripten_websocket_deinitialize__deps: ['$WS'], + emscripten_websocket_deinitialize__deps: ['$webSockets', 'emscripten_websocket_delete'], emscripten_websocket_deinitialize__proxy: 'sync', - emscripten_websocket_deinitialize__deps: ['emscripten_websocket_delete'], emscripten_websocket_deinitialize: () => { #if WEBSOCKET_DEBUG dbg('emscripten_websocket_deinitialize()'); #endif - for (var i in WS.sockets) { - var socket = WS.sockets[i]; - if (socket) { - socket.close(); - _emscripten_websocket_delete(i); - } + for (let id of webSockets.list()) { + let socket = webSockets.get(id); + socket.close(); + _emscripten_websocket_delete(id); } - WS.sockets = []; } } diff --git a/test/test_sockets.py b/test/test_sockets.py index 1a21d5866bdca..0e94c67124bda 100644 --- a/test/test_sockets.py +++ b/test/test_sockets.py @@ -388,6 +388,7 @@ def test_nodejs_sockets_echo_subprotocol_runtime(self): @parameterized({ '': [[]], 'shared': [['-sSHARED_MEMORY']], + 'deinitialize': [['-DTEST_EMSCRIPTEN_WEBSOCKET_DEINITIALIZE']], }) @requires_dev_dependency('ws') def test_websocket_send(self, args): diff --git a/test/websocket/test_websocket_send.c b/test/websocket/test_websocket_send.c index a3a01c1d3b695..260f796a6dec6 100644 --- a/test/websocket/test_websocket_send.c +++ b/test/websocket/test_websocket_send.c @@ -3,8 +3,11 @@ #include #include -// This test performs that same server communications using two different +// This test performs the same server communications using two different // sockets. This verifies that multiple sockets are supported simultaneously. +// Depending on whether TEST_EMSCRIPTEN_WEBSOCKET_DEINITIALIZE is defined, +// cleanup is either performed using emscripten_websocket_deinitialize() or +// emscripten_websocket_close() and emscripten_websocket_delete(). EMSCRIPTEN_WEBSOCKET_T sock1; EMSCRIPTEN_WEBSOCKET_T sock2; @@ -44,6 +47,7 @@ bool WebSocketError(int eventType, const EmscriptenWebSocketErrorEvent *e, void bool WebSocketMessage(int eventType, const EmscriptenWebSocketMessageEvent *e, void *userData) { printf("message(socket=%d, eventType=%d, userData=%p data=%p, numBytes=%d, isText=%d)\n", e->socket, eventType, userData, e->data, e->numBytes, e->isText); static int text_received = 0; + static int binary_received = 0; assert(e->socket == sock1 || e->socket == sock2); if (e->isText) { printf("text data: \"%s\"\n", e->data); @@ -54,13 +58,39 @@ bool WebSocketMessage(int eventType, const EmscriptenWebSocketMessageEvent *e, v // We expect to receive the text message before the binary one assert(text_received); + binary_received++; printf("binary data:"); for (int i = 0; i < e->numBytes; ++i) { printf(" %02X", e->data[i]); assert(e->data[i] == i); } printf("\n"); + +#ifndef TEST_EMSCRIPTEN_WEBSOCKET_DEINITIALIZE emscripten_websocket_close(e->socket, 0, 0); + // The WebSocket is being closed, but its handle is still valid. + // It should therefore still be possible to query its state. + unsigned short ready_state; + EMSCRIPTEN_RESULT result = emscripten_websocket_get_ready_state(e->socket, &ready_state); + assert(result == EMSCRIPTEN_RESULT_SUCCESS); + // https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState + assert(ready_state == 2); // 2 = CLOSING +#else + if (binary_received == 2) { + // We successfully received binary data from both websockets. + // We are done. We can deinitialize and exit. + emscripten_websocket_deinitialize(); + // All websocket handles are invalidated. + // It is no longer possible to query their state. + unsigned short ready_state; + EMSCRIPTEN_RESULT result = emscripten_websocket_get_ready_state(e->socket, &ready_state); + assert(result == EMSCRIPTEN_RESULT_INVALID_TARGET); + (void)ready_state; + sock1 = sock2 = 0; + emscripten_force_exit(0); + } +#endif // TEST_EMSCRIPTEN_WEBSOCKET_DEINITIALIZE + return 0; }