Chromium Code Reviews| 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 |