diff options
author | Andreas Huber <andih@google.com> | 2010-04-20 15:46:28 -0700 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2010-04-20 15:56:36 -0700 |
commit | 63fbd5ab8fee9db73077d10c9b5ac61625588624 (patch) | |
tree | c67c6ff00541a2d684a6e67475c13d067f28bec0 | |
parent | 25dc5f30b2a8276c5790c7152a801fcd905c7281 (diff) | |
download | frameworks_base-63fbd5ab8fee9db73077d10c9b5ac61625588624.zip frameworks_base-63fbd5ab8fee9db73077d10c9b5ac61625588624.tar.gz frameworks_base-63fbd5ab8fee9db73077d10c9b5ac61625588624.tar.bz2 |
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.
Change-Id: Ic2d4a8f5b6bbf16772fba39377809ec68d249c1f
related-to-bug: 2611257
-rw-r--r-- | media/libstagefright/HTTPDataSource.cpp | 7 | ||||
-rw-r--r-- | media/libstagefright/HTTPStream.cpp | 34 |
2 files changed, 14 insertions, 27 deletions
diff --git a/media/libstagefright/HTTPDataSource.cpp b/media/libstagefright/HTTPDataSource.cpp index a0b1993..cca6062 100644 --- a/media/libstagefright/HTTPDataSource.cpp +++ b/media/libstagefright/HTTPDataSource.cpp @@ -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) { diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp index 1e06f03..6145ec2 100644 --- a/media/libstagefright/HTTPStream.cpp +++ b/media/libstagefright/HTTPStream.cpp @@ -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) { |