FdBuffer.cpp revision 0f0471623e91c202fb7381a050cc331572fb439f
11754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato/*
21754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Copyright (C) 2016 The Android Open Source Project
31754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *
41754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
51754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * you may not use this file except in compliance with the License.
61754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * You may obtain a copy of the License at
71754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *
81754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
91754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *
101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Unless required by applicable law or agreed to in writing, software
111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * See the License for the specific language governing permissions and
141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * limitations under the License.
151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato */
161754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
171754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#define LOG_TAG "incidentd"
181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include "FdBuffer.h"
2099c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin#include "io_util.h"
211754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
221754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <cutils/log.h>
231754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <utils/SystemClock.h>
241754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
251754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <fcntl.h>
261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <poll.h>
271754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <unistd.h>
280a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin#include <wait.h>
291754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
300a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinconst ssize_t BUFFER_SIZE = 16 * 1024; // 16 KB
311754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratoconst ssize_t MAX_BUFFER_COUNT = 256; // 4 MB max
321754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
331754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoFdBuffer::FdBuffer()
341754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    :mBuffers(),
351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato     mStartTime(-1),
361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato     mFinishTime(-1),
371754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato     mCurrentWritten(-1),
381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato     mTimedOut(false),
391754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato     mTruncated(false)
401754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{
411754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
421754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
431754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoFdBuffer::~FdBuffer()
441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{
451754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    const int N = mBuffers.size();
461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    for (int i=0; i<N; i++) {
471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        uint8_t* buf = mBuffers[i];
481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        free(buf);
491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
521754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatus_t
531754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoFdBuffer::read(int fd, int64_t timeout)
541754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{
551754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    struct pollfd pfds = {
561754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        .fd = fd,
571754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        .events = POLLIN
581754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    };
591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    mStartTime = uptimeMillis();
601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
611754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
621754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
631754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    uint8_t* buf = NULL;
641754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    while (true) {
651754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        if (mCurrentWritten >= BUFFER_SIZE || mCurrentWritten < 0) {
661754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            if (mBuffers.size() == MAX_BUFFER_COUNT) {
671754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                mTruncated = true;
681754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                break;
691754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            }
701754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            buf = (uint8_t*)malloc(BUFFER_SIZE);
711754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            if (buf == NULL) {
721754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                return NO_MEMORY;
731754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            }
741754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            mBuffers.push_back(buf);
751754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            mCurrentWritten = 0;
761754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        }
771754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
781754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        int64_t remainingTime = (mStartTime + timeout) - uptimeMillis();
791754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        if (remainingTime <= 0) {
801754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            mTimedOut = true;
811754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            break;
821754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        }
831754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
841754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        int count = poll(&pfds, 1, remainingTime);
851754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        if (count == 0) {
861754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            mTimedOut = true;
871754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            break;
881754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        } else if (count < 0) {
891754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            return -errno;
901754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        } else {
911754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            if ((pfds.revents & POLLERR) != 0) {
921754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                return errno != 0 ? -errno : UNKNOWN_ERROR;
931754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            } else {
941754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                ssize_t amt = ::read(fd, buf + mCurrentWritten, BUFFER_SIZE - mCurrentWritten);
951754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                if (amt < 0) {
961754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                    if (errno == EAGAIN || errno == EWOULDBLOCK) {
971754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                        continue;
981754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                    } else {
991754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                        return -errno;
1001754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                    }
1011754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                } else if (amt == 0) {
1021754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                    break;
1031754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                }
1041754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                mCurrentWritten += amt;
1051754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            }
1061754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        }
1071754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
1081754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
1091754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    mFinishTime = uptimeMillis();
1101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    return NO_ERROR;
1111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
1121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
1130a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jinstatus_t
1140a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi JinFdBuffer::readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeoutMs)
1150a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin{
1160a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    struct pollfd pfds[] = {
1170a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        { .fd = fd,     .events = POLLIN  },
1180a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        { .fd = toFd,   .events = POLLOUT },
1190a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        { .fd = fromFd, .events = POLLIN  },
1200a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    };
1210a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1220a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    mStartTime = uptimeMillis();
1230a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1240a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    // mark all fds non blocking
1250a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
1260a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    fcntl(toFd, F_SETFL, fcntl(toFd, F_GETFL, 0) | O_NONBLOCK);
1270a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    fcntl(fromFd, F_SETFL, fcntl(fromFd, F_GETFL, 0) | O_NONBLOCK);
1280a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1290a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    // A circular buffer holds data read from fd and writes to parsing process
1300a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    uint8_t cirBuf[BUFFER_SIZE];
1310a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    size_t cirSize = 0;
1320a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    int rpos = 0, wpos = 0;
1330a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1340a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    // This is the buffer used to store processed data
1350a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    uint8_t* buf = NULL;
1360a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    while (true) {
1370a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (mCurrentWritten >= BUFFER_SIZE || mCurrentWritten < 0) {
1380a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            if (mBuffers.size() == MAX_BUFFER_COUNT) {
1390a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                mTruncated = true;
1400a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                break;
1410a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            }
1420a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            buf = (uint8_t*)malloc(BUFFER_SIZE);
1430a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            if (buf == NULL) {
1440a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                return NO_MEMORY;
1450a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            }
1460a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            mBuffers.push_back(buf);
1470a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            mCurrentWritten = 0;
1480a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
1490a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1500a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        int64_t remainingTime = (mStartTime + timeoutMs) - uptimeMillis();
1510a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (remainingTime <= 0) {
1520a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            mTimedOut = true;
1530a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            break;
1540a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
1550a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1560a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // wait for any pfds to be ready to perform IO
1570a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        int count = poll(pfds, 3, remainingTime);
1580a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (count == 0) {
1590a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            mTimedOut = true;
1600a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            break;
1610a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        } else if (count < 0) {
1620a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            return -errno;
1630a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
1640a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1650a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // make sure no errors occur on any fds
1660a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        for (int i = 0; i < 3; ++i) {
1670a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            if ((pfds[i].revents & POLLERR) != 0) {
1680a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                return errno != 0 ? -errno : UNKNOWN_ERROR;
1690a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            }
1700a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
1710a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1720a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // read from fd
1730a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (cirSize != BUFFER_SIZE && pfds[0].fd != -1) {
1740a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            ssize_t amt;
1750a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            if (rpos >= wpos) {
1760a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                amt = ::read(fd, cirBuf + rpos, BUFFER_SIZE - rpos);
1770a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            } else {
1780ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin                amt = ::read(fd, cirBuf + rpos, wpos - rpos);
1790a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            }
1800a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            if (amt < 0) {
1810a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
1820a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                    return -errno;
1830a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                } // otherwise just continue
1840a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            } else if (amt == 0) {  // reach EOF so don't have to poll pfds[0].
1850a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                ::close(pfds[0].fd);
1860a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                pfds[0].fd = -1;
1870a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            } else {
1880a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                rpos += amt;
1890a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                cirSize += amt;
1900a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            }
1910a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
1920a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1930a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // write to parsing process
1940a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (cirSize > 0 && pfds[1].fd != -1) {
1950a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            ssize_t amt;
1960a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            if (rpos > wpos) {
1970a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                amt = ::write(toFd, cirBuf + wpos, rpos - wpos);
1980a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            } else {
1990a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                amt = ::write(toFd, cirBuf + wpos, BUFFER_SIZE - wpos);
2000a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            }
2010a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            if (amt < 0) {
2020a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
2030a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                    return -errno;
2040a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                } // otherwise just continue
2050a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            } else {
2060a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                wpos += amt;
2070a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                cirSize -= amt;
2080a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            }
2090a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
2100a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2110a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // if buffer is empty and fd is closed, close write fd.
2120a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (cirSize == 0 && pfds[0].fd == -1 && pfds[1].fd != -1) {
2130a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            ::close(pfds[1].fd);
2140a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            pfds[1].fd = -1;
2150a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
2160a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2170a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // circular buffer, reset rpos and wpos
2180a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (rpos >= BUFFER_SIZE) {
2190a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            rpos = 0;
2200a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
2210a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (wpos >= BUFFER_SIZE) {
2220a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            wpos = 0;
2230a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
2240a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2250a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // read from parsing process
2260a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        ssize_t amt = ::read(fromFd, buf + mCurrentWritten, BUFFER_SIZE - mCurrentWritten);
2270a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (amt < 0) {
2280a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
2290a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                return -errno;
2300a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            } // otherwise just continue
2310a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        } else if (amt == 0) {
2320a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            break;
2330a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        } else {
2340a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            mCurrentWritten += amt;
2350a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
2360a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
2370a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2380a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    mFinishTime = uptimeMillis();
2390a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    return NO_ERROR;
2400a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin}
2410a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2421754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratosize_t
24399c248feb2d1f863b864bdfd1e3b37af17f18732Yi JinFdBuffer::size() const
2441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{
2450ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    if (mBuffers.empty()) return 0;
2461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    return ((mBuffers.size() - 1) * BUFFER_SIZE) + mCurrentWritten;
2471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
2481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
2491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatus_t
25099c248feb2d1f863b864bdfd1e3b37af17f18732Yi JinFdBuffer::flush(int fd) const
2511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{
25299c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin    size_t i=0;
25399c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin    status_t err = NO_ERROR;
25499c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin    for (i=0; i<mBuffers.size()-1; i++) {
25599c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin        err = write_all(fd, mBuffers[i], BUFFER_SIZE);
25699c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin        if (err != NO_ERROR) return err;
2571754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
25899c248feb2d1f863b864bdfd1e3b37af17f18732Yi Jin    return write_all(fd, mBuffers[i], mCurrentWritten);
2591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
2601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
2610ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi JinFdBuffer::iterator
2620f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::begin() const
2630f0471623e91c202fb7381a050cc331572fb439fYi Jin{
2640f0471623e91c202fb7381a050cc331572fb439fYi Jin    return iterator(*this, 0, 0);
2650f0471623e91c202fb7381a050cc331572fb439fYi Jin}
2660f0471623e91c202fb7381a050cc331572fb439fYi Jin
2670f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator
26899c248feb2d1f863b864bdfd1e3b37af17f18732Yi JinFdBuffer::end() const
2690ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin{
2700ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    if (mBuffers.empty() || mCurrentWritten < 0) return begin();
2710ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    if (mCurrentWritten == BUFFER_SIZE)
2720ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin        // FdBuffer doesn't allocate another buf since no more bytes to read.
2730ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin        return FdBuffer::iterator(*this, mBuffers.size(), 0);
2740ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    return FdBuffer::iterator(*this, mBuffers.size() - 1, mCurrentWritten);
2750ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin}
2761754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
2770f0471623e91c202fb7381a050cc331572fb439fYi Jin// ===============================================================================
2780f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator::iterator(const FdBuffer& buffer, ssize_t index, ssize_t offset)
2790f0471623e91c202fb7381a050cc331572fb439fYi Jin        : mFdBuffer(buffer),
2800f0471623e91c202fb7381a050cc331572fb439fYi Jin          mIndex(index),
2810f0471623e91c202fb7381a050cc331572fb439fYi Jin          mOffset(offset)
2820f0471623e91c202fb7381a050cc331572fb439fYi Jin{
2830f0471623e91c202fb7381a050cc331572fb439fYi Jin}
2840f0471623e91c202fb7381a050cc331572fb439fYi Jin
2850f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator&
2860f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator::operator=(iterator& other) const { return other; }
2870f0471623e91c202fb7381a050cc331572fb439fYi Jin
2880ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi JinFdBuffer::iterator&
2890ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi JinFdBuffer::iterator::operator+(size_t offset)
2900ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin{
2910ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    size_t newOffset = mOffset + offset;
2920ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    while (newOffset >= BUFFER_SIZE) {
2930ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin        mIndex++;
2940ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin        newOffset -= BUFFER_SIZE;
2950ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    }
2960ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    mOffset = newOffset;
2970ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    return *this;
2980ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin}
2990ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin
3000f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator&
3010f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator::operator+=(size_t offset) { return *this + offset; }
3020f0471623e91c202fb7381a050cc331572fb439fYi Jin
3030f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator&
3040f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator::operator++() { return *this + 1; }
3050f0471623e91c202fb7381a050cc331572fb439fYi Jin
3060f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator
3070f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator::operator++(int) { return *this + 1; }
3080f0471623e91c202fb7381a050cc331572fb439fYi Jin
3090f0471623e91c202fb7381a050cc331572fb439fYi Jinbool
3100f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator::operator==(iterator other) const
3110f0471623e91c202fb7381a050cc331572fb439fYi Jin{
3120f0471623e91c202fb7381a050cc331572fb439fYi Jin    return mIndex == other.mIndex && mOffset == other.mOffset;
3130f0471623e91c202fb7381a050cc331572fb439fYi Jin}
3140f0471623e91c202fb7381a050cc331572fb439fYi Jin
3150f0471623e91c202fb7381a050cc331572fb439fYi Jinbool
3160f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator::operator!=(iterator other) const { return !(*this == other); }
3170f0471623e91c202fb7381a050cc331572fb439fYi Jin
3180f0471623e91c202fb7381a050cc331572fb439fYi Jinint
3190f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator::operator-(iterator other) const
3200f0471623e91c202fb7381a050cc331572fb439fYi Jin{
3210f0471623e91c202fb7381a050cc331572fb439fYi Jin    return (int)bytesRead() - (int)other.bytesRead();
3220f0471623e91c202fb7381a050cc331572fb439fYi Jin}
3230f0471623e91c202fb7381a050cc331572fb439fYi Jin
3240f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator::reference
3250f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator::operator*() const
3260f0471623e91c202fb7381a050cc331572fb439fYi Jin{
3270f0471623e91c202fb7381a050cc331572fb439fYi Jin    return mFdBuffer.mBuffers[mIndex][mOffset];
3280f0471623e91c202fb7381a050cc331572fb439fYi Jin}
3290f0471623e91c202fb7381a050cc331572fb439fYi Jin
3300f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator
3310f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator::snapshot() const
3320f0471623e91c202fb7381a050cc331572fb439fYi Jin{
3330f0471623e91c202fb7381a050cc331572fb439fYi Jin    return FdBuffer::iterator(mFdBuffer, mIndex, mOffset);
3340f0471623e91c202fb7381a050cc331572fb439fYi Jin}
3350f0471623e91c202fb7381a050cc331572fb439fYi Jin
3360ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jinsize_t
33799c248feb2d1f863b864bdfd1e3b37af17f18732Yi JinFdBuffer::iterator::bytesRead() const
3380ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin{
3390ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin    return mIndex * BUFFER_SIZE + mOffset;
3400ed9b68a3fa8f6eab536a93cb18ce75d7d22b757Yi Jin}
3410f0471623e91c202fb7381a050cc331572fb439fYi Jin
3420f0471623e91c202fb7381a050cc331572fb439fYi Jinbool
3430f0471623e91c202fb7381a050cc331572fb439fYi JinFdBuffer::iterator::outOfBound() const
3440f0471623e91c202fb7381a050cc331572fb439fYi Jin{
3450f0471623e91c202fb7381a050cc331572fb439fYi Jin    return bytesRead() > mFdBuffer.size();
3460f0471623e91c202fb7381a050cc331572fb439fYi Jin}
347