tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DOMMozPromiseRequestHolder.h (3771B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_DOMMozPromiseRequestHolder_h
      8 #define mozilla_dom_DOMMozPromiseRequestHolder_h
      9 
     10 #include "mozilla/DOMEventTargetHelper.h"
     11 #include "mozilla/MozPromise.h"
     12 
     13 namespace mozilla::dom {
     14 
     15 /**
     16 * This is a helper class that can be used when MozPromises are
     17 * being consumed by binding layer code.  It effectively creates
     18 * a MozPromiseRequestHolder that auto-disconnects when the binding's
     19 * global is disconnected.
     20 *
     21 * It can be used like this:
     22 *
     23 *    RefPtr<Promise>
     24 *    SomeAsyncAPI(Args& aArgs, ErrorResult& aRv)
     25 *    {
     26 *      nsIGlobalObject* global = GetParentObject();
     27 *      if (!global) {
     28 *        aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     29 *        return nullptr;
     30 *      }
     31 *
     32 *      RefPtr<Promise> outer = Promise::Create(global, aRv);
     33 *      if (aRv.Failed()) {
     34 *        return nullptr;
     35 *      }
     36 *
     37 *      RefPtr<DOMMozPromiseRequestHolder> holder =
     38 *        new DOMMozPromiseRequestHolder(global);
     39 *
     40 *      DoAsyncStuff()->Then(
     41 *        global->EventTargetFor(TaskCategory::Other), __func__,
     42 *        [holder, outer] (const Result& aResult) {
     43 *          holder->Complete();
     44 *
     45 *          // Note, you can access the holder's bound global in
     46 *          // your reaction handler.  Its mostly likely set if
     47 *          // the handler fires, but you still must check for
     48 *          // its existence since something could disconnect
     49 *          // the global between when the MozPromise reaction
     50 *          // runnable is queued and when it actually runs.
     51 *          nsIGlobalObject* global = holder->GetParentObject();
     52 *          NS_ENSURE_TRUE_VOID(global);
     53 *
     54 *          outer->MaybeResolve(aResult);
     55 *        }, [holder, outer] (nsresult aRv) {
     56 *          holder->Complete();
     57 *          outer->MaybeReject(aRv);
     58 *        })->Track(*holder);
     59 *
     60 *      return outer.forget();
     61 *    }
     62 *
     63 * NOTE: Currently this helper class extends DETH.  This is only
     64 *       so that it can bind to the global and receive the
     65 *       DisconnectFromOwner() method call.  In this future the
     66 *       binding code should be factored out so DETH is not
     67 *       needed here.  See bug 1456893.
     68 */
     69 template <typename PromiseType>
     70 class DOMMozPromiseRequestHolder final : public DOMEventTargetHelper {
     71  MozPromiseRequestHolder<PromiseType> mHolder;
     72 
     73  ~DOMMozPromiseRequestHolder() = default;
     74 
     75  void DisconnectFromOwner() override {
     76    mHolder.DisconnectIfExists();
     77    DOMEventTargetHelper::DisconnectFromOwner();
     78  }
     79 
     80  JSObject* WrapObject(JSContext* aCx,
     81                       JS::Handle<JSObject*> aGivenProto) override {
     82    // We are extending DETH to get notified when the global goes
     83    // away, but this object should never actually be exposed to
     84    // script.
     85    MOZ_CRASH("illegal method");
     86  }
     87 
     88 public:
     89  explicit DOMMozPromiseRequestHolder(nsIGlobalObject* aGlobal)
     90      : DOMEventTargetHelper(aGlobal) {
     91    MOZ_DIAGNOSTIC_ASSERT(aGlobal);
     92  }
     93 
     94  operator MozPromiseRequestHolder<PromiseType>&() { return mHolder; }
     95 
     96  operator const MozPromiseRequestHolder<PromiseType>&() const {
     97    return mHolder;
     98  }
     99 
    100  void Complete() { mHolder.Complete(); }
    101 
    102  void DisconnectIfExists() { mHolder.DisconnectIfExists(); }
    103 
    104  bool Exists() const { return mHolder.Exists(); }
    105 
    106  NS_INLINE_DECL_REFCOUNTING_INHERITED(DOMMozPromiseRequestHolder,
    107                                       DOMEventTargetHelper)
    108 };
    109 
    110 }  // namespace mozilla::dom
    111 
    112 #endif  // mozilla_dom_DOMMozPromiseRequestHolder_h