Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9e609b0d authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

Merge "Apparently select() does not immediately return if one of the masked...

Merge "Apparently select() does not immediately return if one of the masked socket descriptors is closed... Stop relying on select for read-with-timeout functionality and use SO_RCVTIMEO socket option instead." into froyo
parents fe8620ac 63fbd5ab
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -39,6 +39,13 @@ status_t HTTPDataSource::connectWithRedirectsAndRange(off_t rangeStart) {

    int numRedirectsRemaining = 5;
    while (numRedirectsRemaining-- > 0) {
        {
            Mutex::Autolock autoLock(mStateLock);
            if (mState == DISCONNECTED) {
                return UNKNOWN_ERROR;
            }
        }

        status_t err = mHttp->connect(host.c_str(), port);

        if (err != OK) {
+7 −27
Original line number Diff line number Diff line
@@ -68,6 +68,11 @@ status_t HTTPStream::connect(const char *server, int port) {
        return UNKNOWN_ERROR;
    }

    struct timeval tv;
    tv.tv_usec = 0;
    tv.tv_sec = 5;
    CHECK_EQ(0, setsockopt(mSocket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)));

    mState = CONNECTING;

    int s = mSocket;
@@ -150,30 +155,6 @@ status_t HTTPStream::send(const char *data) {
    return send(data, strlen(data));
}

static ssize_t recvWithTimeout(
        int s, void *data, size_t size) {
    fd_set rs, es;
    FD_ZERO(&rs);
    FD_ZERO(&es);
    FD_SET(s, &rs);
    FD_SET(s, &es);

    struct timeval tv;
    tv.tv_sec = 5;  // 5 sec timeout
    tv.tv_usec = 0;

    int res = select(s + 1, &rs, NULL, &es, &tv);

    if (res < 0) {
        return -1;
    } else if (res == 0) {
        errno = ETIMEDOUT;
        return -1;
    }

    return recv(s, data, size, 0);
}

// A certain application spawns a local webserver that sends invalid responses,
// specifically it terminates header line with only a newline instead of the
// CRLF (carriage-return followed by newline) required by the HTTP specs.
@@ -192,7 +173,7 @@ status_t HTTPStream::receive_line(char *line, size_t size) {

    for (;;) {
        char c;
        ssize_t n = recvWithTimeout(mSocket, &c, 1);
        ssize_t n = recv(mSocket, &c, 1, 0);
        if (n < 0) {
            if (errno == EINTR) {
                continue;
@@ -310,8 +291,7 @@ status_t HTTPStream::receive_header(int *http_status) {
ssize_t HTTPStream::receive(void *data, size_t size) {
    size_t total = 0;
    while (total < size) {
        ssize_t n = recvWithTimeout(
                mSocket, (char *)data + total, size - total);
        ssize_t n = recv(mSocket, (char *)data + total, size - total, 0);

        if (n < 0) {
            if (errno == EINTR) {