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 |