Index: /trunk/src/corelib/io/qprocess_os2.cpp
===================================================================
--- /trunk/src/corelib/io/qprocess_os2.cpp	(revision 197)
+++ /trunk/src/corelib/io/qprocess_os2.cpp	(revision 198)
@@ -126,6 +126,4 @@
     static void removeProcess(USHORT procKey);
 
-    static QMutex *mutex() { return &mtx; }
-
 private:
 
@@ -162,10 +160,10 @@
 
     static QProcessManager *instance;
-    static QMutex mtx;
+    static QMutex mutex;
 };
 
 // static
 QProcessManager *QProcessManager::instance = 0;
-QMutex QProcessManager::mtx;
+QMutex QProcessManager::mutex;
 
 // static
@@ -202,5 +200,5 @@
 void QProcessManager::addRef()
 {
-    QMutexLocker locker(mutex());
+    QMutexLocker locker(&mutex);
 
     if (instance == 0) {
@@ -214,5 +212,5 @@
 void QProcessManager::release()
 {
-    QMutexLocker locker(mutex());
+    QMutexLocker locker(&mutex);
 
     Q_ASSERT(instance);
@@ -245,5 +243,5 @@
 #endif
 
-    QMutexLocker locker(mutex());
+    QMutexLocker locker(&mutex);
     Q_ASSERT(instance);
 
@@ -301,5 +299,5 @@
 void QProcessManager::removeProcess(USHORT procKey)
 {
-    QMutexLocker locker(mutex());
+    QMutexLocker locker(&mutex);
     Q_ASSERT(instance);
 
@@ -392,5 +390,5 @@
     // and all complex work is done here asynchronously.
 
-    QMutexLocker locker(mutex());
+    QMutexLocker locker(&mutex);
     APIRET arc;
 
@@ -480,14 +478,11 @@
                 // data to read, or if it fails to write to a (closed) pipe
             } else {
-                d->pipeData[type].bytes = pipeStates[i].usAvail;
+                // update the counter
+                if (d->pipeData[type].newBytes.fetchAndStoreRelaxed(pipeStates[i].usAvail) != 0) {
+                    // the object didn't process the previous notification yet;
+                    // there is no point to send a new one
+                    continue;
+                }
             }
-
-            if (d->pipeData[type].isNew) {
-                // the object didn't process the previous notification yet;
-                // there is no point to send a new one
-                continue;
-            }
-
-            d->pipeData[type].isNew = true;
 
             // signal the process object
@@ -532,7 +527,8 @@
     waitSem = NULLHANDLE;
 
-    // Note: after calling QProcessManager::addProcess(), pipeData member must
-    // only be accessed from under QProcessManager::mutex()!
-    memset(pipeData, sizeof(pipeData), 0);
+    pipeData[InPipe].bytesLeft = 0;
+    pipeData[OutPipe].bytesLeft = 0;
+    pipeData[ErrPipe].bytesLeft = 0;
+
     procKey = QProcessManager::InvalidProcKey;
 
@@ -992,30 +988,30 @@
 qint64 QProcessPrivate::bytesAvailableFromStdout() const
 {
-    qint64 available = 0;
-    {
-        QMutexLocker lock(QProcessManager::mutex());
-        available = pipeData[OutPipe].bytes;
-        // accept new messages from QProcessManager
-        const_cast<QProcessPrivate*>(this)->pipeData[OutPipe].isNew = false;
-    }
-#if defined (QPROCESS_DEBUG)
-    qDebug("QProcessPrivate::bytesAvailableFromStdout() == %lld", available);
-#endif
-    return available;
+    QProcessPrivate* that = const_cast<QProcessPrivate*>(this);
+
+    // grab new bytes from QProcessManager (if any)
+    int newBytes = that->pipeData[OutPipe].newBytes.fetchAndStoreRelaxed(0);
+    that->pipeData[OutPipe].bytesLeft += newBytes;
+
+#if defined (QPROCESS_DEBUG)
+    qDebug("QProcessPrivate::bytesAvailableFromStdout() == %lld",
+           that->pipeData[OutPipe].bytesLeft);
+#endif
+    return that->pipeData[OutPipe].bytesLeft;
 }
 
 qint64 QProcessPrivate::bytesAvailableFromStderr() const
 {
-    qint64 available = 0;
-    {
-        QMutexLocker lock(QProcessManager::mutex());
-        available = pipeData[ErrPipe].bytes;
-        // accept new messages from QProcessManager
-        const_cast<QProcessPrivate*>(this)->pipeData[ErrPipe].isNew = false;
-    }
-#if defined (QPROCESS_DEBUG)
-    qDebug("QProcessPrivate::bytesAvailableFromStderr() == %lld", available);
-#endif
-    return available;
+    QProcessPrivate* that = const_cast<QProcessPrivate*>(this);
+
+    // grab new bytes from QProcessManager (if any)
+    int newBytes = that->pipeData[ErrPipe].newBytes.fetchAndStoreRelaxed(0);
+    that->pipeData[ErrPipe].bytesLeft += newBytes;
+
+#if defined (QPROCESS_DEBUG)
+    qDebug("QProcessPrivate::bytesAvailableFromStderr() == %lld",
+           that->pipeData[ErrPipe].bytesLeft);
+#endif
+    return that->pipeData[ErrPipe].bytesLeft;
 }
 
@@ -1025,13 +1021,11 @@
     APIRET arc = DosRead(stdoutChannel.pipe.server, data, maxlen, &actual);
 
-    // decrement the counter to make sure bytesAvailableFromStdout() will return
-    // a correct number before QProcessManager::run() updates it
-    QMutexLocker lock(QProcessManager::mutex());
-    if (actual <= (ULONG) pipeData[OutPipe].bytes)
-        pipeData[OutPipe].bytes -= (USHORT) actual;
-    else
-        pipeData[OutPipe].bytes = 0;
-
-    qint64 bytesRead = arc == NO_ERROR ? (qint64)actual : -1;
+    qint64 bytesRead = -1;
+    if (arc == NO_ERROR) {
+        bytesRead = (qint64)actual;
+        // update our counter
+        Q_ASSERT(pipeData[OutPipe].bytesLeft >= bytesRead);
+        pipeData[OutPipe].bytesLeft -= bytesRead;
+    }
 
 #if defined QPROCESS_DEBUG
@@ -1047,13 +1041,11 @@
     APIRET arc = DosRead(stderrChannel.pipe.server, data, maxlen, &actual);
 
-    // decrement the counter to make sure bytesAvailableFromStderr() will return
-    // a correct number before QProcessManager::run() updates it
-    QMutexLocker lock(QProcessManager::mutex());
-    if (actual <= (ULONG) pipeData[ErrPipe].bytes)
-        pipeData[ErrPipe].bytes -= (USHORT) actual;
-    else
-        pipeData[ErrPipe].bytes = 0;
-
-    qint64 bytesRead = arc == NO_ERROR ? (qint64)actual : -1;
+    qint64 bytesRead = -1;
+    if (arc == NO_ERROR) {
+        bytesRead = (qint64)actual;
+        // update our counter
+        Q_ASSERT(pipeData[ErrPipe].bytesLeft >= bytesRead);
+        pipeData[ErrPipe].bytesLeft -= bytesRead;
+    }
 
 #if defined QPROCESS_DEBUG
@@ -1071,7 +1063,9 @@
     qint64 written = arc == NO_ERROR ? (qint64)actual : -1;
 
-    // accept new messages from QProcessManager
-    QMutexLocker lock(QProcessManager::mutex());
-    const_cast<QProcessPrivate*>(this)->pipeData[InPipe].isNew = false;
+    QProcessPrivate* that = const_cast<QProcessPrivate*>(this);
+
+    // reset the counter so that QProcessManager will inform us again if
+    // more space is available (note that we don't care about the actual number)
+    that->pipeData[InPipe].newBytes.fetchAndStoreRelaxed(0);
 
 #if defined QPROCESS_DEBUG
@@ -1174,13 +1168,11 @@
                 failed = true;
             } else {
-                QMutexLocker lock(QProcessManager::mutex());
-
                 bool readyReadEmitted = false;
-                if (pipeData[OutPipe].bytes) {
+                if (pipeData[OutPipe].newBytes.fetchAndAddRelaxed(0)) {
                     bool canRead = _q_canReadStandardOutput();
                     if (processChannel == QProcess::StandardOutput && canRead)
                         readyReadEmitted = true;
                 }
-                if (pipeData[ErrPipe].bytes) {
+                if (pipeData[ErrPipe].newBytes.fetchAndAddRelaxed(0)) {
                     bool canRead = _q_canReadStandardError();
                     if (processChannel == QProcess::StandardError && canRead)
@@ -1192,5 +1184,5 @@
                 }
 
-                if (pipeData[InPipe].bytes)
+                if (pipeData[InPipe].newBytes.fetchAndAddRelaxed(0))
                     _q_canWrite();
 
@@ -1242,15 +1234,13 @@
                 failed = true;
             } else {
-                QMutexLocker lock(QProcessManager::mutex());
-
-                if (pipeData[InPipe].bytes) {
+                if (pipeData[InPipe].newBytes.fetchAndAddRelaxed(0)) {
                     waitMode.fetchAndStoreRelaxed(Async);
                     return _q_canWrite();
                 }
 
-                if (pipeData[OutPipe].bytes)
+                if (pipeData[OutPipe].newBytes.fetchAndAddRelaxed(0))
                     _q_canReadStandardOutput();
 
-                if (pipeData[ErrPipe].bytes)
+                if (pipeData[ErrPipe].newBytes.fetchAndAddRelaxed(0))
                     _q_canReadStandardError();
 
@@ -1303,13 +1293,11 @@
                 failed = true;
             } else {
-                QMutexLocker lock(QProcessManager::mutex());
-
-                if (pipeData[InPipe].bytes)
+                if (pipeData[InPipe].newBytes.fetchAndAddRelaxed(0))
                     _q_canWrite();
 
-                if (pipeData[OutPipe].bytes)
+                if (pipeData[OutPipe].newBytes.fetchAndAddRelaxed(0))
                     _q_canReadStandardOutput();
 
-                if (pipeData[ErrPipe].bytes)
+                if (pipeData[ErrPipe].newBytes.fetchAndAddRelaxed(0))
                     _q_canReadStandardError();
 
@@ -1350,6 +1338,5 @@
         qDosNI(arc = DosWaitEventSem(waitSem, (ULONG)msecs));
         if (arc == NO_ERROR) {
-            QMutexLocker lock(QProcessManager::mutex());
-            ret = pipeData[InPipe].bytes;
+            ret = pipeData[InPipe].newBytes.fetchAndAddRelaxed(0);
         }
     }
Index: /trunk/src/corelib/io/qprocess_p.h
===================================================================
--- /trunk/src/corelib/io/qprocess_p.h	(revision 197)
+++ /trunk/src/corelib/io/qprocess_p.h	(revision 198)
@@ -236,6 +236,6 @@
     HEV waitSem;
     struct PipeData {
-        qint64 bytes;
-        bool isNew;
+        QAtomicInt newBytes;
+        qint64 bytesLeft;
     };
     PipeData pipeData[3]; // size must match PipeType!
