Bug 1385313 - Use MozPromiseRequestHolders in U2FTokenManager r=jcj
authorTim Taubert <ttaubert@mozilla.com>
Fri, 28 Jul 2017 17:11:03 +0200
changeset 420428 f78bdc8e529b898112a505e1905b4c7a7c66bf66
parent 420427 ee929726e09380236f2c8c5ba8eabc120c8a8cfd
child 420429 7c9e0fb89d84cf4a12e7635239d06b890867df69
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjcj
bugs1385313
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1385313 - Use MozPromiseRequestHolders in U2FTokenManager r=jcj
dom/webauthn/U2FTokenManager.cpp
dom/webauthn/U2FTokenManager.h
--- a/dom/webauthn/U2FTokenManager.cpp
+++ b/dom/webauthn/U2FTokenManager.cpp
@@ -153,27 +153,16 @@ U2FTokenManager::Get()
 {
   MOZ_ASSERT(XRE_IsParentProcess());
   // We should only be accessing this on the background thread
   MOZ_ASSERT(!NS_IsMainThread());
   return gU2FTokenManager;
 }
 
 void
-U2FTokenManager::MaybeAbortTransaction(uint64_t aTransactionId,
-                                       const nsresult& aError)
-{
-  if (mTransactionId != aTransactionId) {
-    return;
-  }
-
-  AbortTransaction(aError);
-}
-
-void
 U2FTokenManager::AbortTransaction(const nsresult& aError)
 {
   Unused << mTransactionParent->SendCancel(aError);
   ClearTransaction();
 }
 
 void
 U2FTokenManager::MaybeClearTransaction(WebAuthnTransactionParent* aParent)
@@ -186,26 +175,28 @@ U2FTokenManager::MaybeClearTransaction(W
 }
 
 void
 U2FTokenManager::ClearTransaction()
 {
   mTransactionParent = nullptr;
   // Drop managers at the end of all transactions
   mTokenManagerImpl = nullptr;
-  // Drop promises.
-  mRegisterPromise = nullptr;
-  mSignPromise = nullptr;
-  // Increase in case we're called by the WebAuthnTransactionParent.
+  // Forget promises, if necessary.
+  mRegisterPromise.DisconnectIfExists();
+  mSignPromise.DisconnectIfExists();
+  // Bump transaction id.
   mTransactionId++;
 }
 
 RefPtr<U2FTokenTransport>
 U2FTokenManager::GetTokenManagerImpl()
 {
+  MOZ_ASSERT(U2FPrefManager::Get());
+
   if (mTokenManagerImpl) {
     return mTokenManagerImpl;
   }
 
   auto pm = U2FPrefManager::Get();
   bool useSoftToken = pm->GetSoftTokenEnabled();
   bool useUsbToken = pm->GetUsbTokenEnabled();
 
@@ -226,19 +217,18 @@ U2FTokenManager::GetTokenManagerImpl()
   return new U2FHIDTokenManager();
 }
 
 void
 U2FTokenManager::Register(WebAuthnTransactionParent* aTransactionParent,
                           const WebAuthnTransactionInfo& aTransactionInfo)
 {
   MOZ_LOG(gU2FTokenManagerLog, LogLevel::Debug, ("U2FAuthRegister"));
-  MOZ_ASSERT(U2FPrefManager::Get());
 
-  uint64_t tid = ++mTransactionId;
+  ClearTransaction();
   mTransactionParent = aTransactionParent;
   mTokenManagerImpl = GetTokenManagerImpl();
 
   if (!mTokenManagerImpl) {
     AbortTransaction(NS_ERROR_DOM_NOT_ALLOWED_ERR);
     return;
   }
 
@@ -247,107 +237,137 @@ U2FTokenManager::Register(WebAuthnTransa
   // UnknownError and terminate the operation.
 
   if ((aTransactionInfo.RpIdHash().Length() != SHA256_LENGTH) ||
       (aTransactionInfo.ClientDataHash().Length() != SHA256_LENGTH)) {
     AbortTransaction(NS_ERROR_DOM_UNKNOWN_ERR);
     return;
   }
 
-  mRegisterPromise = mTokenManagerImpl->Register(aTransactionInfo.Descriptors(),
-                                                 aTransactionInfo.RpIdHash(),
-                                                 aTransactionInfo.ClientDataHash(),
-                                                 aTransactionInfo.TimeoutMS());
-
-  mRegisterPromise->Then(GetCurrentThreadSerialEventTarget(), __func__,
+  uint64_t tid = mTransactionId;
+  mTokenManagerImpl->Register(aTransactionInfo.Descriptors(),
+                              aTransactionInfo.RpIdHash(),
+                              aTransactionInfo.ClientDataHash(),
+                              aTransactionInfo.TimeoutMS())
+                   ->Then(GetCurrentThreadSerialEventTarget(), __func__,
                          [tid](U2FRegisterResult&& aResult) {
                            U2FTokenManager* mgr = U2FTokenManager::Get();
                            mgr->MaybeConfirmRegister(tid, aResult);
                          },
                          [tid](nsresult rv) {
                            MOZ_ASSERT(NS_FAILED(rv));
                            U2FTokenManager* mgr = U2FTokenManager::Get();
-                           mgr->MaybeAbortTransaction(tid, rv);
-                         });
+                           mgr->MaybeAbortRegister(tid, rv);
+                         })
+                   ->Track(mRegisterPromise);
 }
 
 void
 U2FTokenManager::MaybeConfirmRegister(uint64_t aTransactionId,
                                       U2FRegisterResult& aResult)
 {
   if (mTransactionId != aTransactionId) {
     return;
   }
 
+  mRegisterPromise.Complete();
+
   nsTArray<uint8_t> registration;
   aResult.ConsumeRegistration(registration);
 
   Unused << mTransactionParent->SendConfirmRegister(registration);
   ClearTransaction();
 }
 
 void
