Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(362)

Side by Side Diff: Source/modules/crypto/CryptoResultImpl.cpp

Issue 253563002: [webcrypto] Make it safe to delete WebCryptoResult from any thread. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/modules/crypto/CryptoResultImpl.h ('k') | Source/platform/CryptoResult.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 15 matching lines...) Expand all
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 #include "modules/crypto/CryptoResultImpl.h" 32 #include "modules/crypto/CryptoResultImpl.h"
33 33
34 #include "bindings/v8/NewScriptState.h" 34 #include "bindings/v8/NewScriptState.h"
35 #include "bindings/v8/ScriptPromiseResolverWithContext.h" 35 #include "bindings/v8/ScriptPromiseResolverWithContext.h"
36 #include "core/dom/ContextLifecycleObserver.h"
36 #include "core/dom/ExecutionContext.h" 37 #include "core/dom/ExecutionContext.h"
37 #include "modules/crypto/Key.h" 38 #include "modules/crypto/Key.h"
38 #include "modules/crypto/KeyPair.h" 39 #include "modules/crypto/KeyPair.h"
39 #include "modules/crypto/NormalizeAlgorithm.h" 40 #include "modules/crypto/NormalizeAlgorithm.h"
40 #include "public/platform/Platform.h" 41 #include "public/platform/Platform.h"
41 #include "public/platform/WebArrayBuffer.h" 42 #include "public/platform/WebArrayBuffer.h"
42 #include "public/platform/WebCryptoAlgorithm.h" 43 #include "public/platform/WebCryptoAlgorithm.h"
43 #include "wtf/ArrayBufferView.h" 44 #include "wtf/ArrayBufferView.h"
44 45
45 namespace WebCore { 46 namespace WebCore {
46 47
48 // The PromiseState class contains all the state which is tied to an
49 // ExecutionContext. Whereas CryptoResultImpl can be deleted from any thread,
50 // PromiseState is not thread safe and must only be accessed and deleted from
51 // the blink thread.
52 //
53 // This is achieved by making CryptoResultImpl hold a WeakPtr to the PromiseStat e.
54 // The PromiseState deletes itself after being notified of completion.
55 // Additionally the PromiseState deletes itself when the ExecutionContext is
56 // destroyed (necessary to avoid leaks when dealing with WebWorker threads,
57 // which may die before the operation is completed).
58 class CryptoResultImpl::PromiseState FINAL : public ContextLifecycleObserver {
59 public:
60 static WeakPtr<PromiseState> create(ExecutionContext* context)
61 {
62 PromiseState* promiseState = new PromiseState(context);
63 return promiseState->m_weakFactory.createWeakPtr();
64 }
65
66 // Override from ContextLifecycleObserver
67 virtual void contextDestroyed() OVERRIDE
68 {
69 ContextLifecycleObserver::contextDestroyed();
70 delete this;
71 }
72
73 ScriptPromise promise()
74 {
75 return m_promiseResolver->promise();
76 }
77
78 void completeWithError(const blink::WebString& errorDetails)
79 {
80 if (!errorDetails.isEmpty()) {
81 // FIXME: Include the line number which started the crypto operation .
82 executionContext()->addConsoleMessage(JSMessageSource, ErrorMessageL evel, errorDetails);
83 }
84 m_promiseResolver->reject(V8NullType());
85 delete this;
86 }
87
88 void completeWithError()
89 {
90 completeWithError(blink::WebString());
91 }
92
93 void completeWithBuffer(const blink::WebArrayBuffer& buffer)
94 {
95 m_promiseResolver->resolve(PassRefPtr<ArrayBuffer>(buffer));
96 delete this;
97 }
98
99 void completeWithBoolean(bool b)
100 {
101 m_promiseResolver->resolve(b);
102 delete this;
103 }
104
105 void completeWithKey(const blink::WebCryptoKey& key)
106 {
107 m_promiseResolver->resolve(Key::create(key));
108 delete this;
109 }
110
111 void completeWithKeyPair(const blink::WebCryptoKey& publicKey, const blink:: WebCryptoKey& privateKey)
112 {
113 m_promiseResolver->resolve(KeyPair::create(publicKey, privateKey));
114 delete this;
115 }
116
117 private:
118 explicit PromiseState(ExecutionContext* context)
119 : ContextLifecycleObserver(context)
120 , m_weakFactory(this)
121 , m_promiseResolver(ScriptPromiseResolverWithContext::create(NewScriptSt ate::current(toIsolate(context))))
122 {
123 }
124
125 WeakPtrFactory<PromiseState> m_weakFactory;
126 RefPtr<ScriptPromiseResolverWithContext> m_promiseResolver;
127 };
128
47 CryptoResultImpl::~CryptoResultImpl() 129 CryptoResultImpl::~CryptoResultImpl()
48 { 130 {
49 } 131 }
50 132
51 PassRefPtr<CryptoResultImpl> CryptoResultImpl::create() 133 PassRefPtr<CryptoResultImpl> CryptoResultImpl::create()
52 { 134 {
53 return adoptRef(new CryptoResultImpl(callingExecutionContext(v8::Isolate::Ge tCurrent()))); 135 return adoptRef(new CryptoResultImpl(callingExecutionContext(v8::Isolate::Ge tCurrent())));
54 } 136 }
55 137
56 void CryptoResultImpl::completeWithError(const blink::WebString& errorDetails) 138 void CryptoResultImpl::completeWithError(const blink::WebString& errorDetails)
57 { 139 {
58 ASSERT(!m_finished); 140 if (m_promiseState)
59 141 m_promiseState->completeWithError(errorDetails);
60 if (canCompletePromise()) {
61 if (!errorDetails.isEmpty()) {
62 // FIXME: Include the line number which started the crypto operation .
63 executionContext()->addConsoleMessage(JSMessageSource, ErrorMessageL evel, errorDetails);
64 }
65 m_promiseResolver->reject(V8NullType());
66 }
67 } 142 }
68 143
69 void CryptoResultImpl::completeWithError() 144 void CryptoResultImpl::completeWithError()
70 { 145 {
71 completeWithError(blink::WebString()); 146 completeWithError(blink::WebString());
72 } 147 }
73 148
74 void CryptoResultImpl::completeWithBuffer(const blink::WebArrayBuffer& buffer) 149 void CryptoResultImpl::completeWithBuffer(const blink::WebArrayBuffer& buffer)
75 { 150 {
76 ASSERT(!m_finished); 151 if (m_promiseState)
77 152 m_promiseState->completeWithBuffer(buffer);
78 if (canCompletePromise()) {
79 m_promiseResolver->resolve(PassRefPtr<ArrayBuffer>(buffer));
80 }
81
82 finish();
83 } 153 }
84 154
85 void CryptoResultImpl::completeWithBoolean(bool b) 155 void CryptoResultImpl::completeWithBoolean(bool b)
86 { 156 {
87 ASSERT(!m_finished); 157 if (m_promiseState)
88 158 m_promiseState->completeWithBoolean(b);
89 if (canCompletePromise()) {
90 m_promiseResolver->resolve(b);
91 }
92
93 finish();
94 } 159 }
95 160
96 void CryptoResultImpl::completeWithKey(const blink::WebCryptoKey& key) 161 void CryptoResultImpl::completeWithKey(const blink::WebCryptoKey& key)
97 { 162 {
98 ASSERT(!m_finished); 163 if (m_promiseState)
99 164 m_promiseState->completeWithKey(key);
100 if (canCompletePromise()) {
101 m_promiseResolver->resolve(Key::create(key));
102 }
103
104 finish();
105 } 165 }
106 166
107 void CryptoResultImpl::completeWithKeyPair(const blink::WebCryptoKey& publicKey, const blink::WebCryptoKey& privateKey) 167 void CryptoResultImpl::completeWithKeyPair(const blink::WebCryptoKey& publicKey, const blink::WebCryptoKey& privateKey)
108 { 168 {
109 ASSERT(!m_finished); 169 if (m_promiseState)
110 170 m_promiseState->completeWithKeyPair(publicKey, privateKey);
111 if (canCompletePromise()) {
112 m_promiseResolver->resolve(KeyPair::create(publicKey, privateKey));
113 }
114
115 finish();
116 } 171 }
117 172
118 CryptoResultImpl::CryptoResultImpl(ExecutionContext* context) 173 CryptoResultImpl::CryptoResultImpl(ExecutionContext* context)
119 : ContextLifecycleObserver(context) 174 : m_promiseState(PromiseState::create(context))
120 , m_promiseResolver(ScriptPromiseResolverWithContext::create(NewScriptState: :current(toIsolate(context))))
121 #if !ASSERT_DISABLED
122 , m_owningThread(currentThread())
123 , m_finished(false)
124 #endif
125 { 175 {
126 } 176 }
127 177
128 void CryptoResultImpl::finish() 178 ScriptPromise CryptoResultImpl::promise()
129 { 179 {
130 #if !ASSERT_DISABLED 180 return m_promiseState->promise();
131 m_finished = true;
132 #endif
133 clearPromiseResolver();
134 }
135
136 void CryptoResultImpl::clearPromiseResolver()
137 {
138 m_promiseResolver.clear();
139 }
140
141 void CryptoResultImpl::CheckValidThread() const
142 {
143 ASSERT(m_owningThread == currentThread());
144 }
145
146 void CryptoResultImpl::contextDestroyed()
147 {
148 ContextLifecycleObserver::contextDestroyed();
149
150 // Abandon the promise without completing it when the context goes away.
151 clearPromiseResolver();
152 ASSERT(!canCompletePromise());
153 }
154
155 bool CryptoResultImpl::canCompletePromise() const
156 {
157 CheckValidThread();
158 ExecutionContext* context = executionContext();
159 return context && !context->activeDOMObjectsAreSuspended() && !context->acti veDOMObjectsAreStopped();
160 } 181 }
161 182
162 } // namespace WebCore 183 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/modules/crypto/CryptoResultImpl.h ('k') | Source/platform/CryptoResult.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698