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

Side by Side Diff: third_party/WebKit/Source/modules/serviceworkers/FetchEvent.cpp

Issue 2922863002: Keep the wrapper of FetchEvent alive while waiting for the preload response. (Closed)
Patch Set: use ContextClient and add comment Created 3 years, 6 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "modules/serviceworkers/FetchEvent.h" 5 #include "modules/serviceworkers/FetchEvent.h"
6 6
7 #include "bindings/core/v8/ToV8ForCore.h" 7 #include "bindings/core/v8/ToV8ForCore.h"
8 #include "core/dom/ExecutionContext.h" 8 #include "core/dom/ExecutionContext.h"
9 #include "core/timing/WorkerGlobalScopePerformance.h" 9 #include "core/timing/WorkerGlobalScopePerformance.h"
10 #include "modules/fetch/BytesConsumerForDataConsumerHandle.h" 10 #include "modules/fetch/BytesConsumerForDataConsumerHandle.h"
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 } 62 }
63 63
64 ScriptPromise FetchEvent::preloadResponse(ScriptState* script_state) { 64 ScriptPromise FetchEvent::preloadResponse(ScriptState* script_state) {
65 return preload_response_property_->Promise(script_state->World()); 65 return preload_response_property_->Promise(script_state->World());
66 } 66 }
67 67
68 const AtomicString& FetchEvent::InterfaceName() const { 68 const AtomicString& FetchEvent::InterfaceName() const {
69 return EventNames::FetchEvent; 69 return EventNames::FetchEvent;
70 } 70 }
71 71
72 bool FetchEvent::HasPendingActivity() const {
73 // Prevent V8 from garbage collecting the wrapper object while waiting for the
74 // preload response. This is in order to keep the resolver of preloadResponse
75 // Promise alive.
76 return waiting_for_preload_response_ && GetExecutionContext();
77 }
78
72 FetchEvent::FetchEvent(ScriptState* script_state, 79 FetchEvent::FetchEvent(ScriptState* script_state,
73 const AtomicString& type, 80 const AtomicString& type,
74 const FetchEventInit& initializer, 81 const FetchEventInit& initializer,
75 FetchRespondWithObserver* respond_with_observer, 82 FetchRespondWithObserver* respond_with_observer,
76 WaitUntilObserver* wait_until_observer, 83 WaitUntilObserver* wait_until_observer,
77 bool navigation_preload_sent) 84 bool navigation_preload_sent)
78 : ExtendableEvent(type, initializer, wait_until_observer), 85 : ExtendableEvent(type, initializer, wait_until_observer),
86 ContextClient(ExecutionContext::From(script_state)),
79 observer_(respond_with_observer), 87 observer_(respond_with_observer),
80 preload_response_property_(new PreloadResponseProperty( 88 preload_response_property_(new PreloadResponseProperty(
81 ExecutionContext::From(script_state), 89 ExecutionContext::From(script_state),
82 this, 90 this,
83 PreloadResponseProperty::kPreloadResponse)) { 91 PreloadResponseProperty::kPreloadResponse)),
92 waiting_for_preload_response_(navigation_preload_sent) {
84 if (!navigation_preload_sent) 93 if (!navigation_preload_sent)
85 preload_response_property_->ResolveWithUndefined(); 94 preload_response_property_->ResolveWithUndefined();
86 95
87 client_id_ = initializer.clientId(); 96 client_id_ = initializer.clientId();
88 is_reload_ = initializer.isReload(); 97 is_reload_ = initializer.isReload();
89 if (initializer.hasRequest()) { 98 if (initializer.hasRequest()) {
90 ScriptState::Scope scope(script_state); 99 ScriptState::Scope scope(script_state);
91 request_ = initializer.request(); 100 request_ = initializer.request();
92 v8::Local<v8::Value> request = ToV8(request_, script_state); 101 v8::Local<v8::Value> request = ToV8(request_, script_state);
93 v8::Local<v8::Value> event = ToV8(this, script_state); 102 v8::Local<v8::Value> event = ToV8(this, script_state);
94 if (event.IsEmpty()) { 103 if (event.IsEmpty()) {
95 // |toV8| can return an empty handle when the worker is terminating. 104 // |toV8| can return an empty handle when the worker is terminating.
96 // We don't want the renderer to crash in such cases. 105 // We don't want the renderer to crash in such cases.
97 // TODO(yhirano): Replace this branch with an assertion when the 106 // TODO(yhirano): Replace this branch with an assertion when the
98 // graceful shutdown mechanism is introduced. 107 // graceful shutdown mechanism is introduced.
99 return; 108 return;
100 } 109 }
101 DCHECK(event->IsObject()); 110 DCHECK(event->IsObject());
102 // Sets a hidden value in order to teach V8 the dependency from 111 // Sets a hidden value in order to teach V8 the dependency from
103 // the event to the request. 112 // the event to the request.
104 V8PrivateProperty::GetFetchEventRequest(script_state->GetIsolate()) 113 V8PrivateProperty::GetFetchEventRequest(script_state->GetIsolate())
105 .Set(event.As<v8::Object>(), request); 114 .Set(event.As<v8::Object>(), request);
106 // From the same reason as above, setHiddenValue can return false. 115 // From the same reason as above, setHiddenValue can return false.
107 // TODO(yhirano): Add an assertion that it returns true once the 116 // TODO(yhirano): Add an assertion that it returns true once the
108 // graceful shutdown mechanism is introduced. 117 // graceful shutdown mechanism is introduced.
109 } 118 }
110 } 119 }
111 120
121 FetchEvent::~FetchEvent() {}
122
112 void FetchEvent::OnNavigationPreloadResponse( 123 void FetchEvent::OnNavigationPreloadResponse(
113 ScriptState* script_state, 124 ScriptState* script_state,
114 std::unique_ptr<WebURLResponse> response, 125 std::unique_ptr<WebURLResponse> response,
115 std::unique_ptr<WebDataConsumerHandle> data_consume_handle) { 126 std::unique_ptr<WebDataConsumerHandle> data_consume_handle) {
116 if (!script_state->ContextIsValid()) 127 if (!script_state->ContextIsValid())
117 return; 128 return;
118 DCHECK(preload_response_property_); 129 DCHECK(preload_response_property_);
119 DCHECK(!preload_response_); 130 DCHECK(!preload_response_);
120 ScriptState::Scope scope(script_state); 131 ScriptState::Scope scope(script_state);
121 preload_response_ = std::move(response); 132 preload_response_ = std::move(response);
(...skipping 20 matching lines...) Expand all
142 NetworkUtils::IsRedirectResponseCode(preload_response_->HttpStatusCode()) 153 NetworkUtils::IsRedirectResponseCode(preload_response_->HttpStatusCode())
143 ? response_data->CreateOpaqueRedirectFilteredResponse() 154 ? response_data->CreateOpaqueRedirectFilteredResponse()
144 : response_data->CreateBasicFilteredResponse(); 155 : response_data->CreateBasicFilteredResponse();
145 preload_response_property_->Resolve( 156 preload_response_property_->Resolve(
146 Response::Create(ExecutionContext::From(script_state), tainted_response)); 157 Response::Create(ExecutionContext::From(script_state), tainted_response));
147 } 158 }
148 159
149 void FetchEvent::OnNavigationPreloadError( 160 void FetchEvent::OnNavigationPreloadError(
150 ScriptState* script_state, 161 ScriptState* script_state,
151 std::unique_ptr<WebServiceWorkerError> error) { 162 std::unique_ptr<WebServiceWorkerError> error) {
163 waiting_for_preload_response_ = false;
152 if (!script_state->ContextIsValid()) 164 if (!script_state->ContextIsValid())
153 return; 165 return;
154 DCHECK(preload_response_property_); 166 DCHECK(preload_response_property_);
155 preload_response_property_->Reject( 167 preload_response_property_->Reject(
156 ServiceWorkerError::Take(nullptr, *error.get())); 168 ServiceWorkerError::Take(nullptr, *error.get()));
157 } 169 }
158 170
159 void FetchEvent::OnNavigationPreloadComplete( 171 void FetchEvent::OnNavigationPreloadComplete(
160 WorkerGlobalScope* worker_global_scope, 172 WorkerGlobalScope* worker_global_scope,
161 double completion_time, 173 double completion_time,
162 int64_t encoded_data_length, 174 int64_t encoded_data_length,
163 int64_t encoded_body_length, 175 int64_t encoded_body_length,
164 int64_t decoded_body_length) { 176 int64_t decoded_body_length) {
165 DCHECK(preload_response_); 177 DCHECK(preload_response_);
178 waiting_for_preload_response_ = false;
166 std::unique_ptr<WebURLResponse> response = std::move(preload_response_); 179 std::unique_ptr<WebURLResponse> response = std::move(preload_response_);
167 ResourceResponse resource_response = response->ToResourceResponse(); 180 ResourceResponse resource_response = response->ToResourceResponse();
168 resource_response.SetEncodedDataLength(encoded_data_length); 181 resource_response.SetEncodedDataLength(encoded_data_length);
169 resource_response.SetEncodedBodyLength(encoded_body_length); 182 resource_response.SetEncodedBodyLength(encoded_body_length);
170 resource_response.SetDecodedBodyLength(decoded_body_length); 183 resource_response.SetDecodedBodyLength(decoded_body_length);
171 // According to the current spec of Resource Timing, the initiator type of 184 // According to the current spec of Resource Timing, the initiator type of
172 // navigation preload request must be "other". But it may change when the spec 185 // navigation preload request must be "other". But it may change when the spec
173 // discussion is settled. https://github.com/w3c/resource-timing/issues/110 186 // discussion is settled. https://github.com/w3c/resource-timing/issues/110
174 RefPtr<ResourceTimingInfo> info = ResourceTimingInfo::Create( 187 RefPtr<ResourceTimingInfo> info = ResourceTimingInfo::Create(
175 "other", resource_response.GetResourceLoadTiming()->RequestTime(), 188 "other", resource_response.GetResourceLoadTiming()->RequestTime(),
176 false /* is_main_resource */); 189 false /* is_main_resource */);
177 info->SetNegativeAllowed(true); 190 info->SetNegativeAllowed(true);
178 info->SetLoadFinishTime(completion_time); 191 info->SetLoadFinishTime(completion_time);
179 info->SetInitialURL(request_->url()); 192 info->SetInitialURL(request_->url());
180 info->SetFinalResponse(resource_response); 193 info->SetFinalResponse(resource_response);
181 info->AddFinalTransferSize(encoded_data_length); 194 info->AddFinalTransferSize(encoded_data_length);
182 WorkerGlobalScopePerformance::performance(*worker_global_scope) 195 WorkerGlobalScopePerformance::performance(*worker_global_scope)
183 ->AddResourceTiming(*info); 196 ->AddResourceTiming(*info);
184 } 197 }
185 198
186 DEFINE_TRACE(FetchEvent) { 199 DEFINE_TRACE(FetchEvent) {
187 visitor->Trace(observer_); 200 visitor->Trace(observer_);
188 visitor->Trace(request_); 201 visitor->Trace(request_);
189 visitor->Trace(preload_response_property_); 202 visitor->Trace(preload_response_property_);
190 ExtendableEvent::Trace(visitor); 203 ExtendableEvent::Trace(visitor);
204 ContextClient::Trace(visitor);
191 } 205 }
192 206
193 } // namespace blink 207 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698