[tbb-commits] [tor-browser] 55/311: Bug 1743671 - Keep worker threads alive while IOUtils tasks are running r=Gijs, asuth a=RyanVM

gitolite role git at cupani.torproject.org
Tue Apr 26 15:27:35 UTC 2022


This is an automated email from the git hooks/post-receive script.

pierov pushed a commit to branch geckoview-99.0.1-11.0-1
in repository tor-browser.

commit 7227342df73049980dd7c5a68e04a3b2928029b8
Author: Barret Rennie <barret at brennie.ca>
AuthorDate: Tue Feb 1 03:23:44 2022 +0000

    Bug 1743671 - Keep worker threads alive while IOUtils tasks are running r=Gijs,asuth a=RyanVM
    
    Differential Revision: https://phabricator.services.mozilla.com/D137465
---
 dom/system/IOUtils.cpp | 38 ++++++++++++++++++++++++++++++++------
 dom/system/IOUtils.h   | 18 ++++++++++++++++++
 2 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/dom/system/IOUtils.cpp b/dom/system/IOUtils.cpp
index 0de583060a92f..3f3db833f03ba 100644
--- a/dom/system/IOUtils.cpp
+++ b/dom/system/IOUtils.cpp
@@ -32,6 +32,8 @@
 #include "mozilla/Utf8.h"
 #include "mozilla/dom/IOUtilsBinding.h"
 #include "mozilla/dom/Promise.h"
+#include "mozilla/dom/WorkerCommon.h"
+#include "mozilla/dom/WorkerRef.h"
 #include "PathUtils.h"
 #include "nsCOMPtr.h"
 #include "nsError.h"
