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