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

Side by Side Diff: third_party/WebKit/Source/core/fileapi/FileReader.cpp

Issue 2143353003: FileReader shouldn't mark itself as inactive before firing events (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comment Created 4 years, 5 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
« no previous file with comments | « third_party/WebKit/Source/core/fileapi/FileReader.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) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 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 27 matching lines...) Expand all
38 #include "core/dom/ExceptionCode.h" 38 #include "core/dom/ExceptionCode.h"
39 #include "core/dom/ExecutionContext.h" 39 #include "core/dom/ExecutionContext.h"
40 #include "core/events/ProgressEvent.h" 40 #include "core/events/ProgressEvent.h"
41 #include "core/fileapi/File.h" 41 #include "core/fileapi/File.h"
42 #include "core/inspector/InspectorInstrumentation.h" 42 #include "core/inspector/InspectorInstrumentation.h"
43 #include "platform/Logging.h" 43 #include "platform/Logging.h"
44 #include "platform/Supplementable.h" 44 #include "platform/Supplementable.h"
45 #include "wtf/CurrentTime.h" 45 #include "wtf/CurrentTime.h"
46 #include "wtf/Deque.h" 46 #include "wtf/Deque.h"
47 #include "wtf/HashSet.h" 47 #include "wtf/HashSet.h"
48 #include "wtf/TemporaryChange.h"
48 #include "wtf/text/CString.h" 49 #include "wtf/text/CString.h"
49 50
50 namespace blink { 51 namespace blink {
51 52
52 namespace { 53 namespace {
53 54
54 const CString utf8BlobUUID(Blob* blob) 55 const CString utf8BlobUUID(Blob* blob)
55 { 56 {
56 return blob->uuid().utf8(); 57 return blob->uuid().utf8();
57 } 58 }
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 FileReader* fileReader = new FileReader(context); 193 FileReader* fileReader = new FileReader(context);
193 fileReader->suspendIfNeeded(); 194 fileReader->suspendIfNeeded();
194 return fileReader; 195 return fileReader;
195 } 196 }
196 197
197 FileReader::FileReader(ExecutionContext* context) 198 FileReader::FileReader(ExecutionContext* context)
198 : ActiveScriptWrappable(this) 199 : ActiveScriptWrappable(this)
199 , ActiveDOMObject(context) 200 , ActiveDOMObject(context)
200 , m_state(EMPTY) 201 , m_state(EMPTY)
201 , m_loadingState(LoadingStateNone) 202 , m_loadingState(LoadingStateNone)
203 , m_stillFiringEvents(false)
202 , m_readType(FileReaderLoader::ReadAsBinaryString) 204 , m_readType(FileReaderLoader::ReadAsBinaryString)
203 , m_lastProgressNotificationTimeMS(0) 205 , m_lastProgressNotificationTimeMS(0)
204 { 206 {
205 } 207 }
206 208
207 FileReader::~FileReader() 209 FileReader::~FileReader()
208 { 210 {
209 terminate(); 211 terminate();
210 } 212 }
211 213
212 const AtomicString& FileReader::interfaceName() const 214 const AtomicString& FileReader::interfaceName() const
213 { 215 {
214 return EventTargetNames::FileReader; 216 return EventTargetNames::FileReader;
215 } 217 }
216 218
217 void FileReader::stop() 219 void FileReader::stop()
218 { 220 {
219 // The delayed abort task tidies up and advances to the DONE state. 221 // The delayed abort task tidies up and advances to the DONE state.
220 if (m_loadingState == LoadingStateAborted) 222 if (m_loadingState == LoadingStateAborted)
221 return; 223 return;
222 224
223 if (hasPendingActivity()) 225 if (hasPendingActivity())
224 ThrottlingController::finishReader(getExecutionContext(), this, Throttli ngController::removeReader(getExecutionContext(), this)); 226 ThrottlingController::finishReader(getExecutionContext(), this, Throttli ngController::removeReader(getExecutionContext(), this));
225 terminate(); 227 terminate();
226 } 228 }
227 229
228 bool FileReader::hasPendingActivity() const 230 bool FileReader::hasPendingActivity() const
229 { 231 {
230 return m_state == LOADING; 232 return m_state == LOADING || m_stillFiringEvents;
231 } 233 }
232 234
233 void FileReader::readAsArrayBuffer(Blob* blob, ExceptionState& exceptionState) 235 void FileReader::readAsArrayBuffer(Blob* blob, ExceptionState& exceptionState)
234 { 236 {
235 ASSERT(blob); 237 ASSERT(blob);
236 DVLOG(1) << "reading as array buffer: " << utf8BlobUUID(blob).data() << " " << utf8FilePath(blob).data(); 238 DVLOG(1) << "reading as array buffer: " << utf8BlobUUID(blob).data() << " " << utf8FilePath(blob).data();
237 239
238 readInternal(blob, FileReaderLoader::ReadAsArrayBuffer, exceptionState); 240 readInternal(blob, FileReaderLoader::ReadAsArrayBuffer, exceptionState);
239 } 241 }
240 242
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 m_loadingState = LoadingStateAborted; 336 m_loadingState = LoadingStateAborted;
335 337
336 // Schedule to have the abort done later since abort() might be called from the event handler and we do not want the resource loading code to be in the stac k. 338 // Schedule to have the abort done later since abort() might be called from the event handler and we do not want the resource loading code to be in the stac k.
337 getExecutionContext()->postTask( 339 getExecutionContext()->postTask(
338 BLINK_FROM_HERE, createSameThreadTask(&delayedAbort, wrapPersistent(this ))); 340 BLINK_FROM_HERE, createSameThreadTask(&delayedAbort, wrapPersistent(this )));
339 } 341 }
340 342
341 void FileReader::doAbort() 343 void FileReader::doAbort()
342 { 344 {
343 ASSERT(m_state != DONE); 345 ASSERT(m_state != DONE);
346 TemporaryChange<bool> firingEvents(m_stillFiringEvents, true);
344 347
345 terminate(); 348 terminate();
346 349
347 m_error = FileError::create(FileError::ABORT_ERR); 350 m_error = FileError::create(FileError::ABORT_ERR);
348 351
349 // Unregister the reader. 352 // Unregister the reader.
350 ThrottlingController::FinishReaderType finalStep = ThrottlingController::rem oveReader(getExecutionContext(), this); 353 ThrottlingController::FinishReaderType finalStep = ThrottlingController::rem oveReader(getExecutionContext(), this);
351 354
352 fireEvent(EventTypeNames::error); 355 fireEvent(EventTypeNames::error);
353 fireEvent(EventTypeNames::abort); 356 fireEvent(EventTypeNames::abort);
(...skipping 19 matching lines...) Expand all
373 if (m_loader) { 376 if (m_loader) {
374 m_loader->cancel(); 377 m_loader->cancel();
375 m_loader = nullptr; 378 m_loader = nullptr;
376 } 379 }
377 m_state = DONE; 380 m_state = DONE;
378 m_loadingState = LoadingStateNone; 381 m_loadingState = LoadingStateNone;
379 } 382 }
380 383
381 void FileReader::didStartLoading() 384 void FileReader::didStartLoading()
382 { 385 {
386 TemporaryChange<bool> firingEvents(m_stillFiringEvents, true);
383 fireEvent(EventTypeNames::loadstart); 387 fireEvent(EventTypeNames::loadstart);
384 } 388 }
385 389
386 void FileReader::didReceiveData() 390 void FileReader::didReceiveData()
387 { 391 {
388 // Fire the progress event at least every 50ms. 392 // Fire the progress event at least every 50ms.
389 double now = currentTimeMS(); 393 double now = currentTimeMS();
390 if (!m_lastProgressNotificationTimeMS) { 394 if (!m_lastProgressNotificationTimeMS) {
391 m_lastProgressNotificationTimeMS = now; 395 m_lastProgressNotificationTimeMS = now;
392 } else if (now - m_lastProgressNotificationTimeMS > progressNotificationInte rvalMS) { 396 } else if (now - m_lastProgressNotificationTimeMS > progressNotificationInte rvalMS) {
397 TemporaryChange<bool> firingEvents(m_stillFiringEvents, true);
393 fireEvent(EventTypeNames::progress); 398 fireEvent(EventTypeNames::progress);
394 m_lastProgressNotificationTimeMS = now; 399 m_lastProgressNotificationTimeMS = now;
395 } 400 }
396 } 401 }
397 402
398 void FileReader::didFinishLoading() 403 void FileReader::didFinishLoading()
399 { 404 {
400 if (m_loadingState == LoadingStateAborted) 405 if (m_loadingState == LoadingStateAborted)
401 return; 406 return;
402 ASSERT(m_loadingState == LoadingStateLoading); 407 ASSERT(m_loadingState == LoadingStateLoading);
403 408
409 // TODO(jochen): When we set m_state to DONE below, we still need to fire
410 // the load and loadend events. To avoid GC to collect this FileReader, we
411 // use this separate variable to keep the wrapper of this FileReader alive.
412 // An alternative would be to keep any active DOM object alive that is on
413 // the stack.
414 TemporaryChange<bool> firingEvents(m_stillFiringEvents, true);
415
404 // It's important that we change m_loadingState before firing any events 416 // It's important that we change m_loadingState before firing any events
405 // since any of the events could call abort(), which internally checks 417 // since any of the events could call abort(), which internally checks
406 // if we're still loading (therefore we need abort process) or not. 418 // if we're still loading (therefore we need abort process) or not.
407 m_loadingState = LoadingStateNone; 419 m_loadingState = LoadingStateNone;
408 420
409 fireEvent(EventTypeNames::progress); 421 fireEvent(EventTypeNames::progress);
410 422
411 ASSERT(m_state != DONE); 423 ASSERT(m_state != DONE);
412 m_state = DONE; 424 m_state = DONE;
413 425
414 // Unregister the reader. 426 // Unregister the reader.
415 ThrottlingController::FinishReaderType finalStep = ThrottlingController::rem oveReader(getExecutionContext(), this); 427 ThrottlingController::FinishReaderType finalStep = ThrottlingController::rem oveReader(getExecutionContext(), this);
416 428
417 fireEvent(EventTypeNames::load); 429 fireEvent(EventTypeNames::load);
418 fireEvent(EventTypeNames::loadend); 430 fireEvent(EventTypeNames::loadend);
419 431
420 // All possible events have fired and we're done, no more pending activity. 432 // All possible events have fired and we're done, no more pending activity.
421 ThrottlingController::finishReader(getExecutionContext(), this, finalStep); 433 ThrottlingController::finishReader(getExecutionContext(), this, finalStep);
422 } 434 }
423 435
424 void FileReader::didFail(FileError::ErrorCode errorCode) 436 void FileReader::didFail(FileError::ErrorCode errorCode)
425 { 437 {
426 if (m_loadingState == LoadingStateAborted) 438 if (m_loadingState == LoadingStateAborted)
427 return; 439 return;
440
441 TemporaryChange<bool> firingEvents(m_stillFiringEvents, true);
442
428 ASSERT(m_loadingState == LoadingStateLoading); 443 ASSERT(m_loadingState == LoadingStateLoading);
429 m_loadingState = LoadingStateNone; 444 m_loadingState = LoadingStateNone;
430 445
431 ASSERT(m_state != DONE); 446 ASSERT(m_state != DONE);
432 m_state = DONE; 447 m_state = DONE;
433 448
434 m_error = FileError::create(static_cast<FileError::ErrorCode>(errorCode)); 449 m_error = FileError::create(static_cast<FileError::ErrorCode>(errorCode));
435 450
436 // Unregister the reader. 451 // Unregister the reader.
437 ThrottlingController::FinishReaderType finalStep = ThrottlingController::rem oveReader(getExecutionContext(), this); 452 ThrottlingController::FinishReaderType finalStep = ThrottlingController::rem oveReader(getExecutionContext(), this);
(...skipping 20 matching lines...) Expand all
458 } 473 }
459 474
460 DEFINE_TRACE(FileReader) 475 DEFINE_TRACE(FileReader)
461 { 476 {
462 visitor->trace(m_error); 477 visitor->trace(m_error);
463 EventTargetWithInlineData::trace(visitor); 478 EventTargetWithInlineData::trace(visitor);
464 ActiveDOMObject::trace(visitor); 479 ActiveDOMObject::trace(visitor);
465 } 480 }
466 481
467 } // namespace blink 482 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/fileapi/FileReader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698