summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@qt.io>2019-09-06 10:26:11 +0200
committerMorten Johan Sørvig <morten.sorvig@qt.io>2019-09-13 13:40:07 +0200
commit24a9e0f961d84af037999771948d3d3d9c683a6c (patch)
tree94d03facb8968a58da79e16b77eaf976141bcaa3
parent81587889b1563557dd6fdc61dcde2a08445a9243 (diff)
downloadqtwebsockets-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>
-rw-r--r--src/websockets/qwebsocket_wasm_p.cpp16
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();
}