bool NamedPipe::serviceIo()

in src/agent/NamedPipe.cc [33:81]


bool NamedPipe::serviceIo(std::vector<HANDLE> *waitHandles)
{
    bool justConnected = false;
    const auto kError = ServiceResult::Error;
    const auto kProgress = ServiceResult::Progress;
    const auto kNoProgress = ServiceResult::NoProgress;
    if (m_handle == NULL) {
        return false;
    }
    if (m_connectEvent.get() != nullptr) {
        // We're still connecting this server pipe.  Check whether the pipe is
        // now connected.  If it isn't, add the pipe to the list of handles to
        // wait on.
        DWORD actual = 0;
        BOOL success =
            GetOverlappedResult(m_handle, &m_connectOver, &actual, FALSE);
        if (!success && GetLastError() == ERROR_PIPE_CONNECTED) {
            // I'm not sure this can happen, but it's easy to handle if it
            // does.
            success = TRUE;
        }
        if (!success) {
            ASSERT(GetLastError() == ERROR_IO_INCOMPLETE &&
                "Pended ConnectNamedPipe call failed");
            waitHandles->push_back(m_connectEvent.get());
        } else {
            TRACE("Server pipe [%s] connected",
                utf8FromWide(m_name).c_str());
            m_connectEvent.dispose();
            startPipeWorkers();
            justConnected = true;
        }
    }
    const auto readProgress = m_inputWorker ? m_inputWorker->service() : kNoProgress;
    const auto writeProgress = m_outputWorker ? m_outputWorker->service() : kNoProgress;
    if (readProgress == kError || writeProgress == kError) {
        closePipe();
        return true;
    }
    if (m_inputWorker && m_inputWorker->getWaitEvent() != nullptr) {
        waitHandles->push_back(m_inputWorker->getWaitEvent());
    }
    if (m_outputWorker && m_outputWorker->getWaitEvent() != nullptr) {
        waitHandles->push_back(m_outputWorker->getWaitEvent());
    }
    return justConnected
        || readProgress == kProgress
        || writeProgress == kProgress;
}