Index: Source/modules/crypto/CryptoOperation.h |
diff --git a/Source/modules/crypto/CryptoOperation.h b/Source/modules/crypto/CryptoOperation.h |
index 79e79a6c882b820b8226c5d01c00dc06f565f424..85446db3137421c912c0b5a583bd368fc5b70e1f 100644 |
--- a/Source/modules/crypto/CryptoOperation.h |
+++ b/Source/modules/crypto/CryptoOperation.h |
@@ -38,35 +38,60 @@ |
#include "public/platform/WebCryptoAlgorithm.h" |
#include "wtf/Forward.h" |
#include "wtf/PassRefPtr.h" |
-#include "wtf/RefCounted.h" |
+#include "wtf/ThreadSafeRefCounted.h" |
namespace WebCore { |
class ScriptPromiseResolver; |
class ExceptionState; |
-class CryptoOperation : public ScriptWrappable, public WebKit::WebCryptoOperationResult, public RefCounted<CryptoOperation> { |
+typedef int ExceptionCode; |
+ |
+// CryptoOperation vs CryptoOperationImpl: |
+// |
+// A CryptoOperation corresponds with the request from JavaScript to start a |
+// multi-part cryptographic operation. This is forwarded to the Platform layer, |
+// which creates a WebCryptoOperation. When the WebCryptoOperation eventually |
+// completes, it resolves a Promise. |
+// |
+// To avoid a reference cycle between WebCryptoOperation and CryptoOperation, |
+// WebCryptoOperation's result handle holds a reference to |
+// CryptoOperationImpl rather than CryptoOperation. This prevents extending the |
+// lifetime of CryptoOperation beyond JavaScript garbage collection, which is |
+// important since: |
+// |
+// * When JavaScript garbage collects CryptoOperation and finish() has NOT |
+// been called on it, the Platform operation can no longer complete and |
+// should therefore be aborted. |
+// * The WebCryptoOperation may outlive CryptoOperation if finish() was |
+// called, as the result is delivered to a separate Promise (this is |
+// different than what the current version of the spec says). |
+ |
+class CryptoOperationImpl : public WebKit::WebCryptoOperationResultPrivate, public ThreadSafeRefCounted<CryptoOperationImpl> { |
public: |
- ~CryptoOperation(); |
- static PassRefPtr<CryptoOperation> create(const WebKit::WebCryptoAlgorithm&, ExceptionState*); |
+ static PassRefPtr<CryptoOperationImpl> create() { return adoptRef(new CryptoOperationImpl); } |
- CryptoOperation* process(ArrayBuffer* data); |
- CryptoOperation* process(ArrayBufferView* data); |
+ bool throwInitializationError(ExceptionState&); |
+ |
+ // The CryptoOperation which started the request is getting destroyed. |
+ void detach(); |
+ |
+ void process(const void* bytes, size_t); |
ScriptObject finish(); |
ScriptObject abort(); |
- Algorithm* algorithm(); |
- |
- // Implementation of WebKit::WebCryptoOperationResult. |
+ // WebCryptoOperationResultPrivate implementation. |
virtual void initializationFailed() OVERRIDE; |
- virtual void initializationSucceded(WebKit::WebCryptoOperation*) OVERRIDE; |
+ virtual void initializationSucceeded(WebKit::WebCryptoOperation*) OVERRIDE; |
virtual void completeWithError() OVERRIDE; |
virtual void completeWithArrayBuffer(const WebKit::WebArrayBuffer&) OVERRIDE; |
+ virtual void ref() OVERRIDE; |
+ virtual void deref() OVERRIDE; |
private: |
enum State { |
- // Constructing the WebCryptoOperation. |
+ // Constructing the WebCryptoOperationImpl. |
Initializing, |
// Accepting calls to process(). |
@@ -82,24 +107,39 @@ private: |
Done, |
}; |
- CryptoOperation(const WebKit::WebCryptoAlgorithm&, ExceptionState*); |
- |
- void process(const unsigned char*, size_t); |
- |
- // Aborts and clears m_impl. If the operation has already comleted then |
- // returns false. |
- bool abortImpl(); |
+ CryptoOperationImpl(); |
ScriptPromiseResolver* promiseResolver(); |
- WebKit::WebCryptoAlgorithm m_algorithm; |
- WebKit::WebCryptoOperation* m_impl; |
- RefPtr<Algorithm> m_algorithmNode; |
State m_state; |
+ WebKit::WebCryptoOperation* m_impl; |
RefPtr<ScriptPromiseResolver> m_promiseResolver; |
+ ExceptionCode m_initializationError; |
+}; |
+ |
+class CryptoOperation : public ScriptWrappable, public RefCounted<CryptoOperation> { |
+public: |
+ ~CryptoOperation(); |
+ static PassRefPtr<CryptoOperation> create(const WebKit::WebCryptoAlgorithm&, CryptoOperationImpl*); |
+ |
+ CryptoOperation* process(ArrayBuffer* data); |
+ CryptoOperation* process(ArrayBufferView* data); |
+ |
+ ScriptObject finish(); |
+ ScriptObject abort(); |
+ |
+ Algorithm* algorithm(); |
+ |
+ CryptoOperationImpl* impl() { return m_impl.get(); } |
+ |
+private: |
+ explicit CryptoOperation(const WebKit::WebCryptoAlgorithm&, CryptoOperationImpl*); |
+ |
+ WebKit::WebCryptoAlgorithm m_algorithm; |
+ RefPtr<Algorithm> m_algorithmNode; |
- ExceptionState* m_exceptionState; |
+ RefPtr<CryptoOperationImpl> m_impl; |
}; |
} // namespace WebCore |