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

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

Issue 395143002: Make FileReader's throttle controller a supplement. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Add assert Created 6 years, 5 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 | « Source/core/fileapi/FileReader.h ('k') | 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 15 matching lines...) Expand all
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 #include "core/fileapi/FileReader.h" 32 #include "core/fileapi/FileReader.h"
33 33
34 #include "bindings/core/v8/ExceptionState.h" 34 #include "bindings/core/v8/ExceptionState.h"
35 #include "core/dom/CrossThreadTask.h" 35 #include "core/dom/CrossThreadTask.h"
36 #include "core/dom/Document.h"
36 #include "core/dom/ExceptionCode.h" 37 #include "core/dom/ExceptionCode.h"
37 #include "core/dom/ExecutionContext.h" 38 #include "core/dom/ExecutionContext.h"
38 #include "core/events/ProgressEvent.h" 39 #include "core/events/ProgressEvent.h"
39 #include "core/fileapi/File.h" 40 #include "core/fileapi/File.h"
41 #include "core/frame/LocalFrame.h"
42 #include "core/workers/WorkerClients.h"
43 #include "core/workers/WorkerGlobalScope.h"
40 #include "platform/Logging.h" 44 #include "platform/Logging.h"
45 #include "platform/Supplementable.h"
41 #include "wtf/ArrayBuffer.h" 46 #include "wtf/ArrayBuffer.h"
42 #include "wtf/CurrentTime.h" 47 #include "wtf/CurrentTime.h"
43 #include "wtf/Deque.h" 48 #include "wtf/Deque.h"
44 #include "wtf/HashSet.h" 49 #include "wtf/HashSet.h"
45 #include "wtf/ThreadSpecific.h" 50 #include "wtf/ThreadSpecific.h"
46 #include "wtf/Threading.h" 51 #include "wtf/Threading.h"
47 #include "wtf/text/CString.h" 52 #include "wtf/text/CString.h"
48 53
49 namespace WebCore { 54 namespace WebCore {
50 55
(...skipping 12 matching lines...) Expand all
63 #endif 68 #endif
64 69
65 } // namespace 70 } // namespace
66 71
67 // Embedders like chromium limit the number of simultaneous requests to avoid 72 // Embedders like chromium limit the number of simultaneous requests to avoid
68 // excessive IPC congestion. We limit this to 100 per thread to throttle the 73 // excessive IPC congestion. We limit this to 100 per thread to throttle the
69 // requests (the value is arbitrarily chosen). 74 // requests (the value is arbitrarily chosen).
70 static const size_t kMaxOutstandingRequestsPerThread = 100; 75 static const size_t kMaxOutstandingRequestsPerThread = 100;
71 static const double progressNotificationIntervalMS = 50; 76 static const double progressNotificationIntervalMS = 50;
72 77
73 class FileReader::ThrottlingController { 78 class FileReader::ThrottlingController FINAL : public NoBaseWillBeGarbageCollect edFinalized<FileReader::ThrottlingController>, public WillBeHeapSupplement<Local Frame>, public WillBeHeapSupplement<WorkerClients> {
79 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(FileReader::ThrottlingController);
74 public: 80 public:
75 ThrottlingController() : m_maxRunningReaders(kMaxOutstandingRequestsPerThrea d) { } 81 static ThrottlingController* from(ExecutionContext* context)
82 {
83 if (context->isDocument()) {
84 Document* document = toDocument(context);
85 if (!document->frame())
86 return 0;
87
88 ThrottlingController* controller = static_cast<ThrottlingController* >(WillBeHeapSupplement<LocalFrame>::from(document->frame(), supplementName()));
89 if (controller)
90 return controller;
91
92 controller = new ThrottlingController();
93 WillBeHeapSupplement<LocalFrame>::provideTo(*document->frame(), supp lementName(), adoptPtrWillBeNoop(controller));
94 return controller;
95 }
96 ASSERT(!isMainThread());
97 ASSERT(context->isWorkerGlobalScope());
98 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
99 ThrottlingController* controller = static_cast<ThrottlingController*>(Wi llBeHeapSupplement<WorkerClients>::from(workerGlobalScope->clients(), supplement Name()));
100 if (controller)
101 return controller;
102
103 controller = new ThrottlingController();
104 WillBeHeapSupplement<WorkerClients>::provideTo(*workerGlobalScope->clien ts(), supplementName(), adoptPtrWillBeNoop(controller));
105 return controller;
106 }
107
76 ~ThrottlingController() { } 108 ~ThrottlingController() { }
77 109
78 enum FinishReaderType { DoNotRunPendingReaders, RunPendingReaders }; 110 enum FinishReaderType { DoNotRunPendingReaders, RunPendingReaders };
79 111
80 void pushReader(FileReader* reader) 112 void pushReader(FileReader* reader)
81 { 113 {
82 if (m_pendingReaders.isEmpty() 114 if (m_pendingReaders.isEmpty()
83 && m_runningReaders.size() < m_maxRunningReaders) { 115 && m_runningReaders.size() < m_maxRunningReaders) {
84 reader->executePendingRead(); 116 reader->executePendingRead();
85 ASSERT(!m_runningReaders.contains(reader)); 117 ASSERT(!m_runningReaders.contains(reader));
86 m_runningReaders.add(reader); 118 m_runningReaders.add(reader);
87 return; 119 return;
88 } 120 }
89 m_pendingReaders.append(reader); 121 m_pendingReaders.append(reader);
90 executeReaders(); 122 executeReaders();
91 } 123 }
92 124
93 FinishReaderType removeReader(FileReader* reader) 125 FinishReaderType removeReader(FileReader* reader)
94 { 126 {
95 HashSet<FileReader*>::const_iterator hashIter = m_runningReaders.find(re ader); 127 WillBeHeapHashSet<RawPtrWillBeMember<FileReader> >::const_iterator hashI ter = m_runningReaders.find(reader);
96 if (hashIter != m_runningReaders.end()) { 128 if (hashIter != m_runningReaders.end()) {
97 m_runningReaders.remove(hashIter); 129 m_runningReaders.remove(hashIter);
98 return RunPendingReaders; 130 return RunPendingReaders;
99 } 131 }
100 Deque<FileReader*>::const_iterator dequeEnd = m_pendingReaders.end(); 132 WillBeHeapDeque<RawPtrWillBeMember<FileReader> >::const_iterator dequeEn d = m_pendingReaders.end();
101 for (Deque<FileReader*>::const_iterator it = m_pendingReaders.begin(); i t != dequeEnd; ++it) { 133 for (WillBeHeapDeque<RawPtrWillBeMember<FileReader> >::const_iterator it = m_pendingReaders.begin(); it != dequeEnd; ++it) {
102 if (*it == reader) { 134 if (*it == reader) {
103 m_pendingReaders.remove(it); 135 m_pendingReaders.remove(it);
104 break; 136 break;
105 } 137 }
106 } 138 }
107 return DoNotRunPendingReaders; 139 return DoNotRunPendingReaders;
108 } 140 }
109 141
110 void finishReader(FileReader* reader, FinishReaderType nextStep) 142 void finishReader(FileReader* reader, FinishReaderType nextStep)
111 { 143 {
112 if (nextStep == RunPendingReaders) 144 if (nextStep == RunPendingReaders)
113 executeReaders(); 145 executeReaders();
114 } 146 }
115 147
148 void trace(Visitor* visitor)
149 {
150 #if ENABLE(OILPAN)
151 visitor->trace(m_pendingReaders);
152 #endif
153 visitor->trace(m_runningReaders);
154 WillBeHeapSupplement<LocalFrame>::trace(visitor);
155 WillBeHeapSupplement<WorkerClients>::trace(visitor);
156 }
157
116 private: 158 private:
159 ThrottlingController()
160 : m_maxRunningReaders(kMaxOutstandingRequestsPerThread)
161 {
162 }
163
117 void executeReaders() 164 void executeReaders()
118 { 165 {
119 while (m_runningReaders.size() < m_maxRunningReaders) { 166 while (m_runningReaders.size() < m_maxRunningReaders) {
120 if (m_pendingReaders.isEmpty()) 167 if (m_pendingReaders.isEmpty())
121 return; 168 return;
122 FileReader* reader = m_pendingReaders.takeFirst(); 169 FileReader* reader = m_pendingReaders.takeFirst();
123 reader->executePendingRead(); 170 reader->executePendingRead();
124 m_runningReaders.add(reader); 171 m_runningReaders.add(reader);
125 } 172 }
126 } 173 }
127 174
175 static const char* supplementName() { return "FileReaderThrottlingController "; }
176
128 const size_t m_maxRunningReaders; 177 const size_t m_maxRunningReaders;
129 Deque<FileReader*> m_pendingReaders; 178 WillBeHeapDeque<RawPtrWillBeMember<FileReader> > m_pendingReaders;
130 HashSet<FileReader*> m_runningReaders; 179 WillBeHeapHashSet<RawPtrWillBeMember<FileReader> > m_runningReaders;
131 }; 180 };
132 181
133 PassRefPtrWillBeRawPtr<FileReader> FileReader::create(ExecutionContext* context) 182 PassRefPtrWillBeRawPtr<FileReader> FileReader::create(ExecutionContext* context)
134 { 183 {
135 RefPtrWillBeRawPtr<FileReader> fileReader(adoptRefWillBeNoop(new FileReader( context))); 184 RefPtrWillBeRawPtr<FileReader> fileReader(adoptRefWillBeNoop(new FileReader( context)));
136 fileReader->suspendIfNeeded(); 185 fileReader->suspendIfNeeded();
137 return fileReader.release(); 186 return fileReader.release();
138 } 187 }
139 188
140 FileReader::FileReader(ExecutionContext* context) 189 FileReader::FileReader(ExecutionContext* context)
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 dispatchEvent(ProgressEvent::create(type, false, 0, 0)); 429 dispatchEvent(ProgressEvent::create(type, false, 0, 0));
381 return; 430 return;
382 } 431 }
383 432
384 if (m_loader->totalBytes() >= 0) 433 if (m_loader->totalBytes() >= 0)
385 dispatchEvent(ProgressEvent::create(type, true, m_loader->bytesLoaded(), m_loader->totalBytes())); 434 dispatchEvent(ProgressEvent::create(type, true, m_loader->bytesLoaded(), m_loader->totalBytes()));
386 else 435 else
387 dispatchEvent(ProgressEvent::create(type, false, m_loader->bytesLoaded() , 0)); 436 dispatchEvent(ProgressEvent::create(type, false, m_loader->bytesLoaded() , 0));
388 } 437 }
389 438
390 ThreadSpecific<FileReader::ThrottlingController>& FileReader::throttlingControll er() 439 FileReader::ThrottlingController* FileReader::throttlingController()
391 { 440 {
392 AtomicallyInitializedStatic(ThreadSpecific<FileReader::ThrottlingController> *, controller = new ThreadSpecific<FileReader::ThrottlingController>); 441 return FileReader::ThrottlingController::from(executionContext());
393 return *controller;
394 } 442 }
395 443
396 PassRefPtr<ArrayBuffer> FileReader::arrayBufferResult() const 444 PassRefPtr<ArrayBuffer> FileReader::arrayBufferResult() const
397 { 445 {
398 if (!m_loader || m_error) 446 if (!m_loader || m_error)
399 return nullptr; 447 return nullptr;
400 return m_loader->arrayBufferResult(); 448 return m_loader->arrayBufferResult();
401 } 449 }
402 450
403 String FileReader::stringResult() 451 String FileReader::stringResult()
404 { 452 {
405 if (!m_loader || m_error) 453 if (!m_loader || m_error)
406 return String(); 454 return String();
407 return m_loader->stringResult(); 455 return m_loader->stringResult();
408 } 456 }
409 457
410 void FileReader::trace(Visitor* visitor) 458 void FileReader::trace(Visitor* visitor)
411 { 459 {
412 visitor->trace(m_error); 460 visitor->trace(m_error);
413 EventTargetWithInlineData::trace(visitor); 461 EventTargetWithInlineData::trace(visitor);
414 } 462 }
415 463
416 } // namespace WebCore 464 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/fileapi/FileReader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698