Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(188)

Side by Side Diff: Source/core/fileapi/FileReader.cpp

Issue 174963002: Finalize a throttled FileReader in stages. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698