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

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: 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(context->isWorkerGlobalScope());
haraken 2014/07/16 11:37:26 Also add ASSERT(!isMainThread()).
sof 2014/07/16 11:46:19 Done.
97 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
98 ThrottlingController* controller = static_cast<ThrottlingController*>(Wi llBeHeapSupplement<WorkerClients>::from(workerGlobalScope->clients(), supplement Name()));
99 if (controller)
100 return controller;
101
102 controller = new ThrottlingController();
103 WillBeHeapSupplement<WorkerClients>::provideTo(*workerGlobalScope->clien ts(), supplementName(), adoptPtrWillBeNoop(controller));
104 return controller;
105 }
106
76 ~ThrottlingController() { } 107 ~ThrottlingController() { }
77 108
78 enum FinishReaderType { DoNotRunPendingReaders, RunPendingReaders }; 109 enum FinishReaderType { DoNotRunPendingReaders, RunPendingReaders };
79 110
80 void pushReader(FileReader* reader) 111 void pushReader(FileReader* reader)
81 { 112 {
82 if (m_pendingReaders.isEmpty() 113 if (m_pendingReaders.isEmpty()
83 && m_runningReaders.size() < m_maxRunningReaders) { 114 && m_runningReaders.size() < m_maxRunningReaders) {
84 reader->executePendingRead(); 115 reader->executePendingRead();
85 ASSERT(!m_runningReaders.contains(reader)); 116 ASSERT(!m_runningReaders.contains(reader));
86 m_runningReaders.add(reader); 117 m_runningReaders.add(reader);
87 return; 118 return;
88 } 119 }
89 m_pendingReaders.append(reader); 120 m_pendingReaders.append(reader);
90 executeReaders(); 121 executeReaders();
91 } 122 }
92 123
93 FinishReaderType removeReader(FileReader* reader) 124 FinishReaderType removeReader(FileReader* reader)
94 { 125 {
95 HashSet<FileReader*>::const_iterator hashIter = m_runningReaders.find(re ader); 126 WillBeHeapHashSet<RawPtrWillBeMember<FileReader> >::const_iterator hashI ter = m_runningReaders.find(reader);
96 if (hashIter != m_runningReaders.end()) { 127 if (hashIter != m_runningReaders.end()) {
97 m_runningReaders.remove(hashIter); 128 m_runningReaders.remove(hashIter);
98 return RunPendingReaders; 129 return RunPendingReaders;
99 } 130 }
100 Deque<FileReader*>::const_iterator dequeEnd = m_pendingReaders.end(); 131 WillBeHeapDeque<RawPtrWillBeMember<FileReader> >::const_iterator dequeEn d = m_pendingReaders.end();
101 for (Deque<FileReader*>::const_iterator it = m_pendingReaders.begin(); i t != dequeEnd; ++it) { 132 for (WillBeHeapDeque<RawPtrWillBeMember<FileReader> >::const_iterator it = m_pendingReaders.begin(); it != dequeEnd; ++it) {
102 if (*it == reader) { 133 if (*it == reader) {
103 m_pendingReaders.remove(it); 134 m_pendingReaders.remove(it);
104 break; 135 break;
105 } 136 }
106 } 137 }
107 return DoNotRunPendingReaders; 138 return DoNotRunPendingReaders;
108 } 139 }
109 140
110 void finishReader(FileReader* reader, FinishReaderType nextStep) 141 void finishReader(FileReader* reader, FinishReaderType nextStep)
111 { 142 {
112 if (nextStep == RunPendingReaders) 143 if (nextStep == RunPendingReaders)
113 executeReaders(); 144 executeReaders();
114 } 145 }
115 146
147 void trace(Visitor* visitor)
148 {
149 #if ENABLE(OILPAN)
150 visitor->trace(m_pendingReaders);
151 #endif
152 visitor->trace(m_runningReaders);
153 WillBeHeapSupplement<LocalFrame>::trace(visitor);
154 WillBeHeapSupplement<WorkerClients>::trace(visitor);
155 }
156
116 private: 157 private:
158 ThrottlingController()
159 : m_maxRunningReaders(kMaxOutstandingRequestsPerThread)
160 {
161 }
162
117 void executeReaders() 163 void executeReaders()
118 { 164 {
119 while (m_runningReaders.size() < m_maxRunningReaders) { 165 while (m_runningReaders.size() < m_maxRunningReaders) {
120 if (m_pendingReaders.isEmpty()) 166 if (m_pendingReaders.isEmpty())
121 return; 167 return;
122 FileReader* reader = m_pendingReaders.takeFirst(); 168 FileReader* reader = m_pendingReaders.takeFirst();
123 reader->executePendingRead(); 169 reader->executePendingRead();
124 m_runningReaders.add(reader); 170 m_runningReaders.add(reader);
125 } 171 }
126 } 172 }
127 173
174 static const char* supplementName() { return "FileReaderThrottleController"; }
haraken 2014/07/16 11:37:26 "FileReaderThrottlingController"
sof 2014/07/16 11:46:19 Fixed.
175
128 const size_t m_maxRunningReaders; 176 const size_t m_maxRunningReaders;
129 Deque<FileReader*> m_pendingReaders; 177 WillBeHeapDeque<RawPtrWillBeMember<FileReader> > m_pendingReaders;
130 HashSet<FileReader*> m_runningReaders; 178 WillBeHeapHashSet<RawPtrWillBeMember<FileReader> > m_runningReaders;
131 }; 179 };
132 180
133 PassRefPtrWillBeRawPtr<FileReader> FileReader::create(ExecutionContext* context) 181 PassRefPtrWillBeRawPtr<FileReader> FileReader::create(ExecutionContext* context)
134 { 182 {
135 RefPtrWillBeRawPtr<FileReader> fileReader(adoptRefWillBeNoop(new FileReader( context))); 183 RefPtrWillBeRawPtr<FileReader> fileReader(adoptRefWillBeNoop(new FileReader( context)));
136 fileReader->suspendIfNeeded(); 184 fileReader->suspendIfNeeded();
137 return fileReader.release(); 185 return fileReader.release();
138 } 186 }
139 187
140 FileReader::FileReader(ExecutionContext* context) 188 FileReader::FileReader(ExecutionContext* context)
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 dispatchEvent(ProgressEvent::create(type, false, 0, 0)); 428 dispatchEvent(ProgressEvent::create(type, false, 0, 0));
381 return; 429 return;
382 } 430 }
383 431
384 if (m_loader->totalBytes() >= 0) 432 if (m_loader->totalBytes() >= 0)
385 dispatchEvent(ProgressEvent::create(type, true, m_loader->bytesLoaded(), m_loader->totalBytes())); 433 dispatchEvent(ProgressEvent::create(type, true, m_loader->bytesLoaded(), m_loader->totalBytes()));
386 else 434 else
387 dispatchEvent(ProgressEvent::create(type, false, m_loader->bytesLoaded() , 0)); 435 dispatchEvent(ProgressEvent::create(type, false, m_loader->bytesLoaded() , 0));
388 } 436 }
389 437
390 ThreadSpecific<FileReader::ThrottlingController>& FileReader::throttlingControll er() 438 FileReader::ThrottlingController* FileReader::throttlingController()
391 { 439 {
392 AtomicallyInitializedStatic(ThreadSpecific<FileReader::ThrottlingController> *, controller = new ThreadSpecific<FileReader::ThrottlingController>); 440 return FileReader::ThrottlingController::from(executionContext());
393 return *controller;
394 } 441 }
395 442
396 PassRefPtr<ArrayBuffer> FileReader::arrayBufferResult() const 443 PassRefPtr<ArrayBuffer> FileReader::arrayBufferResult() const
397 { 444 {
398 if (!m_loader || m_error) 445 if (!m_loader || m_error)
399 return nullptr; 446 return nullptr;
400 return m_loader->arrayBufferResult(); 447 return m_loader->arrayBufferResult();
401 } 448 }
402 449
403 String FileReader::stringResult() 450 String FileReader::stringResult()
404 { 451 {
405 if (!m_loader || m_error) 452 if (!m_loader || m_error)
406 return String(); 453 return String();
407 return m_loader->stringResult(); 454 return m_loader->stringResult();
408 } 455 }
409 456
410 void FileReader::trace(Visitor* visitor) 457 void FileReader::trace(Visitor* visitor)
411 { 458 {
412 visitor->trace(m_error); 459 visitor->trace(m_error);
413 EventTargetWithInlineData::trace(visitor); 460 EventTargetWithInlineData::trace(visitor);
414 } 461 }
415 462
416 } // namespace WebCore 463 } // 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