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

Side by Side Diff: third_party/WebKit/Source/modules/fetch/CompositeDataConsumerHandle.cpp

Issue 2177243002: Use per-frame TaskRunner instead of thread's default in DataConsumerHandle (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@data_consumer_handle_unique_ptr
Patch Set: test fix Created 4 years, 4 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "modules/fetch/CompositeDataConsumerHandle.h" 5 #include "modules/fetch/CompositeDataConsumerHandle.h"
6 6
7 #include "platform/CrossThreadFunctional.h" 7 #include "platform/CrossThreadFunctional.h"
8 #include "public/platform/Platform.h" 8 #include "public/platform/Platform.h"
9 #include "public/platform/WebTaskRunner.h" 9 #include "public/platform/WebTaskRunner.h"
10 #include "public/platform/WebThread.h" 10 #include "public/platform/WebThread.h"
(...skipping 19 matching lines...) Expand all
30 private: 30 private:
31 RefPtr<Context> m_context; 31 RefPtr<Context> m_context;
32 }; 32 };
33 33
34 class CompositeDataConsumerHandle::Context final : public ThreadSafeRefCounted<C ontext> { 34 class CompositeDataConsumerHandle::Context final : public ThreadSafeRefCounted<C ontext> {
35 public: 35 public:
36 using Token = unsigned; 36 using Token = unsigned;
37 static PassRefPtr<Context> create(std::unique_ptr<WebDataConsumerHandle> han dle) { return adoptRef(new Context(std::move(handle))); } 37 static PassRefPtr<Context> create(std::unique_ptr<WebDataConsumerHandle> han dle) { return adoptRef(new Context(std::move(handle))); }
38 ~Context() 38 ~Context()
39 { 39 {
40 DCHECK(!m_readerThread); 40 DCHECK(!m_readerTaskRunner);
41 DCHECK(!m_reader); 41 DCHECK(!m_reader);
42 DCHECK(!m_client); 42 DCHECK(!m_client);
43 } 43 }
44 std::unique_ptr<ReaderImpl> obtainReader(Client* client) 44 std::unique_ptr<ReaderImpl> obtainReader(Client* client)
45 { 45 {
46 MutexLocker locker(m_mutex); 46 MutexLocker locker(m_mutex);
47 DCHECK(!m_readerThread); 47 DCHECK(!m_readerTaskRunner);
48 DCHECK(!m_reader); 48 DCHECK(!m_reader);
49 DCHECK(!m_client); 49 DCHECK(!m_client);
50 ++m_token; 50 ++m_token;
51 m_client = client; 51 m_client = client;
52 m_readerThread = Platform::current()->currentThread(); 52 m_readerTaskRunner = client->getTaskRunner()->clone();
53 m_reader = m_handle->obtainReader(m_client); 53 m_reader = m_handle->obtainReader(m_client);
54 return wrapUnique(new ReaderImpl(this)); 54 return wrapUnique(new ReaderImpl(this));
55 } 55 }
56 void detachReader() 56 void detachReader()
57 { 57 {
58 MutexLocker locker(m_mutex); 58 MutexLocker locker(m_mutex);
59 DCHECK(m_readerThread); 59 DCHECK(m_readerTaskRunner);
60 DCHECK(m_readerThread->isCurrentThread()); 60 DCHECK(m_readerTaskRunner->runsTasksOnCurrentThread());
61 DCHECK(m_reader); 61 DCHECK(m_reader);
62 DCHECK(!m_isInTwoPhaseRead); 62 DCHECK(!m_isInTwoPhaseRead);
63 DCHECK(!m_isUpdateWaitingForEndRead); 63 DCHECK(!m_isUpdateWaitingForEndRead);
64 ++m_token; 64 ++m_token;
65 m_reader = nullptr; 65 m_reader = nullptr;
66 m_readerThread = nullptr; 66 m_readerTaskRunner = nullptr;
67 m_client = nullptr; 67 m_client = nullptr;
68 } 68 }
69 void update(std::unique_ptr<WebDataConsumerHandle> handle) 69 void update(std::unique_ptr<WebDataConsumerHandle> handle)
70 { 70 {
71 MutexLocker locker(m_mutex); 71 MutexLocker locker(m_mutex);
72 m_handle = std::move(handle); 72 m_handle = std::move(handle);
73 if (!m_readerThread) { 73 if (!m_readerTaskRunner) {
74 // There is no reader. 74 // There is no reader.
75 return; 75 return;
76 } 76 }
77 ++m_token; 77 ++m_token;
78 updateReaderNoLock(m_token); 78 updateReaderNoLock(m_token);
79 } 79 }
80 80
81 Result read(void* data, size_t size, Flags flags, size_t* readSize) 81 Result read(void* data, size_t size, Flags flags, size_t* readSize)
82 { 82 {
83 DCHECK(m_readerThread && m_readerThread->isCurrentThread()); 83 DCHECK(m_readerTaskRunner && m_readerTaskRunner->runsTasksOnCurrentThrea d());
84 return m_reader->read(data, size, flags, readSize); 84 return m_reader->read(data, size, flags, readSize);
85 } 85 }
86 Result beginRead(const void** buffer, Flags flags, size_t* available) 86 Result beginRead(const void** buffer, Flags flags, size_t* available)
87 { 87 {
88 DCHECK(m_readerThread && m_readerThread->isCurrentThread()); 88 DCHECK(m_readerTaskRunner && m_readerTaskRunner->runsTasksOnCurrentThrea d());
89 DCHECK(!m_isInTwoPhaseRead); 89 DCHECK(!m_isInTwoPhaseRead);
90 Result r = m_reader->beginRead(buffer, flags, available); 90 Result r = m_reader->beginRead(buffer, flags, available);
91 m_isInTwoPhaseRead = (r == Ok); 91 m_isInTwoPhaseRead = (r == Ok);
92 return r; 92 return r;
93 } 93 }
94 Result endRead(size_t readSize) 94 Result endRead(size_t readSize)
95 { 95 {
96 DCHECK(m_readerThread && m_readerThread->isCurrentThread()); 96 DCHECK(m_readerTaskRunner && m_readerTaskRunner->runsTasksOnCurrentThrea d());
97 DCHECK(m_isInTwoPhaseRead); 97 DCHECK(m_isInTwoPhaseRead);
98 Result r = m_reader->endRead(readSize); 98 Result r = m_reader->endRead(readSize);
99 m_isInTwoPhaseRead = false; 99 m_isInTwoPhaseRead = false;
100 if (m_isUpdateWaitingForEndRead) { 100 if (m_isUpdateWaitingForEndRead) {
101 // We need this lock to access |m_handle|. 101 // We need this lock to access |m_handle|.
102 MutexLocker locker(m_mutex); 102 MutexLocker locker(m_mutex);
103 m_reader = nullptr; 103 m_reader = nullptr;
104 m_reader = m_handle->obtainReader(m_client); 104 m_reader = m_handle->obtainReader(m_client);
105 m_isUpdateWaitingForEndRead = false; 105 m_isUpdateWaitingForEndRead = false;
106 } 106 }
107 return r; 107 return r;
108 } 108 }
109 109
110 private: 110 private:
111 explicit Context(std::unique_ptr<WebDataConsumerHandle> handle) 111 explicit Context(std::unique_ptr<WebDataConsumerHandle> handle)
112 : m_handle(std::move(handle)) 112 : m_handle(std::move(handle))
113 , m_readerThread(nullptr) 113 , m_readerTaskRunner(nullptr)
114 , m_client(nullptr) 114 , m_client(nullptr)
115 , m_token(0) 115 , m_token(0)
116 , m_isUpdateWaitingForEndRead(false) 116 , m_isUpdateWaitingForEndRead(false)
117 , m_isInTwoPhaseRead(false) 117 , m_isInTwoPhaseRead(false)
118 { 118 {
119 } 119 }
120 void updateReader(Token token) 120 void updateReader(Token token)
121 { 121 {
122 MutexLocker locker(m_mutex); 122 MutexLocker locker(m_mutex);
123 updateReaderNoLock(token); 123 updateReaderNoLock(token);
124 } 124 }
125 void updateReaderNoLock(Token token) 125 void updateReaderNoLock(Token token)
126 { 126 {
127 if (token != m_token) { 127 if (token != m_token) {
128 // This request is not fresh. Ignore it. 128 // This request is not fresh. Ignore it.
129 return; 129 return;
130 } 130 }
131 DCHECK(m_readerThread); 131 DCHECK(m_readerTaskRunner);
132 DCHECK(m_reader); 132 DCHECK(m_reader);
133 if (m_readerThread->isCurrentThread()) { 133 if (m_readerTaskRunner->runsTasksOnCurrentThread()) {
134 if (m_isInTwoPhaseRead) { 134 if (m_isInTwoPhaseRead) {
135 // We are waiting for the two-phase read completion. 135 // We are waiting for the two-phase read completion.
136 m_isUpdateWaitingForEndRead = true; 136 m_isUpdateWaitingForEndRead = true;
137 return; 137 return;
138 } 138 }
139 // Unregister the old one, then register the new one. 139 // Unregister the old one, then register the new one.
140 m_reader = nullptr; 140 m_reader = nullptr;
141 m_reader = m_handle->obtainReader(m_client); 141 m_reader = m_handle->obtainReader(m_client);
142 return; 142 return;
143 } 143 }
144 ++m_token; 144 ++m_token;
145 m_readerThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, crossThrea dBind(&Context::updateReader, wrapPassRefPtr(this), m_token)); 145 m_readerTaskRunner->postTask(BLINK_FROM_HERE, crossThreadBind(&Context:: updateReader, wrapPassRefPtr(this), m_token));
146 } 146 }
147 147
148 std::unique_ptr<Reader> m_reader; 148 std::unique_ptr<Reader> m_reader;
149 std::unique_ptr<WebDataConsumerHandle> m_handle; 149 std::unique_ptr<WebDataConsumerHandle> m_handle;
150 // Note: Holding a WebThread raw pointer is not generally safe, but we can 150 std::unique_ptr<WebTaskRunner> m_readerTaskRunner;
haraken 2016/07/28 09:19:30 Instead of holding a task runner, can we probably
tzik 2016/07/28 14:45:34 Since m_client is nullable and we need to use it e
151 // do that in this case because:
152 // 1. Destructing a ReaderImpl when the bound thread ends is a user's
153 // responsibility.
154 // 2. |m_readerThread| will never be used after the associated reader is
155 // detached.
156 WebThread* m_readerThread;
157 Client* m_client; 151 Client* m_client;
158 Token m_token; 152 Token m_token;
159 // These boolean values are bound to the reader thread. 153 // These boolean values are bound to the reader thread.
160 bool m_isUpdateWaitingForEndRead; 154 bool m_isUpdateWaitingForEndRead;
161 bool m_isInTwoPhaseRead; 155 bool m_isInTwoPhaseRead;
162 Mutex m_mutex; 156 Mutex m_mutex;
163 }; 157 };
164 158
165 CompositeDataConsumerHandle::ReaderImpl::ReaderImpl(PassRefPtr<Context> context) : m_context(context) { } 159 CompositeDataConsumerHandle::ReaderImpl::ReaderImpl(PassRefPtr<Context> context) : m_context(context) { }
166 160
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 } 204 }
211 205
212 CompositeDataConsumerHandle::~CompositeDataConsumerHandle() { } 206 CompositeDataConsumerHandle::~CompositeDataConsumerHandle() { }
213 207
214 std::unique_ptr<WebDataConsumerHandle::Reader> CompositeDataConsumerHandle::obta inReader(Client* client) 208 std::unique_ptr<WebDataConsumerHandle::Reader> CompositeDataConsumerHandle::obta inReader(Client* client)
215 { 209 {
216 return m_context->obtainReader(client); 210 return m_context->obtainReader(client);
217 } 211 }
218 212
219 } // namespace blink 213 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698