@@ -290,13 +292,21 @@ already_AddRefed<Promise> IOUtils::WithPromiseAndState(GlobalObject& aGlobal,
 template <typename OkT, typename Fn>
 void IOUtils::DispatchAndResolve(IOUtils::EventQueue* aQueue, Promise* aPromise,
                                  Fn aFunc) {
+  RefPtr<StrongWorkerRef> workerRef;
+  if (!NS_IsMainThread()) {
+    // We need to manually keep the worker alive until the promise returned by
+    // Dispatch() resolves or rejects.
+    workerRef = StrongWorkerRef::CreateForcibly(GetCurrentThreadWorkerPrivate(),
+                                                __func__);
+  }
+
   if (RefPtr<IOPromise<OkT>> p = aQueue->Dispatch<OkT, Fn>(std::move(aFunc))) {
     p->Then(
         GetCurrentSerialEventTarget(), __func__,
-        [promise = RefPtr(aPromise)](OkT&& ok) {
+        [workerRef, promise = RefPtr(aPromise)](OkT&& ok) {
           ResolveJSPromise(promise, std::forward<OkT>(ok));
         },
-        [promise = RefPtr(aPromise)](const IOError& err) {
+        [workerRef, promise = RefPtr(aPromise)](const IOError& err) {
           RejectJSPromise(promise, err);
         });
   }
@@ -393,6 +403,14 @@ already_AddRefed<Promise> IOUtils::ReadJSON(GlobalObject& aGlobal,
     nsCOMPtr<nsIFile> file = new nsLocalFile();
     REJECT_IF_INIT_PATH_FAILED(file, aPath, promise);
 
+    RefPtr<StrongWorkerRef> workerRef;
+    if (!NS_IsMainThread()) {
+      // We need to manually keep the worker alive until the promise returned by
+      // Dispatch() resolves or rejects.
+      workerRef = StrongWorkerRef::CreateForcibly(
+          GetCurrentThreadWorkerPrivate(), __func__);
+    }
+
     state->mEventQueue
         ->template Dispatch<JsBuffer>(
             [file, decompress = aOptions.mDecompress]() {
@@ -400,7 +418,7 @@ already_AddRefed<Promise> IOUtils::ReadJSON(GlobalObject& aGlobal,
             })
         ->Then(
             GetCurrentSerialEventTarget(), __func__,
-            [promise = RefPtr{promise}, file](JsBuffer&& aBuffer) {
+            [workerRef, promise = RefPtr{promise}, file](JsBuffer&& aBuffer) {
               AutoJSAPI jsapi;
               if (NS_WARN_IF(!jsapi.Init(promise->GetGlobalObject()))) {
                 promise->MaybeRejectWithUnknownError(
@@ -437,7 +455,7 @@ already_AddRefed<Promise> IOUtils::ReadJSON(GlobalObject& aGlobal,
 
               promise->MaybeResolve(val);
             },
-            [promise = RefPtr{promise}](const IOError& aErr) {
+            [workerRef, promise = RefPtr{promise}](const IOError& aErr) {
               RejectJSPromise(promise, aErr);
             });
   });
@@ -721,13 +739,21 @@ already_AddRefed<Promise> IOUtils::GetWindowsAttributes(
     nsCOMPtr<nsIFile> file = new nsLocalFile();
     REJECT_IF_INIT_PATH_FAILED(file, aPath, promise);
 
+    RefPtr<StrongWorkerRef> workerRef;
+    if (!NS_IsMainThread()) {
+      // We need to manually keep the worker alive until the promise returned by
+      // Dispatch() resolves or rejects.
+      workerRef = StrongWorkerRef::CreateForcibly(
+          GetCurrentThreadWorkerPrivate(), __func__);
+    }
+
     state->mEventQueue
         ->template Dispatch<uint32_t>([file = std::move(file)]() {
           return GetWindowsAttributesSync(file);
         })
         ->Then(
             GetCurrentSerialEventTarget(), __func__,
-            [promise = RefPtr{promise}](const uint32_t aAttrs) {
+            [workerRef, promise = RefPtr{promise}](const uint32_t aAttrs) {
               WindowsFileAttributes attrs;
 
               attrs.mReadOnly.Construct(aAttrs & FILE_ATTRIBUTE_READONLY);
@@ -736,7 +762,7 @@ already_AddRefed<Promise> IOUtils::GetWindowsAttributes(
 
               promise->MaybeResolve(attrs);
             },
-            [promise = RefPtr{promise}](const IOError& aErr) {
+            [workerRef, promise = RefPtr{promise}](const IOError& aErr) {
               RejectJSPromise(promise, aErr);
             });
   });
diff --git a/dom/system/IOUtils.h b/dom/system/IOUtils.h
index ef5d84e00c00f..064fb9467f48f 100644
--- a/dom/system/IOUtils.h
+++ b/dom/system/IOUtils.h
@@ -189,6 +189,9 @@ class IOUtils final {
    * Dispatch a task on the event queue and resolve or reject the associated
    * promise based on the result.
    *
+   * NB: If the calling thread is a worker, this function takes care of keepting
+   *     it alive until the |IOPromise| can complete.
+   *
    * @param aPromise The promise corresponding to the task running on the event
    * queue.
    * @param aFunc The task to run.
@@ -486,6 +489,21 @@ class IOUtils::EventQueue final {
   EventQueue& operator=(const EventQueue&) = delete;
   EventQueue& operator=(EventQueue&&) = delete;
 
+  /**
+   * Dispatch a task on the event queue.
+   *
+   * NB: If using this directly from |IOUtils| instead of
+   *     |IOUtils::DispatchAndResolve| *and* the calling thread is a worker, you
+   *     *must* take care to keep the worker thread alive until the |IOPromise|
+   *     resolves or rejects. See the implementation of
+   *     |IOUtils::DispatchAndResolve| or |IOUtils::GetWindowsAttributes| for an
+   *     example.
+   *
+   * @param aFunc The task to dispatch on the event queue.
+   *
+   * @return A promise that resolves to the task's return value or rejects with
+   *         an error.
+   */
   template <typename OkT, typename Fn>
   RefPtr<IOPromise<OkT>> Dispatch(Fn aFunc);
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tbb-commits mailing list