| OLD | NEW |
| 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 "config.h" | 5 #include "config.h" |
| 6 #include "modules/fetch/DataConsumerHandleTestUtil.h" | 6 #include "modules/fetch/DataConsumerHandleTestUtil.h" |
| 7 | 7 |
| 8 #include "bindings/core/v8/DOMWrapperWorld.h" | 8 #include "bindings/core/v8/DOMWrapperWorld.h" |
| 9 | 9 |
| 10 namespace blink { | 10 namespace blink { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 m_executionContext = nullptr; | 46 m_executionContext = nullptr; |
| 47 m_scriptState = nullptr; | 47 m_scriptState = nullptr; |
| 48 m_thread->shutdown(); | 48 m_thread->shutdown(); |
| 49 if (m_isolateHolder) { | 49 if (m_isolateHolder) { |
| 50 isolate()->Exit(); | 50 isolate()->Exit(); |
| 51 m_isolateHolder = nullptr; | 51 m_isolateHolder = nullptr; |
| 52 } | 52 } |
| 53 m_waitableEvent->signal(); | 53 m_waitableEvent->signal(); |
| 54 } | 54 } |
| 55 | 55 |
| 56 class DataConsumerHandleTestUtil::ReplayingHandle::ReaderImpl final : public Rea
der { |
| 57 public: |
| 58 ReaderImpl(PassRefPtr<Context> context, Client* client) |
| 59 : m_context(context) |
| 60 { |
| 61 m_context->attachReader(client); |
| 62 } |
| 63 ~ReaderImpl() |
| 64 { |
| 65 m_context->detachReader(); |
| 66 } |
| 67 |
| 68 Result read(void* buffer, size_t size, Flags flags, size_t* readSize) overri
de |
| 69 { |
| 70 const void* src = nullptr; |
| 71 Result result = beginRead(&src, flags, readSize); |
| 72 if (result != Ok) |
| 73 return result; |
| 74 *readSize = std::min(*readSize, size); |
| 75 memcpy(buffer, src, *readSize); |
| 76 return endRead(*readSize); |
| 77 } |
| 78 Result beginRead(const void** buffer, Flags flags, size_t* available) overri
de |
| 79 { |
| 80 return m_context->beginRead(buffer, flags, available); |
| 81 } |
| 82 Result endRead(size_t readSize) override |
| 83 { |
| 84 return m_context->endRead(readSize); |
| 85 } |
| 86 |
| 87 private: |
| 88 RefPtr<Context> m_context; |
| 89 }; |
| 90 |
| 91 void DataConsumerHandleTestUtil::ReplayingHandle::Context::add(const Command& co
mmand) |
| 92 { |
| 93 MutexLocker locker(m_mutex); |
| 94 m_commands.append(command); |
| 95 } |
| 96 |
| 97 void DataConsumerHandleTestUtil::ReplayingHandle::Context::attachReader(WebDataC
onsumerHandle::Client* client) |
| 98 { |
| 99 MutexLocker locker(m_mutex); |
| 100 ASSERT(!m_readerThread); |
| 101 ASSERT(!m_client); |
| 102 m_readerThread = Platform::current()->currentThread(); |
| 103 m_client = client; |
| 104 |
| 105 if (m_client && !(isEmpty() && m_result == ShouldWait)) |
| 106 notify(); |
| 107 } |
| 108 |
| 109 void DataConsumerHandleTestUtil::ReplayingHandle::Context::detachReader() |
| 110 { |
| 111 MutexLocker locker(m_mutex); |
| 112 ASSERT(m_readerThread && m_readerThread->isCurrentThread()); |
| 113 m_readerThread = nullptr; |
| 114 m_client = nullptr; |
| 115 if (!m_isHandleAttached) |
| 116 m_detached->signal(); |
| 117 } |
| 118 |
| 119 void DataConsumerHandleTestUtil::ReplayingHandle::Context::detachHandle() |
| 120 { |
| 121 MutexLocker locker(m_mutex); |
| 122 m_isHandleAttached = false; |
| 123 if (!m_readerThread) |
| 124 m_detached->signal(); |
| 125 } |
| 126 |
| 127 WebDataConsumerHandle::Result DataConsumerHandleTestUtil::ReplayingHandle::Conte
xt::beginRead(const void** buffer, Flags, size_t* available) |
| 128 { |
| 129 MutexLocker locker(m_mutex); |
| 130 *buffer = nullptr; |
| 131 *available = 0; |
| 132 if (isEmpty()) |
| 133 return m_result; |
| 134 |
| 135 const Command& command = top(); |
| 136 Result result = Ok; |
| 137 switch (command.name()) { |
| 138 case Command::Data: { |
| 139 auto& body = command.body(); |
| 140 *available = body.size() - offset(); |
| 141 *buffer = body.data() + offset(); |
| 142 result = Ok; |
| 143 break; |
| 144 } |
| 145 case Command::Done: |
| 146 m_result = result = Done; |
| 147 consume(0); |
| 148 break; |
| 149 case Command::Wait: |
| 150 consume(0); |
| 151 result = ShouldWait; |
| 152 notify(); |
| 153 break; |
| 154 case Command::Error: |
| 155 m_result = result = UnexpectedError; |
| 156 consume(0); |
| 157 break; |
| 158 } |
| 159 return result; |
| 160 } |
| 161 |
| 162 WebDataConsumerHandle::Result DataConsumerHandleTestUtil::ReplayingHandle::Conte
xt::endRead(size_t readSize) |
| 163 { |
| 164 MutexLocker locker(m_mutex); |
| 165 consume(readSize); |
| 166 return Ok; |
| 167 } |
| 168 |
| 169 DataConsumerHandleTestUtil::ReplayingHandle::Context::Context() |
| 170 : m_offset(0) |
| 171 , m_readerThread(nullptr) |
| 172 , m_client(nullptr) |
| 173 , m_result(ShouldWait) |
| 174 , m_isHandleAttached(true) |
| 175 , m_detached(adoptPtr(Platform::current()->createWaitableEvent())) |
| 176 { |
| 177 } |
| 178 |
| 179 const DataConsumerHandleTestUtil::Command& DataConsumerHandleTestUtil::Replaying
Handle::Context::top() |
| 180 { |
| 181 ASSERT(!isEmpty()); |
| 182 return m_commands.first(); |
| 183 } |
| 184 |
| 185 void DataConsumerHandleTestUtil::ReplayingHandle::Context::consume(size_t size) |
| 186 { |
| 187 ASSERT(!isEmpty()); |
| 188 ASSERT(size + m_offset <= top().body().size()); |
| 189 bool fullyConsumed = (size + m_offset >= top().body().size()); |
| 190 if (fullyConsumed) { |
| 191 m_offset = 0; |
| 192 m_commands.removeFirst(); |
| 193 } else { |
| 194 m_offset += size; |
| 195 } |
| 196 } |
| 197 |
| 198 void DataConsumerHandleTestUtil::ReplayingHandle::Context::notify() |
| 199 { |
| 200 if (!m_client) |
| 201 return; |
| 202 ASSERT(m_readerThread); |
| 203 m_readerThread->postTask(FROM_HERE, new Task(threadSafeBind(&Context::notify
Internal, this))); |
| 204 } |
| 205 |
| 206 void DataConsumerHandleTestUtil::ReplayingHandle::Context::notifyInternal() |
| 207 { |
| 208 { |
| 209 MutexLocker locker(m_mutex); |
| 210 if (!m_client || !m_readerThread->isCurrentThread()) { |
| 211 // There is no client, or a new reader is attached. |
| 212 return; |
| 213 } |
| 214 } |
| 215 // The reading thread is the current thread. |
| 216 m_client->didGetReadable(); |
| 217 } |
| 218 |
| 219 DataConsumerHandleTestUtil::ReplayingHandle::ReplayingHandle() |
| 220 : m_context(Context::create()) |
| 221 { |
| 222 } |
| 223 |
| 224 DataConsumerHandleTestUtil::ReplayingHandle::~ReplayingHandle() |
| 225 { |
| 226 m_context->detachHandle(); |
| 227 } |
| 228 |
| 229 WebDataConsumerHandle::Reader* DataConsumerHandleTestUtil::ReplayingHandle::obta
inReaderInternal(Client* client) |
| 230 { |
| 231 return new ReaderImpl(m_context, client); |
| 232 } |
| 233 |
| 234 void DataConsumerHandleTestUtil::ReplayingHandle::add(const Command& command) |
| 235 { |
| 236 m_context->add(command); |
| 237 } |
| 238 |
| 56 } // namespace blink | 239 } // namespace blink |
| OLD | NEW |