Bug 1399005: Always dispatch OnStop from the IO thread. r?mixedpuppy
Normally, we try to use the same thread for the IO and actor threads, which
means there's some basic assurance that OnStopRequest is always dispatched
after the last OnDataAvailable call. However, in cases where callers retarget
data delivery to a different background thread, it's possible for the main
thread to process the OnStopRequest runnable before the IO thread has
processed the last OnDataAvailable runnable, which can cause problems.
Dispatching the OnStop runnable through the IO thread guarantees at last basic
consistency in order of dispatch. In the case where the IO thread is the same
as the actor thread, the runnable is processed synchronously, and there's no
behavior change. In other cases, it's dispatched to the IO thread first, and
waits in the same queue as the already-dispatched OnDataAvailable events.
MozReview-Commit-ID: H2GD66WKxNn
--- a/toolkit/components/extensions/webrequest/StreamFilterParent.cpp
+++ b/toolkit/components/extensions/webrequest/StreamFilterParent.cpp
@@ -160,19 +160,23 @@ IPCResult
StreamFilterParent::RecvClose()
{
AssertIsActorThread();
mState = State::Closed;
if (!mSentStop) {
RefPtr<StreamFilterParent> self(this);
- RunOnMainThread(FUNC, [=] {
- nsresult rv = self->EmitStopRequest(NS_OK);
- Unused << NS_WARN_IF(NS_FAILED(rv));
+ // Make a trip through the IO thread to be sure OnStopRequest is emitted
+ // after the last OnDataAvailable event.
+ RunOnIOThread(FUNC, [=] {
+ RunOnMainThread(FUNC, [=] {
+ nsresult rv = self->EmitStopRequest(NS_OK);
+ Unused << NS_WARN_IF(NS_FAILED(rv));
+ });
});
}
Unused << SendClosed();
Destroy();
return IPC_OK();
}