Changeset 212 for trunk/src


Ignore:
Timestamp:
Oct 7, 2009, 1:29:22 AM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

corelib: QProcess: Fixed: Don't lose the remaining stdout/stderr bytes from the child process when the death notification gets delivered before the data availability signal.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/corelib/io/qprocess_os2.cpp

    r211 r212  
    316316    // to guarantee that the given procKey may be reused, we must close all
    317317    // pipes in order to ensure that we won't get late NPSS_CLOSE for the
    318     // removed process that may be already associated with a different process
     318    // removed process
    319319    QProcessPrivate *d = process->d_func();
    320320    d->destroyPipe(d->stdinChannel.pipe);
     
    358358void QProcessManager::installSigHandler()
    359359{
    360     // set up the SIGCHLD handler, which calls _q_processDied on all
    361     // known QProcessPrivate instances every time a child dies.
     360    // set up the SIGCHLD handler
     361    //
    362362    struct sigaction oldAction;
    363363    struct sigaction action;
     
    10551055    QProcessPrivate* that = const_cast<QProcessPrivate*>(this);
    10561056
    1057     // grab new bytes from QProcessManager (if any)
    1058     int newBytes = that->pipeData[OutPipe].newBytes.fetchAndStoreRelaxed(0);
     1057    int newBytes = 0;
     1058    if (dying) {
     1059        // we are dying and won't get notifications from QProcessManager
     1060        // anymore, look manually if there's stiil something in the pipe
     1061        APIRET arc;
     1062        ULONG state;
     1063        AVAILDATA avail;
     1064        if (that->stdoutChannel.type == QProcessPrivate::Channel::Normal &&
     1065            that->stdoutChannel.pipe.server != HPIPE(~0)) {
     1066            arc = DosPeekNPipe(that->stdoutChannel.pipe.server, 0, 0, 0, &avail, &state);
     1067            Q_ASSERT(arc == NO_ERROR || arc == ERROR_INVALID_PARAMETER);
     1068            // note that even if ERROR_INVALID_PARAMETER, it seems to return the
     1069            // correct values in avail and state (undocumented)
     1070            newBytes = avail.cbpipe;
     1071            that->pipeData[OutPipe].newBytes = 0;
     1072        }
     1073    } else {
     1074        // grab new bytes from QProcessManager (if any)
     1075        newBytes = that->pipeData[OutPipe].newBytes.fetchAndStoreRelaxed(0);
     1076    }
     1077
    10591078    that->pipeData[OutPipe].bytesLeft += newBytes;
    10601079
     
    10701089    QProcessPrivate* that = const_cast<QProcessPrivate*>(this);
    10711090
    1072     // grab new bytes from QProcessManager (if any)
    1073     int newBytes = that->pipeData[ErrPipe].newBytes.fetchAndStoreRelaxed(0);
    1074     that->pipeData[ErrPipe].bytesLeft += newBytes;
     1091    int newBytes = 0;
     1092    if (dying) {
     1093        // we are dying and won't get notifications from QProcessManager
     1094        // anymore, look manually if there's stiil something in the pipe
     1095        APIRET arc;
     1096        ULONG state;
     1097        AVAILDATA avail;
     1098        if (that->stderrChannel.type == QProcessPrivate::Channel::Normal &&
     1099            that->stderrChannel.pipe.server != HPIPE(~0)) {
     1100            arc = DosPeekNPipe(that->stderrChannel.pipe.server, 0, 0, 0, &avail, &state);
     1101            Q_ASSERT(arc == NO_ERROR || arc == ERROR_INVALID_PARAMETER);
     1102            // note that even if ERROR_INVALID_PARAMETER, it seems to return the
     1103            // correct values in avail and state (undocumented)
     1104            newBytes = avail.cbpipe;
     1105            that->pipeData[ErrPipe].newBytes = 0;
     1106        }
     1107    } else {
     1108        // grab new bytes from QProcessManager (if any)
     1109        newBytes = that->pipeData[ErrPipe].newBytes.fetchAndStoreRelaxed(0);
     1110    }
    10751111
    10761112#if defined (QPROCESS_DEBUG)
Note: See TracChangeset for help on using the changeset viewer.