Bug 1399005: Always dispatch OnStop from the IO thread. r?mixedpuppy draft
authorKris Maglione <maglione.k@gmail.com>
Mon, 11 Sep 2017 20:04:48 -0700
changeset 663148 03406f5793edca2f52b6c9f8a166f0c281780800
parent 662825 827ea05cc1cbe8cee8d7c3059bc8d5786c72ee90
child 731120 d2f215cec33610c30fb29384c65a7f7d3d8a9472
push id79349
push usermaglione.k@gmail.com
push dateTue, 12 Sep 2017 18:44:43 +0000
reviewersmixedpuppy
bugs1399005
milestone57.0a1
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
toolkit/components/extensions/webrequest/StreamFilterParent.cpp
--- 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();
 }