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

Commit 89e28cbe authored by Andreas Huber's avatar Andreas Huber Committed by Android Git Automerger
Browse files

am 9e609b0d: Merge "Apparently select() does not immediately return if one of...

am 9e609b0d: 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

Merge commit '9e609b0d' into froyo-plus-aosp

* commit '9e609b0d':
  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.
parents 8dc4c790 9e609b0d
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) {