[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