From 24a9e0f961d84af037999771948d3d3d9c683a6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 6 Sep 2019 10:26:11 +0200 Subject: wasm: make sendBinaryMessage work in threaded mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes two issues in sendBinaryMessage(), one observed, and one theoretical: 1) WebSocket send() does not accept data views backed by SharedArrayBuffer, which is the case for heap memory views when threading is enabled. 2) We have no way of observing for how long send() will retain the memory view passed to it. This means we don’t know when the QByteArray can be safely freed. Both can be solved by copying the payload data to a separate ArrayBuffer, whose lifetime can be managed by WebSocket. Fixes: QTBUG-78078 Change-Id: I73209080db66f38b971f2c8a727b43402357b1a9 Reviewed-by: Lorn Potter --- src/websockets/qwebsocket_wasm_p.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/websockets/qwebsocket_wasm_p.cpp b/src/websockets/qwebsocket_wasm_p.cpp index 199fe44..85fcab2 100644 --- a/src/websockets/qwebsocket_wasm_p.cpp +++ b/src/websockets/qwebsocket_wasm_p.cpp @@ -137,11 +137,19 @@ qint64 QWebSocketPrivate::sendTextMessage(const QString &message) qint64 QWebSocketPrivate::sendBinaryMessage(const QByteArray &data) { - socketContext.call("send", - val(typed_memory_view(data.size(), - reinterpret_cast - (data.constData())))); + // Make a copy of the payload data; we don't know how long WebSocket.send() will + // retain the memory view, while the QByteArray passed to this function may be + // destroyed as soon as this function returns. In addition, the WebSocket.send() + // API does not accept data from a view backet by a SharedArrayBuffer, which will + // be the case for the view produced by typed_memory_view() when threads are enabled. + val Uint8Array = val::global("Uint8Array"); + val dataCopy = Uint8Array.new_(data.size()); + val dataView = val(typed_memory_view(data.size(), + reinterpret_cast + (data.constData()))); + dataCopy.call("set", dataView); + socketContext.call("send", dataCopy); return data.length(); } -- cgit v1.2.1