diff options
author | Morten Johan Sørvig <morten.sorvig@qt.io> | 2019-09-06 10:26:11 +0200 |
---|---|---|
committer | Morten Johan Sørvig <morten.sorvig@qt.io> | 2019-09-13 13:40:07 +0200 |
commit | 24a9e0f961d84af037999771948d3d3d9c683a6c (patch) | |
tree | 94d03facb8968a58da79e16b77eaf976141bcaa3 /src | |
parent | 81587889b1563557dd6fdc61dcde2a08445a9243 (diff) | |
download | qtwebsockets-24a9e0f961d84af037999771948d3d3d9c683a6c.tar.gz |
wasm: make sendBinaryMessage work in threaded mode
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 <lorn.potter@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/websockets/qwebsocket_wasm_p.cpp | 16 |
1 files 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<void>("send", - val(typed_memory_view(data.size(), - reinterpret_cast<const unsigned char *> - (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<const unsigned char *> + (data.constData()))); + dataCopy.call<void>("set", dataView); + socketContext.call<void>("send", dataCopy); return data.length(); } |