Index: Source/modules/crypto/CryptoResultImpl.h |
diff --git a/Source/modules/crypto/CryptoResultImpl.h b/Source/modules/crypto/CryptoResultImpl.h |
index b6cb6e90126c8290fdfbbd3a2172afc230868247..a54e1d8364d04a78d63bb70bfb21ad3fe3f7d87f 100644 |
--- a/Source/modules/crypto/CryptoResultImpl.h |
+++ b/Source/modules/crypto/CryptoResultImpl.h |
@@ -40,7 +40,6 @@ |
namespace blink { |
-class ScriptPromiseResolver; |
MODULES_EXPORT ExceptionCode webCryptoErrorToExceptionCode(WebCryptoErrorType); |
// Wrapper around a Promise to notify completion of the crypto operation. |
@@ -49,41 +48,72 @@ MODULES_EXPORT ExceptionCode webCryptoErrorToExceptionCode(WebCryptoErrorType); |
// "origin thread". |
// |
// * At creation time there must be an active ExecutionContext. |
-// * The CryptoResult interface must only be called from the origin thread. |
-// * ref(), deref(), cancelled() and cancel() can be called from any thread. |
+// * All methods of the CryptoResult implementation must be called from |
+// the origin thread. The exception is that ref(), deref(), and |
+// destruction may happen on another thread. |
// * One of the completeWith***() functions must be called, or the |
// m_resolver will be leaked until the ExecutionContext is destroyed. |
class CryptoResultImpl final : public CryptoResult { |
public: |
- ~CryptoResultImpl(); |
- |
static PassRefPtrWillBeRawPtr<CryptoResultImpl> create(ScriptState*); |
+ ~CryptoResultImpl(); |
+ |
void completeWithError(WebCryptoErrorType, const WebString&) override; |
void completeWithBuffer(const void* bytes, unsigned bytesSize) override; |
void completeWithJson(const char* utf8Data, unsigned length) override; |
void completeWithBoolean(bool) override; |
void completeWithKey(const WebCryptoKey&) override; |
void completeWithKeyPair(const WebCryptoKey& publicKey, const WebCryptoKey& privateKey) override; |
- bool cancelled() const override; |
// If called after completion (including cancellation) will return an empty |
// ScriptPromise. |
ScriptPromise promise(); |
+ WebCryptoResult result() |
+ { |
+ return WebCryptoResult(this, m_cancel.get()); |
+ } |
+ |
+ DECLARE_VIRTUAL_TRACE(); |
+ |
private: |
class Resolver; |
+ class ResultCancel : public CryptoResultCancel { |
+ public: |
+ static PassRefPtr<ResultCancel> create() |
+ { |
+ return adoptRef(new ResultCancel); |
+ } |
+ |
+ bool cancelled() const override; |
+ |
+ void cancel(); |
+ private: |
+ ResultCancel(); |
+ |
+ int m_cancelled; |
+ }; |
+ |
explicit CryptoResultImpl(ScriptState*); |
- void clearResolver(); |
void cancel(); |
+ void clearResolver(); |
+ |
+ RawPtrWillBeMember<Resolver> m_resolver; |
- // FIXME: ScriptPromiseResolver should not be exported. |
- // Instead, use ScriptPromise. |
- ScriptPromiseResolver* m_resolver; |
- volatile int m_cancelled; |
+ // Separately communicate cancellation to WebCryptoResults so as to |
+ // allow this result object, which will be on the Oilpan heap, to be |
+ // GCed and destructed as needed. That is, it may end being GCed while |
+ // the thread owning the heap is detached and shut down, which will |
+ // in some cases happen before corresponding webcrypto operations have |
+ // all been processed. Hence these webcrypto operations cannot reliably |
+ // check cancellation status via this result object. So, keep a separate |
+ // cancellation status object for the purpose, which will outlive the |
+ // result object and can be safely accessed by multiple threads. |
+ RefPtr<ResultCancel> m_cancel; |
}; |
} // namespace blink |
-#endif |
+#endif // CryptoResultImpl_h |