Merge "While streaming media data, upon a socket-read error, try reconnecting to the server and attempt to re-read for at most 3 times."
This commit is contained in:
committed by
Android (Google) Code Review
commit
cf74ceea59
@@ -54,7 +54,11 @@ protected:
|
||||
|
||||
private:
|
||||
enum {
|
||||
kBufferSize = 32 * 1024
|
||||
kBufferSize = 32 * 1024,
|
||||
|
||||
// If we encounter a socket-read error we'll try reconnecting
|
||||
// and restarting the read for at most this many times.
|
||||
kMaxNumRetries = 3,
|
||||
};
|
||||
|
||||
enum State {
|
||||
@@ -84,6 +88,8 @@ private:
|
||||
bool mContentLengthValid;
|
||||
unsigned long long mContentLength;
|
||||
|
||||
int32_t mNumRetriesLeft;
|
||||
|
||||
void init(const KeyedVector<String8, String8> *headers);
|
||||
|
||||
ssize_t sendRangeRequest(size_t offset);
|
||||
|
||||
@@ -154,8 +154,8 @@ void HTTPDataSource::init(const KeyedVector<String8, String8> *headers) {
|
||||
initHeaders(headers);
|
||||
|
||||
mBuffer = malloc(kBufferSize);
|
||||
mBufferLength = 0;
|
||||
mBufferOffset = 0;
|
||||
|
||||
mNumRetriesLeft = kMaxNumRetries;
|
||||
}
|
||||
|
||||
status_t HTTPDataSource::connect() {
|
||||
@@ -169,6 +169,8 @@ status_t HTTPDataSource::connect() {
|
||||
mState = CONNECTING;
|
||||
}
|
||||
|
||||
mBufferLength = 0;
|
||||
mBufferOffset = 0;
|
||||
mContentLengthValid = false;
|
||||
|
||||
string host = mStartingHost.string();
|
||||
@@ -328,6 +330,7 @@ ssize_t HTTPDataSource::sendRangeRequest(size_t offset) {
|
||||
ssize_t HTTPDataSource::readAt(off_t offset, void *data, size_t size) {
|
||||
LOGV("readAt %ld, size %d", offset, size);
|
||||
|
||||
rinse_repeat:
|
||||
{
|
||||
Mutex::Autolock autoLock(mStateLock);
|
||||
if (mState != CONNECTED) {
|
||||
@@ -383,6 +386,15 @@ ssize_t HTTPDataSource::readAt(off_t offset, void *data, size_t size) {
|
||||
ssize_t num_bytes_received = mHttp->receive(mBuffer, contentLength);
|
||||
|
||||
if (num_bytes_received < 0) {
|
||||
if (mNumRetriesLeft-- > 0) {
|
||||
disconnect();
|
||||
if (connect() == OK) {
|
||||
LOGI("retrying connection succeeded.");
|
||||
goto rinse_repeat;
|
||||
}
|
||||
LOGE("retrying connection failed");
|
||||
}
|
||||
|
||||
mBufferLength = 0;
|
||||
|
||||
return num_bytes_received;
|
||||
|
||||
@@ -289,11 +289,15 @@ ssize_t HTTPStream::receive(void *data, size_t size) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LOGE("recv failed, errno = %d (%s)", errno, strerror(errno));
|
||||
|
||||
disconnect();
|
||||
return total == 0 ? (ssize_t)ERROR_IO : total;
|
||||
return (ssize_t)ERROR_IO;
|
||||
} else if (n == 0) {
|
||||
disconnect();
|
||||
|
||||
LOGE("recv failed, server is gone");
|
||||
|
||||
return total == 0 ? (ssize_t)ERROR_CONNECTION_LOST : total;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user