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

Side by Side Diff: Source/core/xml/XMLHttpRequest.cpp

Issue 104363002: [XHR] Use hasPendingActivity() to manage XHR's life time. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebased Created 7 years 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
« no previous file with comments | « Source/core/xml/XMLHttpRequest.h ('k') | no next file » | 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) 2004, 2006, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2005-2007 Alexey Proskuryakov <ap@webkit.org> 3 * Copyright (C) 2005-2007 Alexey Proskuryakov <ap@webkit.org>
4 * Copyright (C) 2007, 2008 Julien Chaffraix <jchaffraix@webkit.org> 4 * Copyright (C) 2007, 2008 Julien Chaffraix <jchaffraix@webkit.org>
5 * Copyright (C) 2008, 2011 Google Inc. All rights reserved. 5 * Copyright (C) 2008, 2011 Google Inc. All rights reserved.
6 * Copyright (C) 2012 Intel Corporation 6 * Copyright (C) 2012 Intel Corporation
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public 9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 , m_createdDocument(false) 172 , m_createdDocument(false)
173 , m_error(false) 173 , m_error(false)
174 , m_uploadEventsAllowed(true) 174 , m_uploadEventsAllowed(true)
175 , m_uploadComplete(false) 175 , m_uploadComplete(false)
176 , m_sameOriginRequest(true) 176 , m_sameOriginRequest(true)
177 , m_receivedLength(0) 177 , m_receivedLength(0)
178 , m_lastSendLineNumber(0) 178 , m_lastSendLineNumber(0)
179 , m_exceptionCode(0) 179 , m_exceptionCode(0)
180 , m_progressEventThrottle(this) 180 , m_progressEventThrottle(this)
181 , m_responseTypeCode(ResponseTypeDefault) 181 , m_responseTypeCode(ResponseTypeDefault)
182 , m_dropProtectionRunner(this, &XMLHttpRequest::dropProtection)
183 , m_securityOrigin(securityOrigin) 182 , m_securityOrigin(securityOrigin)
184 { 183 {
185 initializeXMLHttpRequestStaticData(); 184 initializeXMLHttpRequestStaticData();
186 #ifndef NDEBUG 185 #ifndef NDEBUG
187 xmlHttpRequestCounter.increment(); 186 xmlHttpRequestCounter.increment();
188 #endif 187 #endif
189 ScriptWrappable::init(this); 188 ScriptWrappable::init(this);
190 } 189 }
191 190
192 XMLHttpRequest::~XMLHttpRequest() 191 XMLHttpRequest::~XMLHttpRequest()
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 if (m_async) { 819 if (m_async) {
821 if (m_upload) 820 if (m_upload)
822 request.setReportUploadProgress(true); 821 request.setReportUploadProgress(true);
823 822
824 // ThreadableLoader::create can return null here, for example if we're n o longer attached to a page. 823 // ThreadableLoader::create can return null here, for example if we're n o longer attached to a page.
825 // This is true while running onunload handlers. 824 // This is true while running onunload handlers.
826 // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload , <http://bugs.webkit.org/show_bug.cgi?id=10904>. 825 // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload , <http://bugs.webkit.org/show_bug.cgi?id=10904>.
827 // FIXME: Maybe create() can return null for other reasons too? 826 // FIXME: Maybe create() can return null for other reasons too?
828 ASSERT(!m_loader); 827 ASSERT(!m_loader);
829 m_loader = ThreadableLoader::create(executionContext(), this, request, o ptions); 828 m_loader = ThreadableLoader::create(executionContext(), this, request, o ptions);
830 if (m_loader) {
831 // Neither this object nor the JavaScript wrapper should be deleted while
832 // a request is in progress because we need to keep the listeners al ive,
833 // and they are referenced by the JavaScript wrapper.
834 setPendingActivity(this);
835 }
836 } else { 829 } else {
837 ThreadableLoader::loadResourceSynchronously(executionContext(), request, *this, options); 830 ThreadableLoader::loadResourceSynchronously(executionContext(), request, *this, options);
838 } 831 }
839 832
840 if (!m_exceptionCode && m_error) 833 if (!m_exceptionCode && m_error)
841 m_exceptionCode = NetworkError; 834 m_exceptionCode = NetworkError;
842 if (m_exceptionCode) 835 if (m_exceptionCode)
843 exceptionState.throwUninformativeAndGenericDOMException(m_exceptionCode) ; 836 exceptionState.throwUninformativeAndGenericDOMException(m_exceptionCode) ;
844 } 837 }
845 838
846 void XMLHttpRequest::abort() 839 void XMLHttpRequest::abort()
847 { 840 {
848 WTF_LOG(Network, "XMLHttpRequest %p abort()", this); 841 WTF_LOG(Network, "XMLHttpRequest %p abort()", this);
849 842
850 // internalAbort() calls dropProtection(), which may release the last refere nce.
851 RefPtr<XMLHttpRequest> protect(this);
abarth-chromium 2013/12/05 04:17:24 Don't we still need this? Won't internalAbort rem
tyoshino (SeeGerritForStatus) 2013/12/05 04:32:10 oh right! I still didn't understand correctly when
852
853 bool sendFlag = m_loader; 843 bool sendFlag = m_loader;
854 844
855 // Response is cleared next, save needed progress event data. 845 // Response is cleared next, save needed progress event data.
856 long long expectedLength = m_response.expectedContentLength(); 846 long long expectedLength = m_response.expectedContentLength();
857 long long receivedLength = m_receivedLength; 847 long long receivedLength = m_receivedLength;
858 848
859 if (!internalAbort()) 849 if (!internalAbort())
860 return; 850 return;
861 851
862 clearResponse(); 852 clearResponse();
(...skipping 10 matching lines...) Expand all
873 863
874 void XMLHttpRequest::clearVariablesForLoading() 864 void XMLHttpRequest::clearVariablesForLoading()
875 { 865 {
876 // FIXME: when we add the support for multi-part XHR, we will have to think be careful with this initialization. 866 // FIXME: when we add the support for multi-part XHR, we will have to think be careful with this initialization.
877 m_receivedLength = 0; 867 m_receivedLength = 0;
878 m_decoder.clear(); 868 m_decoder.clear();
879 869
880 m_responseEncoding = String(); 870 m_responseEncoding = String();
881 } 871 }
882 872
883 bool XMLHttpRequest::internalAbort(DropProtection async) 873 bool XMLHttpRequest::internalAbort()
884 { 874 {
885 m_error = true; 875 m_error = true;
886 876
887 clearVariablesForLoading(); 877 clearVariablesForLoading();
888 878
889 InspectorInstrumentation::didFailXHRLoading(executionContext(), this, this); 879 InspectorInstrumentation::didFailXHRLoading(executionContext(), this, this);
890 880
891 if (m_responseStream && m_state != DONE) 881 if (m_responseStream && m_state != DONE)
892 m_responseStream->abort(); 882 m_responseStream->abort();
893 883
894 if (!m_loader) 884 if (!m_loader)
895 return true; 885 return true;
896 886
897 // Cancelling the ThreadableLoader m_loader may result in calling 887 // Cancelling the ThreadableLoader m_loader may result in calling
898 // window.onload synchronously. If such an onload handler contains open() 888 // window.onload synchronously. If such an onload handler contains open()
899 // call on the same XMLHttpRequest object, reentry happens. If m_loader 889 // call on the same XMLHttpRequest object, reentry happens. If m_loader
900 // is left to be non 0, internalAbort() call for the inner open() makes 890 // is left to be non 0, internalAbort() for the inner open() repeats the
901 // an extra dropProtection() call (when we're back to the outer open(), 891 // the same work. To avoid that, clears m_loader before calling cancel().
902 // we'll call dropProtection()). To avoid that, clears m_loader before 892 RefPtr<ThreadableLoader> loader = m_loader.release();
903 // calling cancel. 893 loader->cancel();
904 // 894
905 // If, window.onload contains open() and send(), m_loader will be set to 895 // If, window.onload contains open() and send(), m_loader will be set to
906 // non 0 value. So, we cannot continue the outer open(). In such case, 896 // non 0 value. So, we cannot continue the outer open(). In such case,
907 // just abort the outer open() by returning false. 897 // just abort the outer open() by returning false.
908 RefPtr<ThreadableLoader> loader = m_loader.release(); 898 if (m_loader)
909 loader->cancel(); 899 return false;
910
911 // Save to a local variable since we're going to drop protection.
912 bool newLoadStarted = m_loader;
913 900
914 // If abort() called internalAbort() and a nested open() ended up 901 // If abort() called internalAbort() and a nested open() ended up
915 // clearing the error flag, but didn't send(), make sure the error 902 // clearing the error flag, but didn't send(), make sure the error
916 // flag is still set. 903 // flag is still set.
917 if (!newLoadStarted) 904 m_error = true;
abarth-chromium 2013/12/05 04:17:24 For example, on this line of code, m_loader is 0,
918 m_error = true;
919 905
920 if (async == DropProtectionAsync) 906 return true;
921 dropProtectionSoon();
922 else
923 dropProtection();
924
925 return !newLoadStarted;
926 } 907 }
927 908
928 void XMLHttpRequest::clearResponse() 909 void XMLHttpRequest::clearResponse()
929 { 910 {
930 m_response = ResourceResponse(); 911 m_response = ResourceResponse();
931 912
932 m_responseText.clear(); 913 m_responseText.clear();
933 914
934 m_createdDocument = false; 915 m_createdDocument = false;
935 m_responseDocument = 0; 916 m_responseDocument = 0;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 if (!m_uploadComplete) { 1011 if (!m_uploadComplete) {
1031 m_uploadComplete = true; 1012 m_uploadComplete = true;
1032 if (m_upload && m_uploadEventsAllowed) 1013 if (m_upload && m_uploadEventsAllowed)
1033 m_upload->handleRequestError(type); 1014 m_upload->handleRequestError(type);
1034 } 1015 }
1035 1016
1036 dispatchThrottledProgressEvent(EventTypeNames::progress, receivedLength, exp ectedLength); 1017 dispatchThrottledProgressEvent(EventTypeNames::progress, receivedLength, exp ectedLength);
1037 dispatchEventAndLoadEnd(type, receivedLength, expectedLength); 1018 dispatchEventAndLoadEnd(type, receivedLength, expectedLength);
1038 } 1019 }
1039 1020
1040 void XMLHttpRequest::dropProtectionSoon()
1041 {
1042 m_dropProtectionRunner.runAsync();
1043 }
1044
1045 void XMLHttpRequest::dropProtection()
1046 {
1047 unsetPendingActivity(this);
1048 }
1049
1050 void XMLHttpRequest::overrideMimeType(const AtomicString& override) 1021 void XMLHttpRequest::overrideMimeType(const AtomicString& override)
1051 { 1022 {
1052 m_mimeTypeOverride = override; 1023 m_mimeTypeOverride = override;
1053 } 1024 }
1054 1025
1055 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const AtomicStri ng& value, ExceptionState& exceptionState) 1026 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const AtomicStri ng& value, ExceptionState& exceptionState)
1056 { 1027 {
1057 if (m_state != OPENED || m_loader) { 1028 if (m_state != OPENED || m_loader) {
1058 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToExecute("setRequestHeader", "XMLHttpRequest", "The object's state must be OPENED.")); 1029 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToExecute("setRequestHeader", "XMLHttpRequest", "The object's state must be OPENED."));
1059 return; 1030 return;
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 changeState(HEADERS_RECEIVED); 1203 changeState(HEADERS_RECEIVED);
1233 1204
1234 if (m_decoder) 1205 if (m_decoder)
1235 m_responseText = m_responseText.concatenateWith(m_decoder->flush()); 1206 m_responseText = m_responseText.concatenateWith(m_decoder->flush());
1236 1207
1237 if (m_responseStream) 1208 if (m_responseStream)
1238 m_responseStream->finalize(); 1209 m_responseStream->finalize();
1239 1210
1240 InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, this , identifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber); 1211 InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, this , identifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber);
1241 1212
1242 // Prevent dropProtection releasing the last reference, and retain |this| un til the end of this method. 1213 if (m_loader)
1243 RefPtr<XMLHttpRequest> protect(this);
1244
1245 if (m_loader) {
1246 m_loader = 0; 1214 m_loader = 0;
1247 dropProtection();
1248 }
1249 1215
1250 changeState(DONE); 1216 changeState(DONE);
1251 1217
1252 clearVariablesForLoading(); 1218 clearVariablesForLoading();
1253 } 1219 }
1254 1220
1255 void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon g totalBytesToBeSent) 1221 void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon g totalBytesToBeSent)
1256 { 1222 {
1257 WTF_LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSen t, totalBytesToBeSent); 1223 WTF_LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSen t, totalBytesToBeSent);
1258 1224
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 // FIXME: Make our implementation and the spec consistent. This 1313 // FIXME: Make our implementation and the spec consistent. This
1348 // behavior was needed when the progress event was not available. 1314 // behavior was needed when the progress event was not available.
1349 dispatchReadyStateChangeEvent(); 1315 dispatchReadyStateChangeEvent();
1350 } 1316 }
1351 } 1317 }
1352 1318
1353 void XMLHttpRequest::handleDidTimeout() 1319 void XMLHttpRequest::handleDidTimeout()
1354 { 1320 {
1355 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); 1321 WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this);
1356 1322
1357 // internalAbort() calls dropProtection(), which may release the last refere nce.
1358 RefPtr<XMLHttpRequest> protect(this);
1359
1360 // Response is cleared next, save needed progress event data. 1323 // Response is cleared next, save needed progress event data.
1361 long long expectedLength = m_response.expectedContentLength(); 1324 long long expectedLength = m_response.expectedContentLength();
1362 long long receivedLength = m_receivedLength; 1325 long long receivedLength = m_receivedLength;
1363 1326
1364 if (!internalAbort()) 1327 if (!internalAbort())
1365 return; 1328 return;
1366 1329
1367 handleDidFailGeneric(); 1330 handleDidFailGeneric();
1368 handleRequestError(TimeoutError, EventTypeNames::timeout, receivedLength, ex pectedLength); 1331 handleRequestError(TimeoutError, EventTypeNames::timeout, receivedLength, ex pectedLength);
1369 } 1332 }
1370 1333
1371 void XMLHttpRequest::suspend() 1334 void XMLHttpRequest::suspend()
1372 { 1335 {
1373 m_progressEventThrottle.suspend(); 1336 m_progressEventThrottle.suspend();
1374 } 1337 }
1375 1338
1376 void XMLHttpRequest::resume() 1339 void XMLHttpRequest::resume()
1377 { 1340 {
1378 m_progressEventThrottle.resume(); 1341 m_progressEventThrottle.resume();
1379 } 1342 }
1380 1343
1381 void XMLHttpRequest::stop() 1344 void XMLHttpRequest::stop()
1382 { 1345 {
1383 internalAbort(DropProtectionAsync); 1346 internalAbort();
abarth-chromium 2013/12/05 04:14:03 Don't we need to set some sort of flag here to pre
tyoshino (SeeGerritForStatus) 2013/12/05 04:26:20 Good catch! We don't want it to start a new loadin
1347 }
1348
1349 bool XMLHttpRequest::hasPendingActivity() const
1350 {
1351 return m_loader;
abarth-chromium 2013/12/05 04:14:03 Is there something that stops m_loader from being
tyoshino (SeeGerritForStatus) 2013/12/05 04:26:20 I once tried to add a boolean member, say "m_abort
1384 } 1352 }
1385 1353
1386 void XMLHttpRequest::contextDestroyed() 1354 void XMLHttpRequest::contextDestroyed()
1387 { 1355 {
1388 ASSERT(!m_loader); 1356 ASSERT(!m_loader);
1389 ActiveDOMObject::contextDestroyed(); 1357 ActiveDOMObject::contextDestroyed();
1390 } 1358 }
1391 1359
1392 const AtomicString& XMLHttpRequest::interfaceName() const 1360 const AtomicString& XMLHttpRequest::interfaceName() const
1393 { 1361 {
1394 return EventTargetNames::XMLHttpRequest; 1362 return EventTargetNames::XMLHttpRequest;
1395 } 1363 }
1396 1364
1397 ExecutionContext* XMLHttpRequest::executionContext() const 1365 ExecutionContext* XMLHttpRequest::executionContext() const
1398 { 1366 {
1399 return ActiveDOMObject::executionContext(); 1367 return ActiveDOMObject::executionContext();
1400 } 1368 }
1401 1369
1402 } // namespace WebCore 1370 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/xml/XMLHttpRequest.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698