Skip to content
This repository has been archived by the owner on Aug 4, 2022. It is now read-only.

Commit

Permalink
Bug 1367850 - Move Android UI thread runnable queue from AndroidBridg…
Browse files Browse the repository at this point in the history
…e to AndroidUiThread r=jchen

MozReview-Commit-ID: 4okw7R2P2LC
  • Loading branch information
Randall Barker committed Jul 4, 2017
1 parent 882897a commit bffb537
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 134 deletions.
104 changes: 0 additions & 104 deletions widget/android/AndroidBridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ AndroidBridge::~AndroidBridge()
}

AndroidBridge::AndroidBridge()
: mUiTaskQueueLock("UiTaskQueue")
{
ALOG_BRIDGE("AndroidBridge::Init");

Expand Down Expand Up @@ -947,109 +946,6 @@ AndroidBridge::IsContentDocumentDisplayed(mozIDOMWindowProxy* aWindow)
return layerClient->IsContentDocumentDisplayed();
}

class AndroidBridge::DelayedTask
{
using TimeStamp = mozilla::TimeStamp;
using TimeDuration = mozilla::TimeDuration;

public:
DelayedTask(already_AddRefed<nsIRunnable> aTask)
: mTask(aTask)
, mRunTime() // Null timestamp representing no delay.
{}

DelayedTask(already_AddRefed<nsIRunnable> aTask, int aDelayMs)
: mTask(aTask)
, mRunTime(TimeStamp::Now() + TimeDuration::FromMilliseconds(aDelayMs))
{}

bool IsEarlierThan(const DelayedTask& aOther) const
{
if (mRunTime) {
return aOther.mRunTime ? mRunTime < aOther.mRunTime : false;
}
// In the case of no delay, we're earlier if aOther has a delay.
// Otherwise, we're not earlier, to maintain task order.
return !!aOther.mRunTime;
}

int64_t MillisecondsToRunTime() const
{
if (mRunTime) {
return int64_t((mRunTime - TimeStamp::Now()).ToMilliseconds());
}
return 0;
}

already_AddRefed<nsIRunnable> TakeTask()
{
return mTask.forget();
}

private:
nsCOMPtr<nsIRunnable> mTask;
const TimeStamp mRunTime;
};


void
AndroidBridge::PostTaskToUiThread(already_AddRefed<nsIRunnable> aTask, int aDelayMs)
{
// add the new task into the mUiTaskQueue, sorted with
// the earliest task first in the queue
size_t i;
DelayedTask newTask(aDelayMs ? DelayedTask(mozilla::Move(aTask), aDelayMs)
: DelayedTask(mozilla::Move(aTask)));

{
MutexAutoLock lock(mUiTaskQueueLock);

for (i = 0; i < mUiTaskQueue.Length(); i++) {
if (newTask.IsEarlierThan(mUiTaskQueue[i])) {
mUiTaskQueue.InsertElementAt(i, mozilla::Move(newTask));
break;
}
}

if (i == mUiTaskQueue.Length()) {
// We didn't insert the task, which means we should append it.
mUiTaskQueue.AppendElement(mozilla::Move(newTask));
}
}

if (i == 0) {
// if we're inserting it at the head of the queue, notify Java because
// we need to get a callback at an earlier time than the last scheduled
// callback
GeckoThread::RequestUiThreadCallback(int64_t(aDelayMs));
}
}

int64_t
AndroidBridge::RunDelayedUiThreadTasks()
{
MutexAutoLock lock(mUiTaskQueueLock);

while (!mUiTaskQueue.IsEmpty()) {
const int64_t timeLeft = mUiTaskQueue[0].MillisecondsToRunTime();
if (timeLeft > 0) {
// this task (and therefore all remaining tasks)
// have not yet reached their runtime. return the
// time left until we should be called again
return timeLeft;
}

// Retrieve task before unlocking/running.
nsCOMPtr<nsIRunnable> nextTask(mUiTaskQueue[0].TakeTask());
mUiTaskQueue.RemoveElementAt(0);

// Unlock to allow posting new tasks reentrantly.
MutexAutoUnlock unlock(mUiTaskQueueLock);
nextTask->Run();
}
return -1;
}

Object::LocalRef AndroidBridge::ChannelCreate(Object::Param stream) {
JNIEnv* const env = GetEnvForThread();
auto rv = Object::LocalRef::Adopt(env, env->CallStaticObjectMethod(
Expand Down
9 changes: 0 additions & 9 deletions widget/android/AndroidBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,15 +224,6 @@ class AndroidBridge final
jni::Object::GlobalRef mMessageQueue;
jfieldID mMessageQueueMessages;
jmethodID mMessageQueueNext;

private:
class DelayedTask;
nsTArray<DelayedTask> mUiTaskQueue;
mozilla::Mutex mUiTaskQueueLock;

public:
void PostTaskToUiThread(already_AddRefed<nsIRunnable> aTask, int aDelayMs);
int64_t RunDelayedUiThreadTasks();
};

class AutoJNIClass {
Expand Down
Loading

0 comments on commit bffb537

Please sign in to comment.