Bug 1454038 - 3. Reject sendRequestForResult promise on finalize; r?esawin
When a sendRequestForResult event callback is finalized, automatically
reject the promise (if it has not been resolved yet). This means if the
callback is never called, or if the communication link is disrupted, we
will end up with a rejected promise rather than a forever-pending
promise.
MozReview-Commit-ID: A1w19vwFxuT
--- a/mobile/android/modules/geckoview/Messaging.jsm
+++ b/mobile/android/modules/geckoview/Messaging.jsm
@@ -107,20 +107,31 @@ DispatcherDelegate.prototype = {
* @param aMsg Message to send; must be an object with a "type" property
* @return A Promise resolving to the response
*/
sendRequestForResult: function(aMsg) {
return new Promise((resolve, reject) => {
const type = aMsg.type;
aMsg.type = undefined;
- this.dispatch(type, aMsg, {
- onSuccess: resolve,
- onError: reject,
- });
+ // Manually release the resolve/reject functions after one callback is
+ // received, so the JS GC is not tied up with the Java GC.
+ const onCallback = (callback, ...args) => {
+ if (callback) {
+ callback(...args);
+ }
+ resolve = undefined;
+ reject = undefined;
+ };
+ const callback = {
+ onSuccess: result => onCallback(resolve, result),
+ onError: error => onCallback(reject, error),
+ onFinalize: _ => onCallback(reject),
+ };
+ this.dispatch(type, aMsg, callback, callback);
});
},
finalize: function() {
if (!this._replies) {
return;
}
this._replies.forEach(reply => {