Bug 1354853 - Avoid thread racing on Androidridge instance. r=jolin, r=jchen

Add a static boolean sThreadDestroyed which can be accessed only on JAVA UI thread.
Set sThreadDestroyed to true at DestroyOnUiThread that will stop remain tasks to access the Bridge() instance at JAVA thread.

MozReview-Commit-ID: 5JtUFgc6Vl3
This commit is contained in:
bechen 2017-05-09 15:05:27 +08:00
parent 6046b7867a
commit e6109d70d8
2 changed files with 14 additions and 5 deletions

View File

@ -20,6 +20,7 @@ namespace {
class AndroidUiThread;
StaticRefPtr<AndroidUiThread> sThread;
static bool sThreadDestroyed;
static MessageLoop* sMessageLoop;
static Atomic<Monitor*> sMessageLoopAccessMonitor;
@ -47,6 +48,14 @@ public:
nsresult Dispatch(already_AddRefed<nsIRunnable> aEvent, uint32_t aFlags) override;
nsresult DelayedDispatch(already_AddRefed<nsIRunnable> aEvent, uint32_t aDelayMs) override;
static int64_t RunDelayedTasksIfValid() {
if (!AndroidBridge::Bridge() ||
sThreadDestroyed) {
return -1;
}
return AndroidBridge::Bridge()->RunDelayedUiThreadTasks();
}
private:
~AndroidUiThread()
{}
@ -118,6 +127,7 @@ public:
{}
NS_IMETHOD Run() override {
MOZ_ASSERT(!sThreadDestroyed);
MOZ_ASSERT(sMessageLoopAccessMonitor);
MonitorAutoLock lock(*sMessageLoopAccessMonitor);
sThread = new AndroidUiThread();
@ -135,6 +145,7 @@ public:
{}
NS_IMETHOD Run() override {
MOZ_ASSERT(!sThreadDestroyed);
MOZ_ASSERT(sMessageLoopAccessMonitor);
MonitorAutoLock lock(*sMessageLoopAccessMonitor);
@ -144,6 +155,7 @@ public:
nsThreadManager::get().UnregisterCurrentThread(*sThread);
sThread = nullptr;
mDestroyed = true;
sThreadDestroyed = true;
lock.NotifyAll();
return NS_OK;
}
@ -171,6 +183,7 @@ CreateAndroidUiThread()
MOZ_ASSERT(!sThread);
MOZ_ASSERT(!sMessageLoopAccessMonitor);
sMessageLoopAccessMonitor = new Monitor("AndroidUiThreadMessageLoopAccessMonitor");
sThreadDestroyed = false;
RefPtr<CreateOnUiThread> runnable = new CreateOnUiThread;
AndroidBridge::Bridge()->PostTaskToUiThread(do_AddRef(runnable), 0);
}

View File

@ -239,11 +239,7 @@ public:
static int64_t RunUiThreadCallback()
{
if (!AndroidBridge::Bridge()) {
return -1;
}
return AndroidBridge::Bridge()->RunDelayedUiThreadTasks();
return AndroidUiThread::RunDelayedTasksIfValid();
}
};