Don't return a MozPromise when using async IPDL methods, it leads to out of order processing of events
Categories
(Core :: IPC, task, P3)
Tracking
()
Tracking | Status | |
---|---|---|
firefox78 | --- | fixed |
People
(Reporter: jya, Assigned: jya)
References
Details
Attachments
(13 files, 6 obsolete files)
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review |
SendXXX(...) can return a MozPromise. However, MozPromise::Then() always dispatch a task to run the callback.
This can lead to processing events out of order and intermittent issues due to races.
There's an additional binding that instead takes a resolve/reject callback instead to get around this issue.
I propose that we remove the MozPromise binding as it makes it easy to shoot yourself in the foot, and transition to the resolve/reject callback instead to make it easier to detect incorrect usage.
Additionally, I propose that we add an extra declaration similar to MozPromise::Then(..., [](MozPromise::ResolveOrRejectValue&& aValue) { ... }); which is useful when using move semantics or dealing with capturing non-refcounted objects
So you could do something like:
auto blah = MakeUnit<T1>(...);
SendBlah(..., [blah = std::move(blah)](Result<T2, nsresult>&& aValue) { ... });
Assignee | ||
Comment 1•5 years ago
|
||
Another alternative would be, if the target thread is the same as the IPDL thread, to dispatch a task via a microtask or tail dispatching
Comment 2•5 years ago
|
||
There was some discussion of the microtask option in bug 1514328.
Comment 3•5 years ago
|
||
The status of this bug is basically “patches welcome” — converting all of the existing promise-returning call sites to use callbacks is believed to be a nontrivial amount of work, none of the IPC peers have much time to spare, and there are things that are more urgently broken.
As far as anyone who's still here and working on IPC can recall, there doesn't seem to have been any deeply strategic reason to use promises vs. callbacks, other than that they seemed to be the popular way to express an eventually available value.
Assignee | ||
Comment 4•5 years ago
|
||
Assignee | ||
Comment 5•5 years ago
|
||
This wraps a main thread such that a call to Dispatch will be done as Tail Dispatch instead so that the task will be run in the current event loop.
Depends on D69994
Assignee | ||
Comment 6•5 years ago
|
||
Depends on D69995
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Assignee | ||
Comment 7•5 years ago
|
||
AbstractThread::MainThread() requires TailDispatcher to work which itself relies on the nsCycleCollectors to have been initialised.
This early in the XPCOM initilization, it doesn't work.
A bug was hiding the fact that the tail dispatcher wasn't available on the main thread by default.
Assignee | ||
Comment 8•5 years ago
|
||
prior bug 1364821, AbstractThread::GetCurrent() would always return AbstractThread::MainThread() when called from the main thread.
After this change, we had to run within an AutoEnter scope.
A hidden side effect of this change was that under most cases AbstractThread::MainThread::Dispatch() would no longer use the tail dispatcher to dispatch a task.
It can be safely assume that whenever you're on the main thread, the equivalent AbstractThread is usable.
As such, we revert this change, making AbstractThread::GetCurrent() always returning the main thread unless overridden locally.
Depends on D71147
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Comment 9•5 years ago
|
||
Comment on attachment 9140954 [details]
Bug 1592488 - P3. Make AbstractThread::GetCurrent() return MainThread by default. r?bholley
Revision D71148 was moved to bug 1630802. Setting attachment 9140954 [details] to obsolete.
Updated•5 years ago
|
Comment 10•5 years ago
|
||
Comment on attachment 9140953 [details]
Bug 1592488 - P2. Do not use AbstractThread too early. r?padenot
Revision D71147 was moved to bug 1630802. Setting attachment 9140953 [details] to obsolete.
Comment 11•5 years ago
|
||
Comment on attachment 9138810 [details]
Bug 1592488 - P1. Cleanup AbstractThread TLS lookup. r?gerald
Revision D69994 was moved to bug 1630802. Setting attachment 9138810 [details] to obsolete.
Assignee | ||
Comment 12•5 years ago
|
||
With bug 1631304, we'll be able to add an automatic dispatch via micro-task that wouldn't make us have to explicitly prevent the race from occurring.
Updated•5 years ago
|
Assignee | ||
Comment 13•5 years ago
|
||
If set, the callback will be run synchronously when the promise is resolved or rejected.
Assignee | ||
Comment 14•5 years ago
|
||
If set, the callback will be run synchronously when the promise is resolved or rejected.
Will dispatch a task via the microtask queue.
This mechanism is only available if both the caller and the target are on the main thread.
Depends on D71591
Assignee | ||
Comment 15•5 years ago
|
||
Fix intermittent issues due to races.
We now run the MozPromise generated by the IPDL bindings to run synchronously their callback.
This avoids a full trip to the back of the event queue for each additional asynchronous step when using MozPromise
The prevent unexpected racy behaviours when combining MozPromise with the other Resolve/Reject IPDL async declaration which was have lead to processing the events out of order.
Depends on D71592
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Assignee | ||
Comment 16•5 years ago
|
||
This is required for MozPromise's direct task dispatch to work.
It only needs to exist in the nsIThread.
Updated•5 years ago
|
Assignee | ||
Comment 17•5 years ago
|
||
Depends on D71592
Updated•5 years ago
|
Assignee | ||
Comment 18•5 years ago
|
||
This is necessary to ensure we can use IPC MozPromise that requires direct tasks dispatch.
Depends on D74165
Assignee | ||
Comment 19•5 years ago
|
||
This is necessary to ensure we can use IPC MozPromise that requires direct tasks dispatch.
Depends on D74592
Assignee | ||
Comment 20•5 years ago
|
||
This is necessary to ensure we can use IPC MozPromise that requires direct tasks dispatch.
Depends on D74593
Assignee | ||
Comment 21•5 years ago
|
||
This is necessary to ensure we can use IPC MozPromise with this target thread that requires direct tasks dispatch.
Depends on D74594
Updated•5 years ago
|
Updated•5 years ago
|
Assignee | ||
Comment 22•5 years ago
|
||
This is a step towards bug 1119864. However, at this stage we only need the cache thread to support direct task dispatch so that we can have IPDL MozPromise acting in a similar fashion to JS promise.
Assignee | ||
Comment 23•5 years ago
|
||
This will be useful to create a nsThread that provides an AbstractThread interface without creating a cycle.
Assignee | ||
Comment 24•5 years ago
|
||
As with P9; in order to be able to use MozPromise and direct task dispatching we need an AbstractThread to exist.
Depends on D74674
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Comment 25•5 years ago
|
||
Assignee | ||
Comment 26•5 years ago
|
||
Comment 27•5 years ago
|
||
Comment 28•5 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/74ff142216da
https://hg.mozilla.org/mozilla-central/rev/09f0c7ef9cd3
https://hg.mozilla.org/mozilla-central/rev/49ca05bab7e0
https://hg.mozilla.org/mozilla-central/rev/b703165595f6
https://hg.mozilla.org/mozilla-central/rev/0220b0ec625b
https://hg.mozilla.org/mozilla-central/rev/828152dfaed5
https://hg.mozilla.org/mozilla-central/rev/ad41d4a3dd8d
https://hg.mozilla.org/mozilla-central/rev/2ad003a3a954
https://hg.mozilla.org/mozilla-central/rev/11deef3eafe8
https://hg.mozilla.org/mozilla-central/rev/773d2ea52765
https://hg.mozilla.org/mozilla-central/rev/78b86c92bedc
https://hg.mozilla.org/mozilla-central/rev/4b0f7ee4f17d
https://hg.mozilla.org/mozilla-central/rev/63abdefd8f5b
Assignee | ||
Comment 29•4 years ago
|
||
This is required to break the cycle between the nsThread and the nsThreadManager and prevent leaks.
Assignee | ||
Comment 30•4 years ago
|
||
Comment on attachment 9158182 [details]
Bug 1592488 - P9.1 Ensure thread gets shutdown when DOMCache manager gets destroyed. r=baku
Beta/Release Uplift Approval Request
- User impact if declined: hundreds of unused threads leaking
- Is this code covered by automated tests?: No
- Has the fix been verified in Nightly?: No
- Needs manual test from QE?: No
- If yes, steps to reproduce:
- List of other uplifts needed: None
- Risk to taking this patch: Low
- Why is the change risky/not risky? (and alternatives if risky): We revert to the original code; only creating an associated AbstractThread to allow for direct task dispatching to work.
- String changes made/needed: none
Comment 31•4 years ago
|
||
Comment on attachment 9158182 [details]
Bug 1592488 - P9.1 Ensure thread gets shutdown when DOMCache manager gets destroyed. r=baku
Revision D80457 was moved to bug 1643690. Setting attachment 9158182 [details] to obsolete.
Description
•