+U2FTokenManager::MaybeAbortRegister(uint64_t aTransactionId,
+                                    const nsresult& aError)
+{
+  if (mTransactionId != aTransactionId) {
+    return;
+  }
+
+  mRegisterPromise.Complete();
+  AbortTransaction(aError);
+}
+
+void
 U2FTokenManager::Sign(WebAuthnTransactionParent* aTransactionParent,
                       const WebAuthnTransactionInfo& aTransactionInfo)
 {
   MOZ_LOG(gU2FTokenManagerLog, LogLevel::Debug, ("U2FAuthSign"));
-  MOZ_ASSERT(U2FPrefManager::Get());
 
-  uint64_t tid = ++mTransactionId;
+  ClearTransaction();
   mTransactionParent = aTransactionParent;
   mTokenManagerImpl = GetTokenManagerImpl();
 
   if (!mTokenManagerImpl) {
     AbortTransaction(NS_ERROR_DOM_NOT_ALLOWED_ERR);
     return;
   }
 
   if ((aTransactionInfo.RpIdHash().Length() != SHA256_LENGTH) ||
       (aTransactionInfo.ClientDataHash().Length() != SHA256_LENGTH)) {
     AbortTransaction(NS_ERROR_DOM_UNKNOWN_ERR);
     return;
   }
 
-  mSignPromise = mTokenManagerImpl->Sign(aTransactionInfo.Descriptors(),
-                                         aTransactionInfo.RpIdHash(),
-                                         aTransactionInfo.ClientDataHash(),
-                                         aTransactionInfo.TimeoutMS());
-
-  mSignPromise->Then(GetCurrentThreadSerialEventTarget(), __func__,
+  uint64_t tid = mTransactionId;
+  mTokenManagerImpl->Sign(aTransactionInfo.Descriptors(),
+                          aTransactionInfo.RpIdHash(),
+                          aTransactionInfo.ClientDataHash(),
+                          aTransactionInfo.TimeoutMS())
+                   ->Then(GetCurrentThreadSerialEventTarget(), __func__,
                      [tid](U2FSignResult&& aResult) {
                        U2FTokenManager* mgr = U2FTokenManager::Get();
                        mgr->MaybeConfirmSign(tid, aResult);
                      },
                      [tid](nsresult rv) {
                        MOZ_ASSERT(NS_FAILED(rv));
                        U2FTokenManager* mgr = U2FTokenManager::Get();
-                       mgr->MaybeAbortTransaction(tid, rv);
-                     });
+                       mgr->MaybeAbortSign(tid, rv);
+                     })
+                   ->Track(mSignPromise);
 }
 
 void
 U2FTokenManager::MaybeConfirmSign(uint64_t aTransactionId,
                                   U2FSignResult& aResult)
 {
   if (mTransactionId != aTransactionId) {
     return;
   }
 
+  mSignPromise.Complete();
+
   nsTArray<uint8_t> keyHandle;
   aResult.ConsumeKeyHandle(keyHandle);
   nsTArray<uint8_t> signature;
   aResult.ConsumeSignature(signature);
 
   Unused << mTransactionParent->SendConfirmSign(keyHandle, signature);
   ClearTransaction();
 }
 
 void
