Improve handling of cancelled HTTP requests

Fix a memory leak of NativeMapView Java object
This commit is contained in:
Leith Bade
2015-09-17 17:34:13 -07:00
parent 6e55dd575e
commit 19e7d154bb
4 changed files with 27 additions and 18 deletions

View File

@@ -73,7 +73,7 @@ NativeMapView::NativeMapView(JNIEnv *env, jobject obj_, float pixelRatio_, int a
return;
}
obj = env->NewGlobalRef(obj_);
obj = env->NewWeakGlobalRef(obj_);
if (obj == nullptr) {
env->ExceptionDescribe();
return;
@@ -93,7 +93,7 @@ NativeMapView::~NativeMapView() {
JNIEnv *env = nullptr;
ret = vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
if (ret == JNI_OK) {
env->DeleteGlobalRef(obj);
env->DeleteWeakGlobalRef(obj);
} else {
mbgl::Log::Error(mbgl::Event::JNI, "GetEnv() failed with %i", ret);
throw new std::runtime_error("GetEnv() failed");

View File

@@ -20,6 +20,7 @@ class HTTPContext {
private static final int CONNECTION_ERROR = 0;
private static final int TEMPORARY_ERROR = 1;
private static final int PERMANENT_ERROR = 2;
private static final int CANCELED_ERROR = 3;
private static HTTPContext mInstance = null;
@@ -78,7 +79,10 @@ class HTTPContext {
type = CONNECTION_ERROR;
} else if ((e instanceof InterruptedIOException)) {
type = TEMPORARY_ERROR;
} else if (mCall.isCanceled()) {
type = CANCELED_ERROR;
}
nativeOnFailure(mNativePtr, type, e.getMessage());
}

View File

@@ -62,7 +62,7 @@ private:
private:
JavaVM *vm = nullptr;
jobject obj = nullptr;
jweak obj = nullptr;
ANativeWindow *window = nullptr;
EGLDisplay display = EGL_NO_DISPLAY;

View File

@@ -75,7 +75,8 @@ private:
static const int connectionError = 0;
static const int temporaryError = 1;
static const int permanentError = 1;
static const int permanentError = 2;
static const int canceledError = 3;
};
// -------------------------------------------------------------------------------------------------
@@ -305,22 +306,26 @@ void HTTPAndroidRequest::onResponse(int code, std::string message, std::string e
}
void HTTPAndroidRequest::onFailure(int type, std::string message) {
if (!response) {
response = std::make_unique<Response>();
}
if (type != canceledError) {
if (!response) {
response = std::make_unique<Response>();
}
response->status = Response::Error;
response->message = message;
response->status = Response::Error;
response->message = message;
switch (type) {
case connectionError:
status = ResponseStatus::ConnectionError;
case temporaryError:
status = ResponseStatus::TemporaryError;
default:
status = ResponseStatus::PermanentError;
switch (type) {
case connectionError:
status = ResponseStatus::ConnectionError;
break;
case temporaryError:
status = ResponseStatus::TemporaryError;
break;
default:
status = ResponseStatus::PermanentError;
}
} else {
status = ResponseStatus::Canceled;
}
async.send();