bug 884792 - crash in nsXPCWrappedJS::Release, removeObserver being called off main thread r=kats

This commit is contained in:
Brad Lassey 2013-06-19 13:55:35 -04:00
parent 62a4531eac
commit fbe796c4d5
8 changed files with 36 additions and 65 deletions

View File

@ -174,7 +174,9 @@ public class GeckoAppShell
public static void callObserver(String observerKey, String topic, String data) {
sendEventToGecko(GeckoEvent.createCallObserverEvent(observerKey, topic, data));
}
public static native void removeObserver(String observerKey);
public static void removeObserver(String observerKey) {
sendEventToGecko(GeckoEvent.createRemoveObserverEvent(observerKey));
}
public static native Message getNextMessageFromQueue(MessageQueue queue);
public static native void onSurfaceTextureFrameAvailable(Object surfaceTexture, int id);

View File

@ -64,8 +64,9 @@ public class GeckoEvent {
NATIVE_GESTURE_EVENT(31),
IME_KEY_EVENT(32),
CALL_OBSERVER(33),
LOW_MEMORY(34),
NETWORK_LINK_CHANGE(35);
REMOVE_OBSERVER(34),
LOW_MEMORY(35),
NETWORK_LINK_CHANGE(36);
public final int value;
@ -669,6 +670,12 @@ public class GeckoEvent {
return event;
}
public static GeckoEvent createRemoveObserverEvent(String observerKey) {
GeckoEvent event = new GeckoEvent(NativeGeckoEvent.REMOVE_OBSERVER);
event.mCharacters = observerKey;
return event;
}
public static GeckoEvent createLowMemoryEvent(int level) {
GeckoEvent event = new GeckoEvent(NativeGeckoEvent.LOW_MEMORY);
event.mMetaState = level;

View File

@ -58,25 +58,6 @@ Java_org_mozilla_gecko_GeckoAppShell_onResume(JNIEnv * arg0, jclass arg1) {
#ifdef JNI_STUBS
typedef void (*Java_org_mozilla_gecko_GeckoAppShell_removeObserver_t)(JNIEnv *, jclass, jstring);
static Java_org_mozilla_gecko_GeckoAppShell_removeObserver_t f_Java_org_mozilla_gecko_GeckoAppShell_removeObserver;
extern "C" NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_removeObserver(JNIEnv * arg0, jclass arg1, jstring arg2) {
if (!f_Java_org_mozilla_gecko_GeckoAppShell_removeObserver) {
arg0->ThrowNew(arg0->FindClass("java/lang/UnsupportedOperationException"),
"JNI Function called before it was loaded");
return ;
}
f_Java_org_mozilla_gecko_GeckoAppShell_removeObserver(arg0, arg1, arg2);
}
#endif
#ifdef JNI_BINDINGS
xul_dlsym("Java_org_mozilla_gecko_GeckoAppShell_removeObserver", &f_Java_org_mozilla_gecko_GeckoAppShell_removeObserver);
#endif
#ifdef JNI_STUBS
typedef jobject (*Java_org_mozilla_gecko_GeckoAppShell_getNextMessageFromQueue_t)(JNIEnv *, jclass, jobject);
static Java_org_mozilla_gecko_GeckoAppShell_getNextMessageFromQueue_t f_Java_org_mozilla_gecko_GeckoAppShell_getNextMessageFromQueue;
extern "C" NS_EXPORT jobject JNICALL

View File

@ -90,20 +90,6 @@ Java_org_mozilla_gecko_GeckoAppShell_onResume(JNIEnv *jenv, jclass jc)
nsAppShell::gAppShell->OnResume();
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_removeObserver(JNIEnv *jenv, jclass, jstring jObserverKey)
{
if (!nsAppShell::gAppShell)
return;
const jchar *observerKey = jenv->GetStringChars(jObserverKey, NULL);
nsString sObserverKey(observerKey);
sObserverKey.SetLength(jenv->GetStringLength(jObserverKey));
jenv->ReleaseStringChars(jObserverKey, observerKey);
nsAppShell::gAppShell->RemoveObserver(sObserverKey);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_reportJavaCrash(JNIEnv *jenv, jclass, jstring jStackTrace)
{

View File

@ -690,6 +690,11 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj)
break;
}
case REMOVE_OBSERVER: {
ReadCharactersField(jenv);
break;
}
case LOW_MEMORY: {
mMetaState = jenv->GetIntField(jobj, jMetaStateField);
break;

View File

@ -707,8 +707,9 @@ public:
NATIVE_GESTURE_EVENT = 31,
IME_KEY_EVENT = 32,
CALL_OBSERVER = 33,
LOW_MEMORY = 34,
NETWORK_LINK_CHANGE = 35,
REMOVE_OBSERVER = 34,
LOW_MEMORY = 35,
NETWORK_LINK_CHANGE = 36,
dummy_java_enum_list_end
};

View File

@ -520,7 +520,22 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
}
case AndroidGeckoEvent::CALL_OBSERVER:
CallObserver(curEvent->Characters(), curEvent->CharactersExtra(), curEvent->Data());
{
nsCOMPtr<nsIObserver> observer;
mObserversHash.Get(curEvent->Characters(), getter_AddRefs(observer));
if (observer) {
observer->Observe(nullptr, NS_ConvertUTF16toUTF8(curEvent->CharactersExtra()).get(),
nsString(curEvent->Data()).get());
} else {
ALOG("Call_Observer event: Observer was not found!");
}
break;
}
case AndroidGeckoEvent::REMOVE_OBSERVER:
mObserversHash.Remove(curEvent->Characters());
break;
case AndroidGeckoEvent::LOW_MEMORY:
@ -736,30 +751,6 @@ nsAppShell::AddObserver(const nsAString &aObserverKey, nsIObserver *aObserver)
return NS_OK;
}
void
nsAppShell::CallObserver(const nsAString &aObserverKey, const nsAString &aTopic, const nsAString &aData)
{
nsCOMPtr<nsIObserver> observer;
mObserversHash.Get(aObserverKey, getter_AddRefs(observer));
if (!observer) {
ALOG("nsAppShell::CallObserver: Observer was not found!");
return;
}
const NS_ConvertUTF16toUTF8 sTopic(aTopic);
const nsPromiseFlatString& sData = PromiseFlatString(aData);
MOZ_ASSERT(NS_IsMainThread());
observer->Observe(nullptr, sTopic.get(), sData.get());
}
void
nsAppShell::RemoveObserver(const nsAString &aObserverKey)
{
mObserversHash.Remove(aObserverKey);
}
// Used by IPC code
namespace mozilla {

View File

@ -47,8 +47,6 @@ public:
void OnResume();
nsresult AddObserver(const nsAString &aObserverKey, nsIObserver *aObserver);
void CallObserver(const nsAString &aObserverKey, const nsAString &aTopic, const nsAString &aData);
void RemoveObserver(const nsAString &aObserverKey);
void ResendLastResizeEvent(nsWindow* aDest);
void SetBrowserApp(nsIAndroidBrowserApp* aBrowserApp) {