| 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 enum FinishReaderType { DoNotRunPendingReaders, RunPendingReaders }; |
| 79 |
| 78 void pushReader(FileReader* reader) | 80 void pushReader(FileReader* reader) |
| 79 { | 81 { |
| 80 reader->setPendingActivity(reader); | 82 reader->setPendingActivity(reader); |
| 81 if (m_pendingReaders.isEmpty() | 83 if (m_pendingReaders.isEmpty() |
| 82 && m_runningReaders.size() < m_maxRunningReaders) { | 84 && m_runningReaders.size() < m_maxRunningReaders) { |
| 83 reader->executePendingRead(); | 85 reader->executePendingRead(); |
| 86 ASSERT(!m_runningReaders.contains(reader)); |
| 84 m_runningReaders.add(reader); | 87 m_runningReaders.add(reader); |
| 85 return; | 88 return; |
| 86 } | 89 } |
| 87 m_pendingReaders.append(reader); | 90 m_pendingReaders.append(reader); |
| 88 executeReaders(); | 91 executeReaders(); |
| 89 } | 92 } |
| 90 | 93 |
| 91 void removeReader(FileReader* reader) | 94 FinishReaderType removeReader(FileReader* reader) |
| 92 { | 95 { |
| 93 HashSet<FileReader*>::const_iterator hashIter = m_runningReaders.find(re
ader); | 96 HashSet<FileReader*>::const_iterator hashIter = m_runningReaders.find(re
ader); |
| 94 if (hashIter != m_runningReaders.end()) { | 97 if (hashIter != m_runningReaders.end()) { |
| 95 m_runningReaders.remove(hashIter); | 98 m_runningReaders.remove(hashIter); |
| 96 reader->unsetPendingActivity(reader); | 99 return RunPendingReaders; |
| 97 executeReaders(); | |
| 98 return; | |
| 99 } | 100 } |
| 100 Deque<FileReader*>::const_iterator dequeEnd = m_pendingReaders.end(); | 101 Deque<FileReader*>::const_iterator dequeEnd = m_pendingReaders.end(); |
| 101 for (Deque<FileReader*>::const_iterator it = m_pendingReaders.begin(); i
t != dequeEnd; ++it) { | 102 for (Deque<FileReader*>::const_iterator it = m_pendingReaders.begin(); i
t != dequeEnd; ++it) { |
| 102 if (*it == reader) { | 103 if (*it == reader) { |
| 103 m_pendingReaders.remove(it); | 104 m_pendingReaders.remove(it); |
| 104 reader->unsetPendingActivity(reader); | 105 break; |
| 105 return; | |
| 106 } | 106 } |
| 107 } | 107 } |
| 108 return DoNotRunPendingReaders; |
| 109 } |
| 110 |
| 111 void finishReader(FileReader* reader, FinishReaderType nextStep) |
| 112 { |
| 113 reader->unsetPendingActivity(reader); |
| 114 if (nextStep == RunPendingReaders) |
| 115 executeReaders(); |
| 108 } | 116 } |
| 109 | 117 |
| 110 private: | 118 private: |
| 111 void executeReaders() | 119 void executeReaders() |
| 112 { | 120 { |
| 113 while (m_runningReaders.size() < m_maxRunningReaders) { | 121 while (m_runningReaders.size() < m_maxRunningReaders) { |
| 114 if (m_pendingReaders.isEmpty()) | 122 if (m_pendingReaders.isEmpty()) |
| 115 return; | 123 return; |
| 116 FileReader* reader = m_pendingReaders.takeFirst(); | 124 FileReader* reader = m_pendingReaders.takeFirst(); |
| 117 reader->executePendingRead(); | 125 reader->executePendingRead(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 147 } | 155 } |
| 148 | 156 |
| 149 const AtomicString& FileReader::interfaceName() const | 157 const AtomicString& FileReader::interfaceName() const |
| 150 { | 158 { |
| 151 return EventTargetNames::FileReader; | 159 return EventTargetNames::FileReader; |
| 152 } | 160 } |
| 153 | 161 |
| 154 void FileReader::stop() | 162 void FileReader::stop() |
| 155 { | 163 { |
| 156 if (m_loadingState == LoadingStateLoading || m_loadingState == LoadingStateP
ending) | 164 if (m_loadingState == LoadingStateLoading || m_loadingState == LoadingStateP
ending) |
| 157 throttlingController()->removeReader(this); | 165 throttlingController()->finishReader(this, throttlingController()->remov
eReader(this)); |
| 158 terminate(); | 166 terminate(); |
| 159 } | 167 } |
| 160 | 168 |
| 161 void FileReader::readAsArrayBuffer(Blob* blob, ExceptionState& exceptionState) | 169 void FileReader::readAsArrayBuffer(Blob* blob, ExceptionState& exceptionState) |
| 162 { | 170 { |
| 163 if (!blob) { | 171 if (!blob) { |
| 164 exceptionState.throwTypeError("The argument is not a Blob."); | 172 exceptionState.throwTypeError("The argument is not a Blob."); |
| 165 return; | 173 return; |
| 166 } | 174 } |
| 167 | 175 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 } | 268 } |
| 261 | 269 |
| 262 void FileReader::doAbort() | 270 void FileReader::doAbort() |
| 263 { | 271 { |
| 264 ASSERT(m_state != DONE); | 272 ASSERT(m_state != DONE); |
| 265 | 273 |
| 266 terminate(); | 274 terminate(); |
| 267 | 275 |
| 268 m_error = FileError::create(FileError::ABORT_ERR); | 276 m_error = FileError::create(FileError::ABORT_ERR); |
| 269 | 277 |
| 278 // Unregister the reader. |
| 279 ThrottlingController::FinishReaderType finalStep = throttlingController()->r
emoveReader(this); |
| 280 |
| 270 fireEvent(EventTypeNames::error); | 281 fireEvent(EventTypeNames::error); |
| 271 fireEvent(EventTypeNames::abort); | 282 fireEvent(EventTypeNames::abort); |
| 272 fireEvent(EventTypeNames::loadend); | 283 fireEvent(EventTypeNames::loadend); |
| 273 | 284 |
| 274 // All possible events have fired and we're done, no more pending activity. | 285 // All possible events have fired and we're done, no more pending activity. |
| 275 throttlingController()->removeReader(this); | 286 throttlingController()->finishReader(this, finalStep); |
| 276 } | 287 } |
| 277 | 288 |
| 278 void FileReader::terminate() | 289 void FileReader::terminate() |
| 279 { | 290 { |
| 280 if (m_loader) { | 291 if (m_loader) { |
| 281 m_loader->cancel(); | 292 m_loader->cancel(); |
| 282 m_loader = nullptr; | 293 m_loader = nullptr; |
| 283 } | 294 } |
| 284 m_state = DONE; | 295 m_state = DONE; |
| 285 m_loadingState = LoadingStateNone; | 296 m_loadingState = LoadingStateNone; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 311 // It's important that we change m_loadingState before firing any events | 322 // It's important that we change m_loadingState before firing any events |
| 312 // since any of the events could call abort(), which internally checks | 323 // since any of the events could call abort(), which internally checks |
| 313 // if we're still loading (therefore we need abort process) or not. | 324 // if we're still loading (therefore we need abort process) or not. |
| 314 m_loadingState = LoadingStateNone; | 325 m_loadingState = LoadingStateNone; |
| 315 | 326 |
| 316 fireEvent(EventTypeNames::progress); | 327 fireEvent(EventTypeNames::progress); |
| 317 | 328 |
| 318 ASSERT(m_state != DONE); | 329 ASSERT(m_state != DONE); |
| 319 m_state = DONE; | 330 m_state = DONE; |
| 320 | 331 |
| 332 // Unregister the reader. |
| 333 ThrottlingController::FinishReaderType finalStep = throttlingController()->r
emoveReader(this); |
| 334 |
| 321 fireEvent(EventTypeNames::load); | 335 fireEvent(EventTypeNames::load); |
| 322 fireEvent(EventTypeNames::loadend); | 336 fireEvent(EventTypeNames::loadend); |
| 323 | 337 |
| 324 // All possible events have fired and we're done, no more pending activity. | 338 // All possible events have fired and we're done, no more pending activity. |
| 325 throttlingController()->removeReader(this); | 339 throttlingController()->finishReader(this, finalStep); |
| 326 } | 340 } |
| 327 | 341 |
| 328 void FileReader::didFail(FileError::ErrorCode errorCode) | 342 void FileReader::didFail(FileError::ErrorCode errorCode) |
| 329 { | 343 { |
| 330 if (m_loadingState == LoadingStateAborted) | 344 if (m_loadingState == LoadingStateAborted) |
| 331 return; | 345 return; |
| 332 ASSERT(m_loadingState == LoadingStateLoading); | 346 ASSERT(m_loadingState == LoadingStateLoading); |
| 333 m_loadingState = LoadingStateNone; | 347 m_loadingState = LoadingStateNone; |
| 334 | 348 |
| 335 ASSERT(m_state != DONE); | 349 ASSERT(m_state != DONE); |
| 336 m_state = DONE; | 350 m_state = DONE; |
| 337 | 351 |
| 338 m_error = FileError::create(static_cast<FileError::ErrorCode>(errorCode)); | 352 m_error = FileError::create(static_cast<FileError::ErrorCode>(errorCode)); |
| 353 |
| 354 // Unregister the reader. |
| 355 ThrottlingController::FinishReaderType finalStep = throttlingController()->r
emoveReader(this); |
| 356 |
| 339 fireEvent(EventTypeNames::error); | 357 fireEvent(EventTypeNames::error); |
| 340 fireEvent(EventTypeNames::loadend); | 358 fireEvent(EventTypeNames::loadend); |
| 341 | 359 |
| 342 // All possible events have fired and we're done, no more pending activity. | 360 // All possible events have fired and we're done, no more pending activity. |
| 343 throttlingController()->removeReader(this); | 361 throttlingController()->finishReader(this, finalStep); |
| 344 } | 362 } |
| 345 | 363 |
| 346 void FileReader::fireEvent(const AtomicString& type) | 364 void FileReader::fireEvent(const AtomicString& type) |
| 347 { | 365 { |
| 348 if (!m_loader) { | 366 if (!m_loader) { |
| 349 dispatchEvent(ProgressEvent::create(type, false, 0, 0)); | 367 dispatchEvent(ProgressEvent::create(type, false, 0, 0)); |
| 350 return; | 368 return; |
| 351 } | 369 } |
| 352 | 370 |
| 353 if (m_loader->totalBytes() >= 0) | 371 if (m_loader->totalBytes() >= 0) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 370 } | 388 } |
| 371 | 389 |
| 372 String FileReader::stringResult() | 390 String FileReader::stringResult() |
| 373 { | 391 { |
| 374 if (!m_loader || m_error) | 392 if (!m_loader || m_error) |
| 375 return String(); | 393 return String(); |
| 376 return m_loader->stringResult(); | 394 return m_loader->stringResult(); |
| 377 } | 395 } |
| 378 | 396 |
| 379 } // namespace WebCore | 397 } // namespace WebCore |
| OLD | NEW |