| 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 #ifndef DataConsumerHandleTestUtil_h | 5 #ifndef DataConsumerHandleTestUtil_h |
| 6 #define DataConsumerHandleTestUtil_h | 6 #define DataConsumerHandleTestUtil_h |
| 7 | 7 |
| 8 #include "bindings/core/v8/ScriptState.h" | 8 #include "bindings/core/v8/ScriptState.h" |
| 9 #include "core/testing/NullExecutionContext.h" | 9 #include "core/testing/NullExecutionContext.h" |
| 10 #include "gin/public/isolate_holder.h" | 10 #include "gin/public/isolate_holder.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 #include "wtf/ThreadingPrimitives.h" | 27 #include "wtf/ThreadingPrimitives.h" |
| 28 #include "wtf/Vector.h" | 28 #include "wtf/Vector.h" |
| 29 | 29 |
| 30 #include <gmock/gmock.h> | 30 #include <gmock/gmock.h> |
| 31 #include <gtest/gtest.h> | 31 #include <gtest/gtest.h> |
| 32 #include <v8.h> | 32 #include <v8.h> |
| 33 | 33 |
| 34 namespace blink { | 34 namespace blink { |
| 35 | 35 |
| 36 class DataConsumerHandleTestUtil { | 36 class DataConsumerHandleTestUtil { |
| 37 STATIC_ONLY(DataConsumerHandleTestUtil); |
| 37 public: | 38 public: |
| 38 class NoopClient final : public WebDataConsumerHandle::Client { | 39 class NoopClient final : public WebDataConsumerHandle::Client { |
| 40 DISALLOW_ALLOCATION(); |
| 39 public: | 41 public: |
| 40 void didGetReadable() override { } | 42 void didGetReadable() override { } |
| 41 }; | 43 }; |
| 42 | 44 |
| 43 // Thread has a WebThreadSupportingGC. It initializes / shutdowns | 45 // Thread has a WebThreadSupportingGC. It initializes / shutdowns |
| 44 // additional objects based on the given policy. The constructor and the | 46 // additional objects based on the given policy. The constructor and the |
| 45 // destructor blocks during the setup and the teardown. | 47 // destructor blocks during the setup and the teardown. |
| 46 class Thread final { | 48 class Thread final { |
| 49 WTF_MAKE_FAST_ALLOCATED(Thread); |
| 47 public: | 50 public: |
| 48 // Initialization policy of a thread. | 51 // Initialization policy of a thread. |
| 49 enum InitializationPolicy { | 52 enum InitializationPolicy { |
| 50 // Only garbage collection is supported. | 53 // Only garbage collection is supported. |
| 51 GarbageCollection, | 54 GarbageCollection, |
| 52 // Creating an isolate in addition to GarbageCollection. | 55 // Creating an isolate in addition to GarbageCollection. |
| 53 ScriptExecution, | 56 ScriptExecution, |
| 54 // Creating an execution context in addition to ScriptExecution. | 57 // Creating an execution context in addition to ScriptExecution. |
| 55 WithExecutionContext, | 58 WithExecutionContext, |
| 56 }; | 59 }; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 | 150 |
| 148 // Protects |m_holder|. | 151 // Protects |m_holder|. |
| 149 Mutex m_holderMutex; | 152 Mutex m_holderMutex; |
| 150 // Because Context outlives ThreadHolder, holding a raw pointer | 153 // Because Context outlives ThreadHolder, holding a raw pointer |
| 151 // here is safe. | 154 // here is safe. |
| 152 ThreadHolder* m_holder; | 155 ThreadHolder* m_holder; |
| 153 }; | 156 }; |
| 154 | 157 |
| 155 // The reading/updating threads are alive while ThreadHolder is alive. | 158 // The reading/updating threads are alive while ThreadHolder is alive. |
| 156 class ThreadHolder { | 159 class ThreadHolder { |
| 160 DISALLOW_ALLOCATION(); |
| 157 public: | 161 public: |
| 158 ThreadHolder(ThreadingTestBase* test) | 162 ThreadHolder(ThreadingTestBase* test) |
| 159 : m_context(test->m_context) | 163 : m_context(test->m_context) |
| 160 , m_readingThread(adoptPtr(new Thread("reading thread"))) | 164 , m_readingThread(adoptPtr(new Thread("reading thread"))) |
| 161 , m_updatingThread(adoptPtr(new Thread("updating thread"))) | 165 , m_updatingThread(adoptPtr(new Thread("updating thread"))) |
| 162 { | 166 { |
| 163 m_context->registerThreadHolder(this); | 167 m_context->registerThreadHolder(this); |
| 164 } | 168 } |
| 165 ~ThreadHolder() | 169 ~ThreadHolder() |
| 166 { | 170 { |
| 167 m_context->unregisterThreadHolder(); | 171 m_context->unregisterThreadHolder(); |
| 168 } | 172 } |
| 169 | 173 |
| 170 WebThreadSupportingGC* readingThread() { return m_readingThread->thr
ead(); } | 174 WebThreadSupportingGC* readingThread() { return m_readingThread->thr
ead(); } |
| 171 WebThreadSupportingGC* updatingThread() { return m_updatingThread->t
hread(); } | 175 WebThreadSupportingGC* updatingThread() { return m_updatingThread->t
hread(); } |
| 172 | 176 |
| 173 private: | 177 private: |
| 174 RefPtr<Context> m_context; | 178 RefPtr<Context> m_context; |
| 175 OwnPtr<Thread> m_readingThread; | 179 OwnPtr<Thread> m_readingThread; |
| 176 OwnPtr<Thread> m_updatingThread; | 180 OwnPtr<Thread> m_updatingThread; |
| 177 }; | 181 }; |
| 178 | 182 |
| 179 class ReaderImpl final : public WebDataConsumerHandle::Reader { | 183 class ReaderImpl final : public WebDataConsumerHandle::Reader { |
| 184 WTF_MAKE_FAST_ALLOCATED(ReaderImpl); |
| 180 public: | 185 public: |
| 181 ReaderImpl(const String& name, PassRefPtr<Context> context) : m_name
(name.isolatedCopy()), m_context(context) | 186 ReaderImpl(const String& name, PassRefPtr<Context> context) : m_name
(name.isolatedCopy()), m_context(context) |
| 182 { | 187 { |
| 183 m_context->recordAttach(m_name.isolatedCopy()); | 188 m_context->recordAttach(m_name.isolatedCopy()); |
| 184 } | 189 } |
| 185 ~ReaderImpl() override { m_context->recordDetach(m_name.isolatedCopy
()); } | 190 ~ReaderImpl() override { m_context->recordDetach(m_name.isolatedCopy
()); } |
| 186 | 191 |
| 187 using Result = WebDataConsumerHandle::Result; | 192 using Result = WebDataConsumerHandle::Result; |
| 188 using Flags = WebDataConsumerHandle::Flags; | 193 using Flags = WebDataConsumerHandle::Flags; |
| 189 Result read(void*, size_t, Flags, size_t*) override { return WebData
ConsumerHandle::ShouldWait; } | 194 Result read(void*, size_t, Flags, size_t*) override { return WebData
ConsumerHandle::ShouldWait; } |
| 190 Result beginRead(const void**, Flags, size_t*) override { return Web
DataConsumerHandle::ShouldWait; } | 195 Result beginRead(const void**, Flags, size_t*) override { return Web
DataConsumerHandle::ShouldWait; } |
| 191 Result endRead(size_t) override { return WebDataConsumerHandle::Unex
pectedError; } | 196 Result endRead(size_t) override { return WebDataConsumerHandle::Unex
pectedError; } |
| 192 | 197 |
| 193 private: | 198 private: |
| 194 const String m_name; | 199 const String m_name; |
| 195 RefPtr<Context> m_context; | 200 RefPtr<Context> m_context; |
| 196 }; | 201 }; |
| 197 class DataConsumerHandle final : public WebDataConsumerHandle { | 202 class DataConsumerHandle final : public WebDataConsumerHandle { |
| 203 WTF_MAKE_FAST_ALLOCATED(DataConsumerHandle); |
| 198 public: | 204 public: |
| 199 static PassOwnPtr<WebDataConsumerHandle> create(const String& name,
PassRefPtr<Context> context) | 205 static PassOwnPtr<WebDataConsumerHandle> create(const String& name,
PassRefPtr<Context> context) |
| 200 { | 206 { |
| 201 return adoptPtr(new DataConsumerHandle(name, context)); | 207 return adoptPtr(new DataConsumerHandle(name, context)); |
| 202 } | 208 } |
| 203 | 209 |
| 204 private: | 210 private: |
| 205 DataConsumerHandle(const String& name, PassRefPtr<Context> context)
: m_name(name.isolatedCopy()), m_context(context) { } | 211 DataConsumerHandle(const String& name, PassRefPtr<Context> context)
: m_name(name.isolatedCopy()), m_context(context) { } |
| 206 | 212 |
| 207 Reader* obtainReaderInternal(Client*) { return new ReaderImpl(m_name
, m_context); } | 213 Reader* obtainReaderInternal(Client*) { return new ReaderImpl(m_name
, m_context); } |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 { | 355 { |
| 350 didFetchDataLoadedArrayBufferMock(arrayBuffer); | 356 didFetchDataLoadedArrayBufferMock(arrayBuffer); |
| 351 } | 357 } |
| 352 void didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHan
dle) override | 358 void didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHan
dle) override |
| 353 { | 359 { |
| 354 didFetchDataLoadedBlobHandleMock(blobDataHandle); | 360 didFetchDataLoadedBlobHandleMock(blobDataHandle); |
| 355 } | 361 } |
| 356 }; | 362 }; |
| 357 | 363 |
| 358 class Command final { | 364 class Command final { |
| 365 ALLOW_ONLY_INLINE_ALLOCATION(); |
| 359 public: | 366 public: |
| 360 enum Name { | 367 enum Name { |
| 361 Data, | 368 Data, |
| 362 Done, | 369 Done, |
| 363 Error, | 370 Error, |
| 364 Wait, | 371 Wait, |
| 365 }; | 372 }; |
| 366 | 373 |
| 367 Command(Name name) : m_name(name) { } | 374 Command(Name name) : m_name(name) { } |
| 368 Command(Name name, const Vector<char>& body) : m_name(name), m_body(body
) { } | 375 Command(Name name, const Vector<char>& body) : m_name(name), m_body(body
) { } |
| 369 Command(Name name, const char* body, size_t size) : m_name(name) | 376 Command(Name name, const char* body, size_t size) : m_name(name) |
| 370 { | 377 { |
| 371 m_body.append(body, size); | 378 m_body.append(body, size); |
| 372 } | 379 } |
| 373 Command(Name name, const char* body) : Command(name, body, strlen(body))
{ } | 380 Command(Name name, const char* body) : Command(name, body, strlen(body))
{ } |
| 374 Name name() const { return m_name; } | 381 Name name() const { return m_name; } |
| 375 const Vector<char>& body() const { return m_body; } | 382 const Vector<char>& body() const { return m_body; } |
| 376 | 383 |
| 377 private: | 384 private: |
| 378 const Name m_name; | 385 const Name m_name; |
| 379 Vector<char> m_body; | 386 Vector<char> m_body; |
| 380 }; | 387 }; |
| 381 | 388 |
| 382 // ReplayingHandle stores commands via |add| and replays the stored commends
when read. | 389 // ReplayingHandle stores commands via |add| and replays the stored commends
when read. |
| 383 class ReplayingHandle final : public WebDataConsumerHandle { | 390 class ReplayingHandle final : public WebDataConsumerHandle { |
| 391 WTF_MAKE_FAST_ALLOCATED(ReplayingHandle); |
| 384 public: | 392 public: |
| 385 static PassOwnPtr<ReplayingHandle> create() { return adoptPtr(new Replay
ingHandle()); } | 393 static PassOwnPtr<ReplayingHandle> create() { return adoptPtr(new Replay
ingHandle()); } |
| 386 ~ReplayingHandle(); | 394 ~ReplayingHandle(); |
| 387 | 395 |
| 388 // Add a command to this handle. This function must be called on the | 396 // Add a command to this handle. This function must be called on the |
| 389 // creator thread. This function must be called BEFORE any reader is | 397 // creator thread. This function must be called BEFORE any reader is |
| 390 // obtained. | 398 // obtained. |
| 391 void add(const Command&); | 399 void add(const Command&); |
| 392 | 400 |
| 393 class Context final : public ThreadSafeRefCounted<Context> { | 401 class Context final : public ThreadSafeRefCounted<Context> { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 class ReaderImpl; | 436 class ReaderImpl; |
| 429 | 437 |
| 430 ReplayingHandle(); | 438 ReplayingHandle(); |
| 431 Reader* obtainReaderInternal(Client*) override; | 439 Reader* obtainReaderInternal(Client*) override; |
| 432 const char* debugName() const override { return "ReplayingHandle"; } | 440 const char* debugName() const override { return "ReplayingHandle"; } |
| 433 | 441 |
| 434 RefPtr<Context> m_context; | 442 RefPtr<Context> m_context; |
| 435 }; | 443 }; |
| 436 | 444 |
| 437 class HandleReadResult final { | 445 class HandleReadResult final { |
| 446 WTF_MAKE_FAST_ALLOCATED(HandleReadResult); |
| 438 public: | 447 public: |
| 439 HandleReadResult(WebDataConsumerHandle::Result result, const Vector<char
>& data) : m_result(result), m_data(data) { } | 448 HandleReadResult(WebDataConsumerHandle::Result result, const Vector<char
>& data) : m_result(result), m_data(data) { } |
| 440 WebDataConsumerHandle::Result result() const { return m_result; } | 449 WebDataConsumerHandle::Result result() const { return m_result; } |
| 441 const Vector<char>& data() const { return m_data; } | 450 const Vector<char>& data() const { return m_data; } |
| 442 | 451 |
| 443 private: | 452 private: |
| 444 const WebDataConsumerHandle::Result m_result; | 453 const WebDataConsumerHandle::Result m_result; |
| 445 const Vector<char> m_data; | 454 const Vector<char> m_data; |
| 446 }; | 455 }; |
| 447 | 456 |
| 448 // HandleReader reads all data from the given WebDataConsumerHandle using | 457 // HandleReader reads all data from the given WebDataConsumerHandle using |
| 449 // Reader::read on the thread on which it is created. When reading is done | 458 // Reader::read on the thread on which it is created. When reading is done |
| 450 // or failed, it calls the given callback with the result. | 459 // or failed, it calls the given callback with the result. |
| 451 class HandleReader final : public WebDataConsumerHandle::Client { | 460 class HandleReader final : public WebDataConsumerHandle::Client { |
| 461 WTF_MAKE_FAST_ALLOCATED(HandleReader); |
| 452 public: | 462 public: |
| 453 using OnFinishedReading = WTF::Function<void(PassOwnPtr<HandleReadResult
>)>; | 463 using OnFinishedReading = WTF::Function<void(PassOwnPtr<HandleReadResult
>)>; |
| 454 | 464 |
| 455 HandleReader(PassOwnPtr<WebDataConsumerHandle>, PassOwnPtr<OnFinishedRea
ding>); | 465 HandleReader(PassOwnPtr<WebDataConsumerHandle>, PassOwnPtr<OnFinishedRea
ding>); |
| 456 void didGetReadable() override; | 466 void didGetReadable() override; |
| 457 | 467 |
| 458 private: | 468 private: |
| 459 void runOnFinishedReading(PassOwnPtr<HandleReadResult>); | 469 void runOnFinishedReading(PassOwnPtr<HandleReadResult>); |
| 460 | 470 |
| 461 OwnPtr<WebDataConsumerHandle::Reader> m_reader; | 471 OwnPtr<WebDataConsumerHandle::Reader> m_reader; |
| 462 OwnPtr<OnFinishedReading> m_onFinishedReading; | 472 OwnPtr<OnFinishedReading> m_onFinishedReading; |
| 463 Vector<char> m_data; | 473 Vector<char> m_data; |
| 464 }; | 474 }; |
| 465 | 475 |
| 466 // HandleTwoPhaseReader does the same as HandleReader, but it uses | 476 // HandleTwoPhaseReader does the same as HandleReader, but it uses |
| 467 // |beginRead| / |endRead| instead of |read|. | 477 // |beginRead| / |endRead| instead of |read|. |
| 468 class HandleTwoPhaseReader final : public WebDataConsumerHandle::Client { | 478 class HandleTwoPhaseReader final : public WebDataConsumerHandle::Client { |
| 479 WTF_MAKE_FAST_ALLOCATED(HandleTwoPhaseReader); |
| 469 public: | 480 public: |
| 470 using OnFinishedReading = WTF::Function<void(PassOwnPtr<HandleReadResult
>)>; | 481 using OnFinishedReading = WTF::Function<void(PassOwnPtr<HandleReadResult
>)>; |
| 471 | 482 |
| 472 HandleTwoPhaseReader(PassOwnPtr<WebDataConsumerHandle>, PassOwnPtr<OnFin
ishedReading>); | 483 HandleTwoPhaseReader(PassOwnPtr<WebDataConsumerHandle>, PassOwnPtr<OnFin
ishedReading>); |
| 473 void didGetReadable() override; | 484 void didGetReadable() override; |
| 474 | 485 |
| 475 private: | 486 private: |
| 476 void runOnFinishedReading(PassOwnPtr<HandleReadResult>); | 487 void runOnFinishedReading(PassOwnPtr<HandleReadResult>); |
| 477 | 488 |
| 478 OwnPtr<WebDataConsumerHandle::Reader> m_reader; | 489 OwnPtr<WebDataConsumerHandle::Reader> m_reader; |
| 479 OwnPtr<OnFinishedReading> m_onFinishedReading; | 490 OwnPtr<OnFinishedReading> m_onFinishedReading; |
| 480 Vector<char> m_data; | 491 Vector<char> m_data; |
| 481 }; | 492 }; |
| 482 | 493 |
| 483 // HandleReaderRunner<T> creates a dedicated thread and run T on the thread | 494 // HandleReaderRunner<T> creates a dedicated thread and run T on the thread |
| 484 // where T is one of HandleReader and HandleTwophaseReader. | 495 // where T is one of HandleReader and HandleTwophaseReader. |
| 485 template <typename T> | 496 template <typename T> |
| 486 class HandleReaderRunner final { | 497 class HandleReaderRunner final { |
| 498 STACK_ALLOCATED(); |
| 487 public: | 499 public: |
| 488 explicit HandleReaderRunner(PassOwnPtr<WebDataConsumerHandle> handle) | 500 explicit HandleReaderRunner(PassOwnPtr<WebDataConsumerHandle> handle) |
| 489 : m_thread(adoptPtr(new Thread("reading thread"))) | 501 : m_thread(adoptPtr(new Thread("reading thread"))) |
| 490 , m_event(adoptPtr(Platform::current()->createWaitableEvent())) | 502 , m_event(adoptPtr(Platform::current()->createWaitableEvent())) |
| 491 , m_isDone(false) | 503 , m_isDone(false) |
| 492 { | 504 { |
| 493 m_thread->thread()->postTask(FROM_HERE, new Task(threadSafeBind(&Han
dleReaderRunner::start, AllowCrossThreadAccess(this), handle))); | 505 m_thread->thread()->postTask(FROM_HERE, new Task(threadSafeBind(&Han
dleReaderRunner::start, AllowCrossThreadAccess(this), handle))); |
| 494 } | 506 } |
| 495 ~HandleReaderRunner() | 507 ~HandleReaderRunner() |
| 496 { | 508 { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 524 OwnPtr<HandleReadResult> m_result; | 536 OwnPtr<HandleReadResult> m_result; |
| 525 bool m_isDone; | 537 bool m_isDone; |
| 526 | 538 |
| 527 OwnPtr<T> m_handleReader; | 539 OwnPtr<T> m_handleReader; |
| 528 }; | 540 }; |
| 529 }; | 541 }; |
| 530 | 542 |
| 531 } // namespace blink | 543 } // namespace blink |
| 532 | 544 |
| 533 #endif // DataConsumerHandleTestUtil_h | 545 #endif // DataConsumerHandleTestUtil_h |
| OLD | NEW |