From 5c89e2eeeed3c58e8068ddfca0cddcc801c2e30a Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 15 Mar 2016 10:59:59 +0100 Subject: Rework QWindowsPipeReader The use of QWinOverlappedIoNotifier in QWindowsPipeReader restricts us in the following ways: - The handle that gets assigned to QWinOverlappedIoNotifier is forever tied to an I/O completion port. - Other notification mechanisms like I/O completion routines of WriteFileEx do not work with such a handle. - No other QWinOverlappedIoNotifier can be registered for this handle. To achieve the ultimate goal of making QWindowsPipeWriter thread-free (to fix QTBUG-23378 and QTBUG-38185) we remove the usage of QWinOverlappedIoNotifier from QWindowsPipeReader and use the ReadFileEx API instead. This has the additional advantage of removing the need for any thread synchronization, as the I/O completion routine runs in the thread that ReadFileEx was called on, leading to simpler and faster code. Change-Id: I05c983e1f1e49d7dd27e3b77a47f87cae9c3f4c6 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipereader_p.h | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'src/corelib/io/qwindowspipereader_p.h') diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h index c8a66d9511..44009877f2 100644 --- a/src/corelib/io/qwindowspipereader_p.h +++ b/src/corelib/io/qwindowspipereader_p.h @@ -45,7 +45,6 @@ // We mean it. // -#include #include #include @@ -53,9 +52,6 @@ QT_BEGIN_NAMESPACE - -class QWinOverlappedIoNotifier; - class Q_CORE_EXPORT QWindowsPipeReader : public QObject { Q_OBJECT @@ -64,6 +60,7 @@ public: ~QWindowsPipeReader(); void setHandle(HANDLE hPipeReadEnd); + void startAsyncRead(); void stop(); void setMaxReadBufferSize(qint64 size) { readBufferMaxSize = size; } @@ -76,31 +73,42 @@ public: bool waitForReadyRead(int msecs); bool waitForPipeClosed(int msecs); - void startAsyncRead(); bool isReadOperationActive() const { return readSequenceStarted; } Q_SIGNALS: void winError(ulong, const QString &); void readyRead(); void pipeClosed(); - -private Q_SLOTS: - void notified(quint32 numberOfBytesRead, quint32 errorCode, OVERLAPPED *notifiedOverlapped); + void _q_queueReadyRead(QPrivateSignal); private: + static void CALLBACK readFileCompleted(DWORD errorCode, DWORD numberOfBytesTransfered, + OVERLAPPED *overlappedBase); + void notified(DWORD errorCode, DWORD numberOfBytesRead); DWORD checkPipeState(); + bool waitForNotification(int timeout); + void emitPendingReadyRead(); + + class Overlapped : public OVERLAPPED + { + Q_DISABLE_COPY(Overlapped) + public: + explicit Overlapped(QWindowsPipeReader *reader); + void clear(); + QWindowsPipeReader *pipeReader; + }; -private: HANDLE handle; - OVERLAPPED overlapped; - QWinOverlappedIoNotifier *dataReadNotifier; + Overlapped overlapped; qint64 readBufferMaxSize; QRingBuffer readBuffer; qint64 actualReadBufferSize; bool stopped; bool readSequenceStarted; + bool notifiedCalled; bool pipeBroken; - bool readyReadEmitted; + bool readyReadPending; + bool inReadyRead; }; QT_END_NAMESPACE -- cgit v1.2.3