+U2FTokenManager::MaybeAbortSign(uint64_t aTransactionId, const nsresult& aError)
+{
+  if (mTransactionId != aTransactionId) {
+    return;
+  }
+
+  mSignPromise.Complete();
+  AbortTransaction(aError);
+}
+
+void
 U2FTokenManager::Cancel(WebAuthnTransactionParent* aParent)
 {
-  if (mTransactionParent == aParent) {
-    mTokenManagerImpl->Cancel();
-    ClearTransaction();
+  if (mTransactionParent != aParent) {
+    return;
   }
+
+  mTokenManagerImpl->Cancel();
+  ClearTransaction();
 }
 
 }
 }
--- a/dom/webauthn/U2FTokenManager.h
+++ b/dom/webauthn/U2FTokenManager.h
@@ -44,28 +44,28 @@ public:
   void MaybeClearTransaction(WebAuthnTransactionParent* aParent);
   static void Initialize();
 private:
   U2FTokenManager();
   ~U2FTokenManager();
   RefPtr<U2FTokenTransport> GetTokenManagerImpl();
   void AbortTransaction(const nsresult& aError);
   void ClearTransaction();
-  void MaybeAbortTransaction(uint64_t aTransactionId,
-                             const nsresult& aError);
   void MaybeConfirmRegister(uint64_t aTransactionId,
                             U2FRegisterResult& aResult);
+  void MaybeAbortRegister(uint64_t aTransactionId, const nsresult& aError);
   void MaybeConfirmSign(uint64_t aTransactionId, U2FSignResult& aResult);
+  void MaybeAbortSign(uint64_t aTransactionId, const nsresult& aError);
   // Using a raw pointer here, as the lifetime of the IPC object is managed by
   // the PBackground protocol code. This means we cannot be left holding an
   // invalid IPC protocol object after the transaction is finished.
   WebAuthnTransactionParent* mTransactionParent;
   RefPtr<U2FTokenTransport> mTokenManagerImpl;
-  RefPtr<U2FRegisterPromise> mRegisterPromise;
-  RefPtr<U2FSignPromise> mSignPromise;
+  MozPromiseRequestHolder<U2FRegisterPromise> mRegisterPromise;
+  MozPromiseRequestHolder<U2FSignPromise> mSignPromise;
   // Guards the asynchronous promise resolution of token manager impls.
   // We don't need to protect this with a lock as it will only be modified
   // and checked on the PBackground thread in the parent process.
   uint64_t mTransactionId;
 };
 
 } // namespace dom
 } // namespace mozilla