 Chromium Code Reviews
 Chromium Code Reviews Issue 174963002:
  Finalize a throttled FileReader in stages.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/blink.git@master
    
  
    Issue 174963002:
  Finalize a throttled FileReader in stages.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/blink.git@master| OLD | NEW | 
|---|---|
| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 // excessive IPC congestion. We limit this to 100 per thread to throttle the | 68 // excessive IPC congestion. We limit this to 100 per thread to throttle the | 
| 69 // requests (the value is arbitrarily chosen). | 69 // requests (the value is arbitrarily chosen). | 
| 70 static const size_t kMaxOutstandingRequestsPerThread = 100; | 70 static const size_t kMaxOutstandingRequestsPerThread = 100; | 
| 71 static const double progressNotificationIntervalMS = 50; | 71 static const double progressNotificationIntervalMS = 50; | 
| 72 | 72 | 
| 73 class FileReader::ThrottlingController { | 73 class FileReader::ThrottlingController { | 
| 74 public: | 74 public: | 
| 75 ThrottlingController() : m_maxRunningReaders(kMaxOutstandingRequestsPerThrea d) { } | 75 ThrottlingController() : m_maxRunningReaders(kMaxOutstandingRequestsPerThrea d) { } | 
| 76 ~ThrottlingController() { } | 76 ~ThrottlingController() { } | 
| 77 | 77 | 
| 78 // Final deactivation steps for a FileReader. | |
| 79 class RemovedReader { | |
| 
kinuko
2014/02/21 15:25:48
nit: could we rename RemoveReader to ReaderRemover
 | |
| 80 public: | |
| 81 RemovedReader(FileReader* reader, bool wasRunning) | |
| 
kinuko
2014/02/21 15:25:48
This is internal impl so it's not strongly require
 | |
| 82 : m_reader(reader) | |
| 83 , m_wasRunning(wasRunning) { } | |
| 84 | |
| 85 ~RemovedReader() | |
| 86 { | |
| 87 m_reader->unsetPendingActivity(m_reader); | |
| 88 if (m_wasRunning) | |
| 89 throttlingController()->executeReaders(); | |
| 90 } | |
| 91 | |
| 92 private: | |
| 93 FileReader* m_reader; | |
| 94 bool m_wasRunning; | |
| 95 }; | |
| 96 | |
| 78 void pushReader(FileReader* reader) | 97 void pushReader(FileReader* reader) | 
| 79 { | 98 { | 
| 80 reader->setPendingActivity(reader); | 99 reader->setPendingActivity(reader); | 
| 81 if (m_pendingReaders.isEmpty() | 100 if (m_pendingReaders.isEmpty() | 
| 82 && m_runningReaders.size() < m_maxRunningReaders) { | 101 && m_runningReaders.size() < m_maxRunningReaders) { | 
| 83 reader->executePendingRead(); | 102 reader->executePendingRead(); | 
| 103 ASSERT(!m_runningReaders.contains(reader)); | |
| 84 m_runningReaders.add(reader); | 104 m_runningReaders.add(reader); | 
| 85 return; | 105 return; | 
| 86 } | 106 } | 
| 87 m_pendingReaders.append(reader); | 107 m_pendingReaders.append(reader); | 
| 88 executeReaders(); | 108 executeReaders(); | 
| 89 } | 109 } | 
| 90 | 110 | 
| 91 void removeReader(FileReader* reader) | 111 RemovedReader removeReader(FileReader* reader) | 
| 92 { | 112 { | 
| 93 HashSet<FileReader*>::const_iterator hashIter = m_runningReaders.find(re ader); | 113 HashSet<FileReader*>::const_iterator hashIter = m_runningReaders.find(re ader); | 
| 94 if (hashIter != m_runningReaders.end()) { | 114 if (hashIter != m_runningReaders.end()) { | 
| 95 m_runningReaders.remove(hashIter); | 115 m_runningReaders.remove(hashIter); | 
| 96 reader->unsetPendingActivity(reader); | 116 return RemovedReader(reader, true); | 
| 97 executeReaders(); | |
| 98 return; | |
| 99 } | 117 } | 
| 100 Deque<FileReader*>::const_iterator dequeEnd = m_pendingReaders.end(); | 118 Deque<FileReader*>::const_iterator dequeEnd = m_pendingReaders.end(); | 
| 101 for (Deque<FileReader*>::const_iterator it = m_pendingReaders.begin(); i t != dequeEnd; ++it) { | 119 for (Deque<FileReader*>::const_iterator it = m_pendingReaders.begin(); i t != dequeEnd; ++it) { | 
| 102 if (*it == reader) { | 120 if (*it == reader) { | 
| 103 m_pendingReaders.remove(it); | 121 m_pendingReaders.remove(it); | 
| 104 reader->unsetPendingActivity(reader); | 122 break; | 
| 105 return; | |
| 106 } | 123 } | 
| 107 } | 124 } | 
| 125 return RemovedReader(reader, false); | |
| 108 } | 126 } | 
| 109 | 127 | 
| 110 private: | 128 private: | 
| 111 void executeReaders() | 129 void executeReaders() | 
| 112 { | 130 { | 
| 113 while (m_runningReaders.size() < m_maxRunningReaders) { | 131 while (m_runningReaders.size() < m_maxRunningReaders) { | 
| 114 if (m_pendingReaders.isEmpty()) | 132 if (m_pendingReaders.isEmpty()) | 
| 115 return; | 133 return; | 
| 116 FileReader* reader = m_pendingReaders.takeFirst(); | 134 FileReader* reader = m_pendingReaders.takeFirst(); | 
| 117 reader->executePendingRead(); | 135 reader->executePendingRead(); | 
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 260 } | 278 } | 
| 261 | 279 | 
| 262 void FileReader::doAbort() | 280 void FileReader::doAbort() | 
| 263 { | 281 { | 
| 264 ASSERT(m_state != DONE); | 282 ASSERT(m_state != DONE); | 
| 265 | 283 | 
| 266 terminate(); | 284 terminate(); | 
| 267 | 285 | 
| 268 m_error = FileError::create(FileError::ABORT_ERR); | 286 m_error = FileError::create(FileError::ABORT_ERR); | 
| 269 | 287 | 
| 288 // Unregister the reader (two-phased; see method's result.) | |
| 289 throttlingController()->removeReader(this); | |
| 
kinuko
2014/02/21 15:25:48
Is the intention here is to execute RemoveReader's
 
sof
2014/02/21 15:31:39
No need, the ignored value will be destructed on l
 
kinuko
2014/02/21 15:43:10
Hmm, my very rough local testing doesn't say so...
 | |
| 290 | |
| 270 fireEvent(EventTypeNames::error); | 291 fireEvent(EventTypeNames::error); | 
| 271 fireEvent(EventTypeNames::abort); | 292 fireEvent(EventTypeNames::abort); | 
| 272 fireEvent(EventTypeNames::loadend); | 293 fireEvent(EventTypeNames::loadend); | 
| 273 | 294 | 
| 274 // All possible events have fired and we're done, no more pending activity. | 295 // All possible events have fired and we're done, no more pending activity. | 
| 275 throttlingController()->removeReader(this); | |
| 276 } | 296 } | 
| 277 | 297 | 
| 278 void FileReader::terminate() | 298 void FileReader::terminate() | 
| 279 { | 299 { | 
| 280 if (m_loader) { | 300 if (m_loader) { | 
| 281 m_loader->cancel(); | 301 m_loader->cancel(); | 
| 282 m_loader = nullptr; | 302 m_loader = nullptr; | 
| 283 } | 303 } | 
| 284 m_state = DONE; | 304 m_state = DONE; | 
| 285 m_loadingState = LoadingStateNone; | 305 m_loadingState = LoadingStateNone; | 
| (...skipping 25 matching lines...) Expand all Loading... | |
| 311 // It's important that we change m_loadingState before firing any events | 331 // It's important that we change m_loadingState before firing any events | 
| 312 // since any of the events could call abort(), which internally checks | 332 // since any of the events could call abort(), which internally checks | 
| 313 // if we're still loading (therefore we need abort process) or not. | 333 // if we're still loading (therefore we need abort process) or not. | 
| 314 m_loadingState = LoadingStateNone; | 334 m_loadingState = LoadingStateNone; | 
| 315 | 335 | 
| 316 fireEvent(EventTypeNames::progress); | 336 fireEvent(EventTypeNames::progress); | 
| 317 | 337 | 
| 318 ASSERT(m_state != DONE); | 338 ASSERT(m_state != DONE); | 
| 319 m_state = DONE; | 339 m_state = DONE; | 
| 320 | 340 | 
| 341 // Unregister the reader (two-phased; see method's result.) | |
| 342 throttlingController()->removeReader(this); | |
| 343 | |
| 321 fireEvent(EventTypeNames::load); | 344 fireEvent(EventTypeNames::load); | 
| 322 fireEvent(EventTypeNames::loadend); | 345 fireEvent(EventTypeNames::loadend); | 
| 323 | 346 | 
| 324 // All possible events have fired and we're done, no more pending activity. | 347 // All possible events have fired and we're done, no more pending activity. | 
| 325 throttlingController()->removeReader(this); | |
| 326 } | 348 } | 
| 327 | 349 | 
| 328 void FileReader::didFail(FileError::ErrorCode errorCode) | 350 void FileReader::didFail(FileError::ErrorCode errorCode) | 
| 329 { | 351 { | 
| 330 if (m_loadingState == LoadingStateAborted) | 352 if (m_loadingState == LoadingStateAborted) | 
| 331 return; | 353 return; | 
| 332 ASSERT(m_loadingState == LoadingStateLoading); | 354 ASSERT(m_loadingState == LoadingStateLoading); | 
| 333 m_loadingState = LoadingStateNone; | 355 m_loadingState = LoadingStateNone; | 
| 334 | 356 | 
| 335 ASSERT(m_state != DONE); | 357 ASSERT(m_state != DONE); | 
| 336 m_state = DONE; | 358 m_state = DONE; | 
| 337 | 359 | 
| 338 m_error = FileError::create(static_cast<FileError::ErrorCode>(errorCode)); | 360 m_error = FileError::create(static_cast<FileError::ErrorCode>(errorCode)); | 
| 361 | |
| 362 // Unregister the reader (two-phased; see method's result.) | |
| 363 throttlingController()->removeReader(this); | |
| 364 | |
| 339 fireEvent(EventTypeNames::error); | 365 fireEvent(EventTypeNames::error); | 
| 340 fireEvent(EventTypeNames::loadend); | 366 fireEvent(EventTypeNames::loadend); | 
| 341 | 367 | 
| 342 // All possible events have fired and we're done, no more pending activity. | 368 // All possible events have fired and we're done, no more pending activity. | 
| 343 throttlingController()->removeReader(this); | |
| 344 } | 369 } | 
| 345 | 370 | 
| 346 void FileReader::fireEvent(const AtomicString& type) | 371 void FileReader::fireEvent(const AtomicString& type) | 
| 347 { | 372 { | 
| 348 if (!m_loader) { | 373 if (!m_loader) { | 
| 349 dispatchEvent(ProgressEvent::create(type, false, 0, 0)); | 374 dispatchEvent(ProgressEvent::create(type, false, 0, 0)); | 
| 350 return; | 375 return; | 
| 351 } | 376 } | 
| 352 | 377 | 
| 353 if (m_loader->totalBytes() >= 0) | 378 if (m_loader->totalBytes() >= 0) | 
| (...skipping 16 matching lines...) Expand all Loading... | |
| 370 } | 395 } | 
| 371 | 396 | 
| 372 String FileReader::stringResult() | 397 String FileReader::stringResult() | 
| 373 { | 398 { | 
| 374 if (!m_loader || m_error) | 399 if (!m_loader || m_error) | 
| 375 return String(); | 400 return String(); | 
| 376 return m_loader->stringResult(); | 401 return m_loader->stringResult(); | 
| 377 } | 402 } | 
| 378 | 403 | 
| 379 } // namespace WebCore | 404 } // namespace WebCore | 
| OLD | NEW |