Bug 1632283: Part 2 - Add task to drain WebGL async Ipdl queue r=jgilbert

When an async message is buffered, we need to make sure that the message is eventually sent to avoid starvation.  This patch queues a future task to do this (currently, randomly, 4 milliseconds in the future) unless one is already queued.  The task may get scooped by a sync message or user call to FlushAsyncCache, in which case the task will have no effect.

Differential Revision: https://phabricator.services.mozilla.com/D74482
This commit is contained in:
David Parks 2020-06-01 22:33:12 +00:00
parent 66aa1517ba
commit 7957e0f9fa

View File

@ -87,6 +87,8 @@ using IpdlQueueBuffers = nsTArray<IpdlQueueBuffer>;
// TODO: Base this on something.
static constexpr size_t kMaxIpdlQueueArgSize = 256 * 1024;
static constexpr uint32_t kAsyncFlushWaitMs = 4; // 4ms
template <typename Derived>
class AsyncProducerActor {
public:
@ -109,6 +111,10 @@ class AsyncProducerActor {
}
}
buffers.AppendElement(std::move(aData));
if (!mResponseBuffers) {
PostFlushAsyncCache(kAsyncFlushWaitMs);
}
return true;
}
@ -134,6 +140,38 @@ class AsyncProducerActor {
return true;
}
bool PostFlushAsyncCache(uint32_t aEstWaitTimeMs) {
if (mPostedFlushRunnable) {
// Already scheduled a flush for later.
return true;
}
if (!MessageLoop::current()) {
NS_WARNING("No message loop for IpdlQueue flush task");
return false;
}
Derived* self = static_cast<Derived*>(this);
// IpdlProducer/IpdlConsumer guarantees the actor supports WeakPtr.
auto weak = WeakPtr<Derived>(self);
already_AddRefed<mozilla::Runnable> flushRunnable =
NS_NewRunnableFunction("FlushAsyncCache", [weak] {
auto strong = RefPtr<Derived>(weak);
if (!strong) {
return;
}
strong->FlushAsyncCache();
strong->ClearFlushRunnable();
});
MessageLoop::current()->PostDelayedTask(std::move(flushRunnable),
aEstWaitTimeMs);
mPostedFlushRunnable = true;
return true;
}
void ClearFlushRunnable() { mPostedFlushRunnable = false; }
template <typename... Args>
IpdlQueueProtocol GetIpdlQueueProtocol(const Args&...) {
return IpdlQueueProtocol::kAsync;
@ -160,6 +198,8 @@ class AsyncProducerActor {
// For kBufferedAsync transmissions that occur outside of a response to a
// kSync message.
IpdlQueueBuffers mAsyncBuffers;
bool mPostedFlushRunnable = false;
};
template <typename Derived>