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

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: Use WeakPtr 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()
61 {
62 ExecutionContext* context = callingExecutionContext(v8::Isolate::GetCurr ent());
abarth-chromium 2014/04/25 23:26:14 Can we pass in the isolate?
eroman 2014/04/26 00:23:44 Done (I think).
63 PromiseState* promiseState = new PromiseState(context);
64 return promiseState->m_weakFactory.createWeakPtr();
65 }
66
67 // Override from ContextLifecycleObserver
68 virtual void contextDestroyed() OVERRIDE
69 {
70 ContextLifecycleObserver::contextDestroyed();
71 delete this;
72 }
73
74 ScriptPromise promise()
75 {
76 return m_promiseResolver->promise();
77 }
78
79 void completeWithError(const blink::WebString& errorDetails)
80 {
81 if (!errorDetails.isEmpty()) {
82 // FIXME: Include the line number which started the crypto operation .
83 executionContext()->addConsoleMessage(JSMessageSource, ErrorMessageL evel, errorDetails);
84 }
85 m_promiseResolver->reject(V8NullType());
86 delete this;
87 }
88
89 void completeWithError()
90 {
91 completeWithError(blink::WebString());
92 }
93
94 void completeWithBuffer(const blink::WebArrayBuffer& buffer)
95 {
96 m_promiseResolver->resolve(PassRefPtr<ArrayBuffer>(buffer));
97 delete this;
98 }
99
100 void completeWithBoolean(bool b)
101 {
102 m_promiseResolver->resolve(b);
103 delete this;
104 }
105
106 void completeWithKey(const blink::WebCryptoKey& key)
107 {
108 m_promiseResolver->resolve(Key::create(key));
109 delete this;
110 }
111
112 void completeWithKeyPair(const blink::WebCryptoKey& publicKey, const blink:: WebCryptoKey& privateKey)
113 {
114 m_promiseResolver->resolve(KeyPair::create(publicKey, privateKey));
115 delete this;
116 }
117
118 private:
119 explicit PromiseState(ExecutionContext* context)
120 : ContextLifecycleObserver(context)
121 , m_weakFactory(this)
122 , m_promiseResolver(ScriptPromiseResolverWithContext::create(NewScriptSt ate::current(toIsolate(context))))
123 {
124 }
125
126 WeakPtrFactory<PromiseState> m_weakFactory;
127 RefPtr<ScriptPromiseResolverWithContext> m_promiseResolver;
128 };
129
47 CryptoResultImpl::~CryptoResultImpl() 130 CryptoResultImpl::~CryptoResultImpl()
48 { 131 {
49 } 132 }
50 133
51 PassRefPtr<CryptoResultImpl> CryptoResultImpl::create() 134 PassRefPtr<CryptoResultImpl> CryptoResultImpl::create()
52 { 135 {
53 return adoptRef(new CryptoResultImpl(callingExecutionContext(v8::Isolate::Ge tCurrent()))); 136 return adoptRef(new CryptoResultImpl);
54 } 137 }
55 138
56 void CryptoResultImpl::completeWithError(const blink::WebString& errorDetails) 139 void CryptoResultImpl::completeWithError(const blink::WebString& errorDetails)
57 { 140 {
58 ASSERT(!m_finished); 141 if (m_promiseState)
59 142 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 } 143 }
68 144
69 void CryptoResultImpl::completeWithError() 145 void CryptoResultImpl::completeWithError()
70 { 146 {
71 completeWithError(blink::WebString()); 147 completeWithError(blink::WebString());
72 } 148 }
73 149
74 void CryptoResultImpl::completeWithBuffer(const blink::WebArrayBuffer& buffer) 150 void CryptoResultImpl::completeWithBuffer(const blink::WebArrayBuffer& buffer)
75 { 151 {
76 ASSERT(!m_finished); 152 if (m_promiseState)
77 153 m_promiseState->completeWithBuffer(buffer);
78 if (canCompletePromise()) {
79 m_promiseResolver->resolve(PassRefPtr<ArrayBuffer>(buffer));
80 }
81
82 finish();
83 } 154 }
84 155
85 void CryptoResultImpl::completeWithBoolean(bool b) 156 void CryptoResultImpl::completeWithBoolean(bool b)
86 { 157 {
87 ASSERT(!m_finished); 158 if (m_promiseState)
88 159 m_promiseState->completeWithBoolean(b);
89 if (canCompletePromise()) {
90 m_promiseResolver->resolve(b);
91 }
92
93 finish();
94 } 160 }
95 161
96 void CryptoResultImpl::completeWithKey(const blink::WebCryptoKey& key) 162 void CryptoResultImpl::completeWithKey(const blink::WebCryptoKey& key)
97 { 163 {
98 ASSERT(!m_finished); 164 if (m_promiseState)
99 165 m_promiseState->completeWithKey(key);
100 if (canCompletePromise()) {
101 m_promiseResolver->resolve(Key::create(key));
102 }
103
104 finish();
105 } 166 }
106 167
107 void CryptoResultImpl::completeWithKeyPair(const blink::WebCryptoKey& publicKey, const blink::WebCryptoKey& privateKey) 168 void CryptoResultImpl::completeWithKeyPair(const blink::WebCryptoKey& publicKey, const blink::WebCryptoKey& privateKey)
108 { 169 {
109 ASSERT(!m_finished); 170 if (m_promiseState)
110 171 m_promiseState->completeWithKeyPair(publicKey, privateKey);
111 if (canCompletePromise()) {
112 m_promiseResolver->resolve(KeyPair::create(publicKey, privateKey));
113 }
114
115 finish();
116 } 172 }
117 173
118 CryptoResultImpl::CryptoResultImpl(ExecutionContext* context) 174 CryptoResultImpl::CryptoResultImpl()
119 : ContextLifecycleObserver(context) 175 : m_promiseState(PromiseState::create())
120 , m_promiseResolver(ScriptPromiseResolverWithContext::create(NewScriptState: :current(toIsolate(context))))
121 #if !ASSERT_DISABLED
122 , m_owningThread(currentThread())
123 , m_finished(false)
124 #endif
125 { 176 {
126 } 177 }
127 178
128 void CryptoResultImpl::finish() 179 ScriptPromise CryptoResultImpl::promise()
129 { 180 {
130 #if !ASSERT_DISABLED 181 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 } 182 }
161 183
162 } // namespace WebCore 184 } // 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