diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2016-11-05 01:52:00 +0100 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2016-11-05 01:53:17 +0100 |
commit | e79ceb97340699ed806aa021e1bda4b63fa6f3fe (patch) | |
tree | 7e9ff3f64e026562eb76b523aa6be615d466598b /src/network/socket | |
parent | 825bb10d9bf40587828e4e589b199a9ffec255ce (diff) | |
parent | a21ffd44b3a13a9ef64a56e67f6e267292f0a8e2 (diff) |
Merge remote-tracking branch 'gerrit/5.8' into dev
Change-Id: Ib31cae9b57f6fb078739c409162bf2987eb430ad
Diffstat (limited to 'src/network/socket')
-rw-r--r-- | src/network/socket/qnativesocketengine_winrt.cpp | 22 | ||||
-rw-r--r-- | src/network/socket/qnativesocketengine_winrt_p.h | 18 |
2 files changed, 30 insertions, 10 deletions
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index f8e92d3f50..62bc8ca683 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<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); @@ -574,6 +575,7 @@ void QNativeSocketEngine::close() } #endif // _MSC_VER >= 1900 + QMutexLocker locker(&d->readOperationsMutex); for (ComPtr<IAsyncBufferOperation> readOp : d->pendingReadOps) { ComPtr<IAsyncInfo> info; hr = readOp.As(&info); @@ -585,6 +587,7 @@ void QNativeSocketEngine::close() Q_ASSERT_SUCCEEDED(hr); } } + locker.unlock(); if (d->socketDescriptor != -1) { ComPtr<IClosable> socket; @@ -659,6 +662,7 @@ qint64 QNativeSocketEngine::read(char *data, qint64 maxlen) if (d->socketType != QAbstractSocket::TcpSocket) return -1; + QMutexLocker mutexLocker(&d->readMutex); // There will be a read notification when the socket was closed by the remote host. If that // happens and there isn't anything left in the buffer, we have to return -1 in order to signal // the closing of the socket. @@ -667,7 +671,6 @@ qint64 QNativeSocketEngine::read(char *data, qint64 maxlen) return -1; } - QMutexLocker mutexLocker(&d->readMutex); qint64 b = d->readBytes.read(data, maxlen); d->bytesAvailable = d->readBytes.size() - d->readBytes.pos(); return b; @@ -701,7 +704,7 @@ qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QIpPacketHea { #ifndef QT_NO_UDPSOCKET Q_D(QNativeSocketEngine); - d->readMutex.lock(); + QMutexLocker locker(&d->readMutex); if (d->socketType != QAbstractSocket::UdpSocket || d->pendingDatagrams.isEmpty()) { if (header) header->clear(); @@ -721,7 +724,7 @@ qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QIpPacketHea } else { readOrigin = datagram.data; } - d->readMutex.unlock(); + locker.unlock(); memcpy(data, readOrigin, qMin(maxlen, qint64(datagram.data.length()))); return readOrigin.length(); #else @@ -772,12 +775,14 @@ qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 len, const QI bool QNativeSocketEngine::hasPendingDatagrams() const { Q_D(const QNativeSocketEngine); + QMutexLocker locker(&d->readMutex); return d->pendingDatagrams.length() > 0; } qint64 QNativeSocketEngine::pendingDatagramSize() const { Q_D(const QNativeSocketEngine); + QMutexLocker locker(&d->readMutex); if (d->pendingDatagrams.isEmpty()) return -1; @@ -943,6 +948,7 @@ void QNativeSocketEngine::establishRead() ComPtr<IAsyncBufferOperation> 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<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); RETURN_HR_IF_FAILED("establishRead(): Failed to register read callback"); @@ -1419,15 +1425,15 @@ 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(); // A read in UnconnectedState will close the socket and return -1 and thus tell the caller, // that the connection was closed. The socket cannot be closed here, as the subsequent read // might fail then. @@ -1465,7 +1471,7 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async hr = byteArrayAccess->Buffer(&data); Q_ASSERT_SUCCEEDED(hr); - readMutex.lock(); + QMutexLocker readLocker(&readMutex); if (readBytes.atEnd()) // Everything has been read; the buffer is safe to reset readBytes.close(); if (!readBytes.isOpen()) @@ -1476,11 +1482,10 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async readBytes.write(reinterpret_cast<const char*>(data), qint64(bufferLength)); readBytes.seek(readPos); bytesAvailable = readBytes.size() - readBytes.pos(); - readMutex.unlock(); + readLocker.unlock(); if (notifyOnRead) emit q->readReady(); - mutex.unlock(); hr = QEventDispatcherWinRT::runOnXamlThread([buffer, q, this]() { UINT32 readBufferLength; @@ -1501,6 +1506,7 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async socketDescription(q).constData()); return S_OK; } + QMutexLocker locker(&readOperationsMutex); pendingReadOps.append(readOp); hr = readOp->put_Completed(Callback<SocketReadCompletedHandler>(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 79530d57f1..085704275c 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -214,13 +214,27 @@ private: { return reinterpret_cast<ABI::Windows::Networking::Sockets::IDatagramSocket *>(socketDescriptor); } Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocketListener> tcpListener; Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncAction> connectOp; + + // Protected by readOperationsMutex. Written in handleReadyRead (native callback) QVector<Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperationWithProgress<ABI::Windows::Storage::Streams::IBuffer *, UINT32>>> pendingReadOps; + + // Protected by readMutex. Written in handleReadyRead (native callback) QBuffer readBytes; - QMutex readMutex; - bool emitOnNewDatagram; + + // In case of TCP readMutex protects readBytes and bytesAvailable. In case of UDP it is + // pendingDatagrams. They are written inside native callbacks (handleReadyRead and + // handleNewDatagrams/putIntoPendingDatagramsList) + mutable QMutex readMutex; + + // As pendingReadOps is changed inside handleReadyRead(native callback) it has to be protected + QMutex readOperationsMutex; + + // Protected by readMutex. Written in handleReadyRead (native callback) QAtomicInteger<int> bytesAvailable; + // Protected by readMutex. Written in handleNewDatagrams/putIntoPendingDatagramsList QList<WinRtDatagram> pendingDatagrams; + QList<ABI::Windows::Networking::Sockets::IStreamSocket *> pendingConnections; QList<ABI::Windows::Networking::Sockets::IStreamSocket *> currentConnections; QEventLoop eventLoop; |