QWindowsPipeWriter: clean up OVERLAPPED resource handling

Use RAII to ensure that every code path cleans up the event handle,
and re-initialize the whole OVERLAPPED object, not just the two
offset members.

Change-Id: If7e68ec6e61b7bb04df0d06734c04589f6822c4a
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
This commit is contained in:
Joerg Bornemann 2015-09-28 16:25:02 +02:00
parent 3964b683f8
commit 9ef8760355

View File

@ -90,11 +90,38 @@ qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen)
return maxlen;
}
class QPipeWriterOverlapped
{
public:
QPipeWriterOverlapped()
{
overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
}
~QPipeWriterOverlapped()
{
CloseHandle(overlapped.hEvent);
}
void prepare()
{
const HANDLE hEvent = overlapped.hEvent;
ZeroMemory(&overlapped, sizeof overlapped);
overlapped.hEvent = hEvent;
}
OVERLAPPED *operator&()
{
return &overlapped;
}
private:
OVERLAPPED overlapped;
};
void QWindowsPipeWriter::run()
{
OVERLAPPED overl;
memset(&overl, 0, sizeof overl);
overl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
QPipeWriterOverlapped overl;
forever {
lock.lock();
while(data.isEmpty() && (!quitNow)) {
@ -115,8 +142,7 @@ void QWindowsPipeWriter::run()
const char *ptrData = copy.data();
qint64 maxlen = copy.size();
qint64 totalWritten = 0;
overl.Offset = 0;
overl.OffsetHigh = 0;
overl.prepare();
while ((!quitNow) && totalWritten < maxlen) {
DWORD written = 0;
if (!WriteFile(writePipe, ptrData + totalWritten,
@ -130,11 +156,9 @@ void QWindowsPipeWriter::run()
#ifndef Q_OS_WINCE
if (GetLastError() == ERROR_IO_PENDING) {
if (!GetOverlappedResult(writePipe, &overl, &written, TRUE)) {
CloseHandle(overl.hEvent);
return;
}
} else {
CloseHandle(overl.hEvent);
return;
}
#else
@ -154,7 +178,6 @@ void QWindowsPipeWriter::run()
emit bytesWritten(totalWritten);
emit canWrite();
}
CloseHandle(overl.hEvent);
}
#endif //QT_NO_THREAD