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 |