| 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 20 matching lines...) Expand all Loading... |
| 31 | 31 |
| 32 namespace blink { | 32 namespace blink { |
| 33 | 33 |
| 34 class DataConsumerHandleTestUtil { | 34 class DataConsumerHandleTestUtil { |
| 35 STATIC_ONLY(DataConsumerHandleTestUtil); | 35 STATIC_ONLY(DataConsumerHandleTestUtil); |
| 36 public: | 36 public: |
| 37 class NoopClient final : public WebDataConsumerHandle::Client { | 37 class NoopClient final : public WebDataConsumerHandle::Client { |
| 38 DISALLOW_NEW(); | 38 DISALLOW_NEW(); |
| 39 public: | 39 public: |
| 40 void didGetReadable() override { } | 40 void didGetReadable() override { } |
| 41 WebTaskRunner* getTaskRunner() override |
| 42 { |
| 43 return Platform::current()->currentThread()->getWebTaskRunner(); |
| 44 } |
| 41 }; | 45 }; |
| 42 | 46 |
| 43 // Thread has a WebThreadSupportingGC. It initializes / shutdowns | 47 // Thread has a WebThreadSupportingGC. It initializes / shutdowns |
| 44 // additional objects based on the given policy. The constructor and the | 48 // additional objects based on the given policy. The constructor and the |
| 45 // destructor blocks during the setup and the teardown. | 49 // destructor blocks during the setup and the teardown. |
| 46 class Thread final { | 50 class Thread final { |
| 47 USING_FAST_MALLOC(Thread); | 51 USING_FAST_MALLOC(Thread); |
| 48 public: | 52 public: |
| 49 // Initialization policy of a thread. | 53 // Initialization policy of a thread. |
| 50 enum InitializationPolicy { | 54 enum InitializationPolicy { |
| 51 // Only garbage collection is supported. | 55 // Only garbage collection is supported. |
| 52 GarbageCollection, | 56 GarbageCollection, |
| 53 // Creating an isolate in addition to GarbageCollection. | 57 // Creating an isolate in addition to GarbageCollection. |
| 54 ScriptExecution, | 58 ScriptExecution, |
| 55 // Creating an execution context in addition to ScriptExecution. | 59 // Creating an execution context in addition to ScriptExecution. |
| 56 WithExecutionContext, | 60 WithExecutionContext, |
| 57 }; | 61 }; |
| 58 | 62 |
| 59 Thread(const char* name, InitializationPolicy = GarbageCollection); | 63 Thread(const char* name, InitializationPolicy = GarbageCollection); |
| 60 ~Thread(); | 64 ~Thread(); |
| 61 | 65 |
| 62 WebThreadSupportingGC* thread() { return m_thread.get(); } | 66 WebThreadSupportingGC* thread() { return m_thread.get(); } |
| 67 WebTaskRunner* taskRunner() { return m_thread->platformThread().getWebTa
skRunner(); } |
| 63 ExecutionContext* getExecutionContext() { return m_executionContext.get(
); } | 68 ExecutionContext* getExecutionContext() { return m_executionContext.get(
); } |
| 64 ScriptState* getScriptState() { return m_scriptState.get(); } | 69 ScriptState* getScriptState() { return m_scriptState.get(); } |
| 65 v8::Isolate* isolate() { return m_isolateHolder->isolate(); } | 70 v8::Isolate* isolate() { return m_isolateHolder->isolate(); } |
| 66 | 71 |
| 67 private: | 72 private: |
| 68 void initialize(); | 73 void initialize(); |
| 69 void shutdown(); | 74 void shutdown(); |
| 70 | 75 |
| 71 std::unique_ptr<WebThreadSupportingGC> m_thread; | 76 std::unique_ptr<WebThreadSupportingGC> m_thread; |
| 72 const InitializationPolicy m_initializationPolicy; | 77 const InitializationPolicy m_initializationPolicy; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 ASSERT(m_holder); | 125 ASSERT(m_holder); |
| 121 m_holder->readingThread()->postTask(location, std::move(task)); | 126 m_holder->readingThread()->postTask(location, std::move(task)); |
| 122 } | 127 } |
| 123 void postTaskToUpdatingThread(const WebTraceLocation& location, std:
:unique_ptr<CrossThreadClosure> task) | 128 void postTaskToUpdatingThread(const WebTraceLocation& location, std:
:unique_ptr<CrossThreadClosure> task) |
| 124 { | 129 { |
| 125 MutexLocker locker(m_holderMutex); | 130 MutexLocker locker(m_holderMutex); |
| 126 ASSERT(m_holder); | 131 ASSERT(m_holder); |
| 127 m_holder->updatingThread()->postTask(location, std::move(task)); | 132 m_holder->updatingThread()->postTask(location, std::move(task)); |
| 128 } | 133 } |
| 129 | 134 |
| 135 WebTaskRunner* getReadingThreadTaskRunner() |
| 136 { |
| 137 return m_holder->readingThread()->platformThread().getWebTaskRun
ner(); |
| 138 } |
| 139 |
| 130 private: | 140 private: |
| 131 Context() | 141 Context() |
| 132 : m_holder(nullptr) { } | 142 : m_holder(nullptr) { } |
| 133 String currentThreadName() | 143 String currentThreadName() |
| 134 { | 144 { |
| 135 MutexLocker locker(m_holderMutex); | 145 MutexLocker locker(m_holderMutex); |
| 136 if (m_holder) { | 146 if (m_holder) { |
| 137 if (m_holder->readingThread()->isCurrentThread()) | 147 if (m_holder->readingThread()->isCurrentThread()) |
| 138 return "the reading thread"; | 148 return "the reading thread"; |
| 139 if (m_holder->updatingThread()->isCurrentThread()) | 149 if (m_holder->updatingThread()->isCurrentThread()) |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 ThreadingHandleNotificationTest() = default; | 273 ThreadingHandleNotificationTest() = default; |
| 264 void obtainReader() | 274 void obtainReader() |
| 265 { | 275 { |
| 266 m_reader = m_handle->obtainReader(this); | 276 m_reader = m_handle->obtainReader(this); |
| 267 } | 277 } |
| 268 void didGetReadable() override | 278 void didGetReadable() override |
| 269 { | 279 { |
| 270 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::rese
tReader, wrapPassRefPtr(this))); | 280 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::rese
tReader, wrapPassRefPtr(this))); |
| 271 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::sign
alDone, wrapPassRefPtr(this))); | 281 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::sign
alDone, wrapPassRefPtr(this))); |
| 272 } | 282 } |
| 283 WebTaskRunner* getTaskRunner() override |
| 284 { |
| 285 return m_context->getReadingThreadTaskRunner(); |
| 286 } |
| 273 | 287 |
| 274 std::unique_ptr<WebDataConsumerHandle> m_handle; | 288 std::unique_ptr<WebDataConsumerHandle> m_handle; |
| 275 }; | 289 }; |
| 276 | 290 |
| 277 class ThreadingHandleNoNotificationTest : public ThreadingTestBase, public W
ebDataConsumerHandle::Client { | 291 class ThreadingHandleNoNotificationTest : public ThreadingTestBase, public W
ebDataConsumerHandle::Client { |
| 278 public: | 292 public: |
| 279 using Self = ThreadingHandleNoNotificationTest; | 293 using Self = ThreadingHandleNoNotificationTest; |
| 280 static PassRefPtr<Self> create() { return adoptRef(new Self); } | 294 static PassRefPtr<Self> create() { return adoptRef(new Self); } |
| 281 | 295 |
| 282 void run(std::unique_ptr<WebDataConsumerHandle> handle) | 296 void run(std::unique_ptr<WebDataConsumerHandle> handle) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 293 void obtainReader() | 307 void obtainReader() |
| 294 { | 308 { |
| 295 m_reader = m_handle->obtainReader(this); | 309 m_reader = m_handle->obtainReader(this); |
| 296 m_reader = nullptr; | 310 m_reader = nullptr; |
| 297 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::sign
alDone, wrapPassRefPtr(this))); | 311 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::sign
alDone, wrapPassRefPtr(this))); |
| 298 } | 312 } |
| 299 void didGetReadable() override | 313 void didGetReadable() override |
| 300 { | 314 { |
| 301 ASSERT_NOT_REACHED(); | 315 ASSERT_NOT_REACHED(); |
| 302 } | 316 } |
| 317 WebTaskRunner* getTaskRunner() override |
| 318 { |
| 319 return m_context->getReadingThreadTaskRunner(); |
| 320 } |
| 303 | 321 |
| 304 std::unique_ptr<WebDataConsumerHandle> m_handle; | 322 std::unique_ptr<WebDataConsumerHandle> m_handle; |
| 305 }; | 323 }; |
| 306 | 324 |
| 307 class MockFetchDataConsumerHandle : public FetchDataConsumerHandle { | 325 class MockFetchDataConsumerHandle : public FetchDataConsumerHandle { |
| 308 public: | 326 public: |
| 309 static std::unique_ptr<::testing::StrictMock<MockFetchDataConsumerHandle
>> create() { return wrapUnique(new ::testing::StrictMock<MockFetchDataConsumerH
andle>); } | 327 static std::unique_ptr<::testing::StrictMock<MockFetchDataConsumerHandle
>> create() { return wrapUnique(new ::testing::StrictMock<MockFetchDataConsumerH
andle>); } |
| 310 MOCK_METHOD1(obtainFetchDataReader, std::unique_ptr<Reader>(Client*)); | 328 MOCK_METHOD1(obtainFetchDataReader, std::unique_ptr<Reader>(Client*)); |
| 311 | 329 |
| 312 private: | 330 private: |
| (...skipping 26 matching lines...) Expand all Loading... |
| 339 DEFINE_INLINE_VIRTUAL_TRACE() | 357 DEFINE_INLINE_VIRTUAL_TRACE() |
| 340 { | 358 { |
| 341 FetchDataLoader::Client::trace(visitor); | 359 FetchDataLoader::Client::trace(visitor); |
| 342 } | 360 } |
| 343 | 361 |
| 344 MOCK_METHOD1(didFetchDataLoadedBlobHandleMock, void(RefPtr<BlobDataHandl
e>)); | 362 MOCK_METHOD1(didFetchDataLoadedBlobHandleMock, void(RefPtr<BlobDataHandl
e>)); |
| 345 MOCK_METHOD1(didFetchDataLoadedArrayBufferMock, void(DOMArrayBuffer*)); | 363 MOCK_METHOD1(didFetchDataLoadedArrayBufferMock, void(DOMArrayBuffer*)); |
| 346 MOCK_METHOD1(didFetchDataLoadedString, void(const String&)); | 364 MOCK_METHOD1(didFetchDataLoadedString, void(const String&)); |
| 347 MOCK_METHOD0(didFetchDataLoadStream, void()); | 365 MOCK_METHOD0(didFetchDataLoadStream, void()); |
| 348 MOCK_METHOD0(didFetchDataLoadFailed, void()); | 366 MOCK_METHOD0(didFetchDataLoadFailed, void()); |
| 367 MOCK_METHOD0(getTaskRunner, WebTaskRunner*()); |
| 349 | 368 |
| 350 void didFetchDataLoadedArrayBuffer(DOMArrayBuffer* arrayBuffer) override | 369 void didFetchDataLoadedArrayBuffer(DOMArrayBuffer* arrayBuffer) override |
| 351 { | 370 { |
| 352 didFetchDataLoadedArrayBufferMock(arrayBuffer); | 371 didFetchDataLoadedArrayBufferMock(arrayBuffer); |
| 353 } | 372 } |
| 354 // In mock methods we use RefPtr<> rather than PassRefPtr<>. | 373 // In mock methods we use RefPtr<> rather than PassRefPtr<>. |
| 355 void didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHan
dle) override | 374 void didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHan
dle) override |
| 356 { | 375 { |
| 357 didFetchDataLoadedBlobHandleMock(blobDataHandle); | 376 didFetchDataLoadedBlobHandleMock(blobDataHandle); |
| 358 } | 377 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 Context(); | 431 Context(); |
| 413 bool isEmpty() const { return m_commands.isEmpty(); } | 432 bool isEmpty() const { return m_commands.isEmpty(); } |
| 414 const Command& top(); | 433 const Command& top(); |
| 415 void consume(size_t); | 434 void consume(size_t); |
| 416 size_t offset() const { return m_offset; } | 435 size_t offset() const { return m_offset; } |
| 417 void notify(); | 436 void notify(); |
| 418 void notifyInternal(); | 437 void notifyInternal(); |
| 419 | 438 |
| 420 Deque<Command> m_commands; | 439 Deque<Command> m_commands; |
| 421 size_t m_offset; | 440 size_t m_offset; |
| 422 WebThread* m_readerThread; | 441 std::unique_ptr<WebTaskRunner> m_readerTaskRunner; |
| 423 Client* m_client; | 442 Client* m_client; |
| 424 Result m_result; | 443 Result m_result; |
| 425 bool m_isHandleAttached; | 444 bool m_isHandleAttached; |
| 426 Mutex m_mutex; | 445 Mutex m_mutex; |
| 427 std::unique_ptr<WaitableEvent> m_detached; | 446 std::unique_ptr<WaitableEvent> m_detached; |
| 428 }; | 447 }; |
| 429 | 448 |
| 430 Context* getContext() { return m_context.get(); } | 449 Context* getContext() { return m_context.get(); } |
| 431 std::unique_ptr<Reader> obtainReader(Client*) override; | 450 std::unique_ptr<Reader> obtainReader(Client*) override; |
| 432 | 451 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 452 }; | 471 }; |
| 453 | 472 |
| 454 // HandleReader reads all data from the given WebDataConsumerHandle using | 473 // HandleReader reads all data from the given WebDataConsumerHandle using |
| 455 // Reader::read on the thread on which it is created. When reading is done | 474 // Reader::read on the thread on which it is created. When reading is done |
| 456 // or failed, it calls the given callback with the result. | 475 // or failed, it calls the given callback with the result. |
| 457 class HandleReader final : public WebDataConsumerHandle::Client { | 476 class HandleReader final : public WebDataConsumerHandle::Client { |
| 458 USING_FAST_MALLOC(HandleReader); | 477 USING_FAST_MALLOC(HandleReader); |
| 459 public: | 478 public: |
| 460 using OnFinishedReading = WTF::Function<void(std::unique_ptr<HandleReadR
esult>)>; | 479 using OnFinishedReading = WTF::Function<void(std::unique_ptr<HandleReadR
esult>)>; |
| 461 | 480 |
| 462 HandleReader(std::unique_ptr<WebDataConsumerHandle>, std::unique_ptr<OnF
inishedReading>); | 481 HandleReader(std::unique_ptr<WebDataConsumerHandle>, std::unique_ptr<OnF
inishedReading>, std::unique_ptr<WebTaskRunner> readerTaskRunner); |
| 463 void didGetReadable() override; | 482 void didGetReadable() override; |
| 483 WebTaskRunner* getTaskRunner() override; |
| 464 | 484 |
| 465 private: | 485 private: |
| 466 void runOnFinishedReading(std::unique_ptr<HandleReadResult>); | 486 void runOnFinishedReading(std::unique_ptr<HandleReadResult>); |
| 467 | 487 |
| 488 std::unique_ptr<WebTaskRunner> m_readerTaskRunner; |
| 468 std::unique_ptr<WebDataConsumerHandle::Reader> m_reader; | 489 std::unique_ptr<WebDataConsumerHandle::Reader> m_reader; |
| 469 std::unique_ptr<OnFinishedReading> m_onFinishedReading; | 490 std::unique_ptr<OnFinishedReading> m_onFinishedReading; |
| 470 Vector<char> m_data; | 491 Vector<char> m_data; |
| 471 }; | 492 }; |
| 472 | 493 |
| 473 // HandleTwoPhaseReader does the same as HandleReader, but it uses | 494 // HandleTwoPhaseReader does the same as HandleReader, but it uses |
| 474 // |beginRead| / |endRead| instead of |read|. | 495 // |beginRead| / |endRead| instead of |read|. |
| 475 class HandleTwoPhaseReader final : public WebDataConsumerHandle::Client { | 496 class HandleTwoPhaseReader final : public WebDataConsumerHandle::Client { |
| 476 USING_FAST_MALLOC(HandleTwoPhaseReader); | 497 USING_FAST_MALLOC(HandleTwoPhaseReader); |
| 477 public: | 498 public: |
| 478 using OnFinishedReading = WTF::Function<void(std::unique_ptr<HandleReadR
esult>)>; | 499 using OnFinishedReading = WTF::Function<void(std::unique_ptr<HandleReadR
esult>)>; |
| 479 | 500 |
| 480 HandleTwoPhaseReader(std::unique_ptr<WebDataConsumerHandle>, std::unique
_ptr<OnFinishedReading>); | 501 HandleTwoPhaseReader(std::unique_ptr<WebDataConsumerHandle>, std::unique
_ptr<OnFinishedReading>, std::unique_ptr<WebTaskRunner>); |
| 481 void didGetReadable() override; | 502 void didGetReadable() override; |
| 503 WebTaskRunner* getTaskRunner() override; |
| 482 | 504 |
| 483 private: | 505 private: |
| 484 void runOnFinishedReading(std::unique_ptr<HandleReadResult>); | 506 void runOnFinishedReading(std::unique_ptr<HandleReadResult>); |
| 485 | 507 |
| 508 std::unique_ptr<WebTaskRunner> m_readerTaskRunner; |
| 486 std::unique_ptr<WebDataConsumerHandle::Reader> m_reader; | 509 std::unique_ptr<WebDataConsumerHandle::Reader> m_reader; |
| 487 std::unique_ptr<OnFinishedReading> m_onFinishedReading; | 510 std::unique_ptr<OnFinishedReading> m_onFinishedReading; |
| 488 Vector<char> m_data; | 511 Vector<char> m_data; |
| 489 }; | 512 }; |
| 490 | 513 |
| 491 // HandleReaderRunner<T> creates a dedicated thread and run T on the thread | 514 // HandleReaderRunner<T> creates a dedicated thread and run T on the thread |
| 492 // where T is one of HandleReader and HandleTwophaseReader. | 515 // where T is one of HandleReader and HandleTwophaseReader. |
| 493 template <typename T> | 516 template <typename T> |
| 494 class HandleReaderRunner final { | 517 class HandleReaderRunner final { |
| 495 STACK_ALLOCATED(); | 518 STACK_ALLOCATED(); |
| 496 public: | 519 public: |
| 497 explicit HandleReaderRunner(std::unique_ptr<WebDataConsumerHandle> handl
e) | 520 explicit HandleReaderRunner(std::unique_ptr<WebDataConsumerHandle> handl
e) |
| 498 : m_thread(wrapUnique(new Thread("reading thread"))) | 521 : m_thread(wrapUnique(new Thread("reading thread"))) |
| 499 , m_event(wrapUnique(new WaitableEvent())) | 522 , m_event(wrapUnique(new WaitableEvent())) |
| 500 , m_isDone(false) | 523 , m_isDone(false) |
| 501 { | 524 { |
| 502 m_thread->thread()->postTask(BLINK_FROM_HERE, crossThreadBind(&Handl
eReaderRunner::start, crossThreadUnretained(this), passed(std::move(handle)))); | 525 m_thread->thread()->postTask(BLINK_FROM_HERE, crossThreadBind(&Handl
eReaderRunner::start, crossThreadUnretained(this), passed(std::move(handle)), pa
ssed(m_thread->taskRunner()->clone()))); |
| 503 } | 526 } |
| 504 ~HandleReaderRunner() | 527 ~HandleReaderRunner() |
| 505 { | 528 { |
| 506 wait(); | 529 wait(); |
| 507 } | 530 } |
| 508 | 531 |
| 509 std::unique_ptr<HandleReadResult> wait() | 532 std::unique_ptr<HandleReadResult> wait() |
| 510 { | 533 { |
| 511 if (m_isDone) | 534 if (m_isDone) |
| 512 return nullptr; | 535 return nullptr; |
| 513 m_event->wait(); | 536 m_event->wait(); |
| 514 m_isDone = true; | 537 m_isDone = true; |
| 515 return std::move(m_result); | 538 return std::move(m_result); |
| 516 } | 539 } |
| 517 | 540 |
| 518 private: | 541 private: |
| 519 void start(std::unique_ptr<WebDataConsumerHandle> handle) | 542 void start(std::unique_ptr<WebDataConsumerHandle> handle, std::unique_pt
r<WebTaskRunner> readerTaskRunner) |
| 520 { | 543 { |
| 521 m_handleReader = wrapUnique(new T(std::move(handle), WTF::bind(&Hand
leReaderRunner::onFinished, WTF::unretained(this)))); | 544 m_handleReader = wrapUnique(new T(std::move(handle), WTF::bind(&Hand
leReaderRunner::onFinished, WTF::unretained(this)), std::move(readerTaskRunner))
); |
| 522 } | 545 } |
| 523 | 546 |
| 524 void onFinished(std::unique_ptr<HandleReadResult> result) | 547 void onFinished(std::unique_ptr<HandleReadResult> result) |
| 525 { | 548 { |
| 526 m_handleReader = nullptr; | 549 m_handleReader = nullptr; |
| 527 m_result = std::move(result); | 550 m_result = std::move(result); |
| 528 m_event->signal(); | 551 m_event->signal(); |
| 529 } | 552 } |
| 530 | 553 |
| 531 std::unique_ptr<Thread> m_thread; | 554 std::unique_ptr<Thread> m_thread; |
| 532 std::unique_ptr<WaitableEvent> m_event; | 555 std::unique_ptr<WaitableEvent> m_event; |
| 533 std::unique_ptr<HandleReadResult> m_result; | 556 std::unique_ptr<HandleReadResult> m_result; |
| 534 bool m_isDone; | 557 bool m_isDone; |
| 535 | 558 |
| 536 std::unique_ptr<T> m_handleReader; | 559 std::unique_ptr<T> m_handleReader; |
| 537 }; | 560 }; |
| 538 }; | 561 }; |
| 539 | 562 |
| 540 } // namespace blink | 563 } // namespace blink |
| 541 | 564 |
| 542 #endif // DataConsumerHandleTestUtil_h | 565 #endif // DataConsumerHandleTestUtil_h |
| OLD | NEW |