diff options
author | Maurice Kalinowski <maurice.kalinowski@qt.io> | 2016-04-25 12:29:20 +0200 |
---|---|---|
committer | Maurice Kalinowski <maurice.kalinowski@qt.io> | 2016-04-28 03:40:07 +0000 |
commit | 52e68d4e106548eb027d4b35e47c941eb2d73f58 (patch) | |
tree | 6e214d113eccd1f522da90ba61dddcb27764d79c /src/plugins/platforms | |
parent | adac71c04454219bdca79cbace5a1d9c18ce05c4 (diff) |
winrt: Fix memory leak for file reading
IInputStream::ReadAsync might create a separate buffer to fill in data.
Passing a buffer with GetAddressOf() can cause a memory leak of the size
of data to be read.
Instead, pass a separate buffer pointer and continue to use this one
after the async operation. This way, the OS can decide whether to switch
buffers or not, keeping ref counting in sync.
Task-number: QTBUG-52961
Change-Id: I9dfb627287142355ebcf74ca52427b4e8108e8d1
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtfileengine.cpp | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp index 858cb841b9..fb7c5e9990 100644 --- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp +++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp @@ -463,14 +463,20 @@ qint64 QWinRTFileEngine::read(char *data, qint64 maxlen) hr = stream->ReadAsync(buffer.Get(), length, InputStreamOptions_None, &op); RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1); - hr = QWinRTFunctions::await(op, buffer.GetAddressOf()); + // Quoting MSDN IInputStream::ReadAsync() documentation: + // "Depending on the implementation, the data that's read might be placed + // into the input buffer, or it might be returned in a different buffer." + // Using GetAddressOf can cause ref counting errors leaking the original + // buffer. + ComPtr<IBuffer> effectiveBuffer; + hr = QWinRTFunctions::await(op, effectiveBuffer.GetAddressOf()); RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1); - hr = buffer->get_Length(&length); + hr = effectiveBuffer->get_Length(&length); RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1); ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess; - hr = buffer.As(&byteArrayAccess); + hr = effectiveBuffer.As(&byteArrayAccess); RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1); byte *bytes; |