From b787977ba0c266c157db9d0275e0fe9b7ae5d35f Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 1 Nov 2016 14:48:16 +0100 Subject: winrt: Guard pendingReadOps with mutex As the list is changed inside a native callback (handleReadyRead) which can be run inside another thread it has to be protected by a mutex. Change-Id: I145a866a36a12b7ea9bfa9f99ad9f7add872a021 Reviewed-by: Maurice Kalinowski Reviewed-by: David Faure --- src/network/socket/qnativesocketengine_winrt.cpp | 7 +++++++ src/network/socket/qnativesocketengine_winrt_p.h | 5 +++++ 2 files changed, 12 insertions(+) (limited to 'src/network') diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index f710f6b142..7ea4d135f4 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -329,6 +329,7 @@ bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket:: hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, readOp.GetAddressOf()); RETURN_OK_IF_FAILED_WITH_ARGS("initialize(): Failed to read from the socket buffer (%s).", socketDescription(this).constData()); + QMutexLocker locker(&d->readOperationsMutex); d->pendingReadOps.append(readOp); d->socketState = socketState; hr = readOp->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); @@ -574,6 +575,7 @@ void QNativeSocketEngine::close() } #endif // _MSC_VER >= 1900 + QMutexLocker locker(&d->readOperationsMutex); for (ComPtr readOp : d->pendingReadOps) { ComPtr info; hr = readOp.As(&info); @@ -585,6 +587,7 @@ void QNativeSocketEngine::close() Q_ASSERT_SUCCEEDED(hr); } } + locker.unlock(); if (d->socketDescriptor != -1) { ComPtr socket; @@ -945,6 +948,7 @@ void QNativeSocketEngine::establishRead() ComPtr readOp; hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, readOp.GetAddressOf()); RETURN_HR_IF_FAILED("establishRead(): Failed to initiate socket read"); + QMutexLocker locker(&d->readOperationsMutex); d->pendingReadOps.append(readOp); hr = readOp->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); RETURN_HR_IF_FAILED("establishRead(): Failed to register read callback"); @@ -1421,12 +1425,14 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async } Q_Q(QNativeSocketEngine); + QMutexLocker locker(&readOperationsMutex); for (int i = 0; i < pendingReadOps.count(); ++i) { if (pendingReadOps.at(i).Get() == asyncInfo) { pendingReadOps.takeAt(i); break; } } + locker.unlock(); static QMutex mutex; mutex.lock(); @@ -1503,6 +1509,7 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async socketDescription(q).constData()); return S_OK; } + QMutexLocker locker(&readOperationsMutex); pendingReadOps.append(readOp); hr = readOp->put_Completed(Callback(this, &QNativeSocketEnginePrivate::handleReadyRead).Get()); if (FAILED(hr)) { diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index c9a67ca5f4..e01d205896 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -214,6 +214,8 @@ private: { return reinterpret_cast(socketDescriptor); } Microsoft::WRL::ComPtr tcpListener; Microsoft::WRL::ComPtr connectOp; + + // Protected by readOperationsMutex. Written in handleReadyRead (native callback) QVector>> pendingReadOps; // Protected by readMutex. Written in handleReadyRead (native callback) @@ -224,6 +226,9 @@ private: // handleNewDatagrams/putIntoPendingDatagramsList) mutable QMutex readMutex; + // As pendingReadOps is changed inside handleReadyRead(native callback) it has to be protected + QMutex readOperationsMutex; + bool emitOnNewDatagram; // Protected by readMutex. Written in handleReadyRead (native callback) -- cgit v1.2.3