| 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/DataConsumerTee.h" | 6 #include "modules/fetch/DataConsumerTee.h" |
| 7 | 7 |
| 8 #include "bindings/core/v8/ScriptState.h" | |
| 9 #include "core/testing/DummyPageHolder.h" | 8 #include "core/testing/DummyPageHolder.h" |
| 10 #include "core/testing/NullExecutionContext.h" | 9 #include "core/testing/NullExecutionContext.h" |
| 11 #include "gin/public/isolate_holder.h" | 10 #include "modules/fetch/DataConsumerHandleTestUtil.h" |
| 12 #include "platform/Task.h" | 11 #include "platform/Task.h" |
| 13 #include "platform/ThreadSafeFunctional.h" | 12 #include "platform/ThreadSafeFunctional.h" |
| 14 #include "platform/WebThreadSupportingGC.h" | 13 #include "platform/WebThreadSupportingGC.h" |
| 15 #include "public/platform/Platform.h" | 14 #include "public/platform/Platform.h" |
| 16 #include "public/platform/WebThread.h" | 15 #include "public/platform/WebThread.h" |
| 17 #include "public/platform/WebTraceLocation.h" | 16 #include "public/platform/WebTraceLocation.h" |
| 18 #include "public/platform/WebWaitableEvent.h" | 17 #include "public/platform/WebWaitableEvent.h" |
| 19 #include "wtf/Deque.h" | 18 #include "wtf/Deque.h" |
| 20 #include "wtf/PassRefPtr.h" | 19 #include "wtf/PassRefPtr.h" |
| 21 #include "wtf/RefPtr.h" | 20 #include "wtf/RefPtr.h" |
| 22 #include "wtf/ThreadSafeRefCounted.h" | 21 #include "wtf/ThreadSafeRefCounted.h" |
| 23 #include "wtf/ThreadingPrimitives.h" | 22 #include "wtf/ThreadingPrimitives.h" |
| 24 #include "wtf/Vector.h" | 23 #include "wtf/Vector.h" |
| 25 | 24 |
| 26 #include <gtest/gtest.h> | 25 #include <gtest/gtest.h> |
| 27 #include <string.h> | 26 #include <string.h> |
| 28 #include <v8.h> | 27 #include <v8.h> |
| 29 | 28 |
| 30 namespace blink { | 29 namespace blink { |
| 31 namespace { | 30 namespace { |
| 32 | 31 |
| 33 using Result = WebDataConsumerHandle::Result; | 32 using Result = WebDataConsumerHandle::Result; |
| 33 using Thread = DataConsumerHandleTestUtil::Thread; |
| 34 const WebDataConsumerHandle::Flags kNone = WebDataConsumerHandle::FlagNone; | 34 const WebDataConsumerHandle::Flags kNone = WebDataConsumerHandle::FlagNone; |
| 35 const Result kOk = WebDataConsumerHandle::Ok; | 35 const Result kOk = WebDataConsumerHandle::Ok; |
| 36 const Result kShouldWait = WebDataConsumerHandle::ShouldWait; | 36 const Result kShouldWait = WebDataConsumerHandle::ShouldWait; |
| 37 const Result kDone = WebDataConsumerHandle::Done; | 37 const Result kDone = WebDataConsumerHandle::Done; |
| 38 const Result kUnexpectedError = WebDataConsumerHandle::UnexpectedError; | 38 const Result kUnexpectedError = WebDataConsumerHandle::UnexpectedError; |
| 39 | 39 |
| 40 class Command final { | 40 class Command final { |
| 41 public: | 41 public: |
| 42 enum Name { | 42 enum Name { |
| 43 Data, | 43 Data, |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 { | 261 { |
| 262 m_context->add(command); | 262 m_context->add(command); |
| 263 } | 263 } |
| 264 | 264 |
| 265 Context* context() { return m_context.get(); }; | 265 Context* context() { return m_context.get(); }; |
| 266 | 266 |
| 267 private: | 267 private: |
| 268 RefPtr<Context> m_context; | 268 RefPtr<Context> m_context; |
| 269 }; | 269 }; |
| 270 | 270 |
| 271 class TestingThread final { | |
| 272 public: | |
| 273 explicit TestingThread(const char* name) | |
| 274 : m_thread(WebThreadSupportingGC::create(name)) | |
| 275 , m_waitableEvent(adoptPtr(Platform::current()->createWaitableEvent())) | |
| 276 { | |
| 277 m_thread->postTask(FROM_HERE, new Task(threadSafeBind(&TestingThread::in
itialize, AllowCrossThreadAccess(this)))); | |
| 278 m_waitableEvent->wait(); | |
| 279 } | |
| 280 | |
| 281 ~TestingThread() | |
| 282 { | |
| 283 m_thread->postTask(FROM_HERE, new Task(threadSafeBind(&TestingThread::sh
utdown, AllowCrossThreadAccess(this)))); | |
| 284 m_waitableEvent->wait(); | |
| 285 } | |
| 286 | |
| 287 WebThreadSupportingGC* thread() { return m_thread.get(); } | |
| 288 ExecutionContext* executionContext() { return m_executionContext.get(); } | |
| 289 ScriptState* scriptState() { return m_scriptState.get(); } | |
| 290 v8::Isolate* isolate() { return m_isolateHolder->isolate(); } | |
| 291 | |
| 292 private: | |
| 293 void initialize() | |
| 294 { | |
| 295 m_isolateHolder = adoptPtr(new gin::IsolateHolder()); | |
| 296 m_thread->initialize(); | |
| 297 isolate()->Enter(); | |
| 298 v8::HandleScope handleScope(isolate()); | |
| 299 v8::Local<v8::Context> context = v8::Context::New(isolate()); | |
| 300 m_scriptState = ScriptState::create(context, DOMWrapperWorld::create(iso
late())); | |
| 301 m_executionContext = adoptRefWillBeNoop(new NullExecutionContext()); | |
| 302 m_waitableEvent->signal(); | |
| 303 } | |
| 304 | |
| 305 void shutdown() | |
| 306 { | |
| 307 m_executionContext = nullptr; | |
| 308 m_scriptState = nullptr; | |
| 309 isolate()->Exit(); | |
| 310 m_thread->shutdown(); | |
| 311 m_isolateHolder = nullptr; | |
| 312 m_waitableEvent->signal(); | |
| 313 } | |
| 314 | |
| 315 OwnPtr<WebThreadSupportingGC> m_thread; | |
| 316 OwnPtr<WebWaitableEvent> m_waitableEvent; | |
| 317 RefPtrWillBePersistent<NullExecutionContext> m_executionContext; | |
| 318 OwnPtr<gin::IsolateHolder> m_isolateHolder; | |
| 319 RefPtr<ScriptState> m_scriptState; | |
| 320 }; | |
| 321 | |
| 322 class HandleReader : public WebDataConsumerHandle::Client { | 271 class HandleReader : public WebDataConsumerHandle::Client { |
| 323 public: | 272 public: |
| 324 HandleReader() : m_finalResult(kOk) { } | 273 HandleReader() : m_finalResult(kOk) { } |
| 325 | 274 |
| 326 // Need to wait for the event signal after this function is called. | 275 // Need to wait for the event signal after this function is called. |
| 327 void start(PassOwnPtr<WebDataConsumerHandle> handle) | 276 void start(PassOwnPtr<WebDataConsumerHandle> handle) |
| 328 { | 277 { |
| 329 m_thread = adoptPtr(new TestingThread("reading thread")); | 278 m_thread = adoptPtr(new Thread("reading thread")); |
| 330 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent()); | 279 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent()); |
| 331 m_thread->thread()->postTask(FROM_HERE, new Task(threadSafeBind(&HandleR
eader::obtainReader, AllowCrossThreadAccess(this), handle))); | 280 m_thread->thread()->postTask(FROM_HERE, new Task(threadSafeBind(&HandleR
eader::obtainReader, AllowCrossThreadAccess(this), handle))); |
| 332 } | 281 } |
| 333 | 282 |
| 334 void didGetReadable() override | 283 void didGetReadable() override |
| 335 { | 284 { |
| 336 Result r = kOk; | 285 Result r = kOk; |
| 337 char buffer[3]; | 286 char buffer[3]; |
| 338 while (true) { | 287 while (true) { |
| 339 size_t size; | 288 size_t size; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 354 // These should be accessed after the thread joins. | 303 // These should be accessed after the thread joins. |
| 355 const String& readString() const { return m_readString; } | 304 const String& readString() const { return m_readString; } |
| 356 Result finalResult() const { return m_finalResult; } | 305 Result finalResult() const { return m_finalResult; } |
| 357 | 306 |
| 358 private: | 307 private: |
| 359 void obtainReader(PassOwnPtr<WebDataConsumerHandle> handle) | 308 void obtainReader(PassOwnPtr<WebDataConsumerHandle> handle) |
| 360 { | 309 { |
| 361 m_reader = handle->obtainReader(this); | 310 m_reader = handle->obtainReader(this); |
| 362 } | 311 } |
| 363 | 312 |
| 364 OwnPtr<TestingThread> m_thread; | 313 OwnPtr<Thread> m_thread; |
| 365 OwnPtr<WebDataConsumerHandle::Reader> m_reader; | 314 OwnPtr<WebDataConsumerHandle::Reader> m_reader; |
| 366 String m_readString; | 315 String m_readString; |
| 367 Result m_finalResult; | 316 Result m_finalResult; |
| 368 OwnPtr<WebWaitableEvent> m_waitableEvent; | 317 OwnPtr<WebWaitableEvent> m_waitableEvent; |
| 369 }; | 318 }; |
| 370 | 319 |
| 371 class HandleTwoPhaseReader : public WebDataConsumerHandle::Client { | 320 class HandleTwoPhaseReader : public WebDataConsumerHandle::Client { |
| 372 public: | 321 public: |
| 373 HandleTwoPhaseReader() : m_finalResult(kOk) { } | 322 HandleTwoPhaseReader() : m_finalResult(kOk) { } |
| 374 | 323 |
| 375 // Need to wait for the event signal after this function is called. | 324 // Need to wait for the event signal after this function is called. |
| 376 void start(PassOwnPtr<WebDataConsumerHandle> handle) | 325 void start(PassOwnPtr<WebDataConsumerHandle> handle) |
| 377 { | 326 { |
| 378 m_thread = adoptPtr(new TestingThread("reading thread")); | 327 m_thread = adoptPtr(new Thread("reading thread")); |
| 379 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent()); | 328 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent()); |
| 380 m_thread->thread()->postTask(FROM_HERE, new Task(threadSafeBind(&HandleT
woPhaseReader::obtainReader, AllowCrossThreadAccess(this), handle))); | 329 m_thread->thread()->postTask(FROM_HERE, new Task(threadSafeBind(&HandleT
woPhaseReader::obtainReader, AllowCrossThreadAccess(this), handle))); |
| 381 } | 330 } |
| 382 | 331 |
| 383 void didGetReadable() override | 332 void didGetReadable() override |
| 384 { | 333 { |
| 385 Result r = kOk; | 334 Result r = kOk; |
| 386 while (true) { | 335 while (true) { |
| 387 const void* buffer = nullptr; | 336 const void* buffer = nullptr; |
| 388 size_t size; | 337 size_t size; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 406 // These should be accessed after the thread joins. | 355 // These should be accessed after the thread joins. |
| 407 const String& readString() const { return m_readString; } | 356 const String& readString() const { return m_readString; } |
| 408 Result finalResult() const { return m_finalResult; } | 357 Result finalResult() const { return m_finalResult; } |
| 409 | 358 |
| 410 private: | 359 private: |
| 411 void obtainReader(PassOwnPtr<WebDataConsumerHandle> handle) | 360 void obtainReader(PassOwnPtr<WebDataConsumerHandle> handle) |
| 412 { | 361 { |
| 413 m_reader = handle->obtainReader(this); | 362 m_reader = handle->obtainReader(this); |
| 414 } | 363 } |
| 415 | 364 |
| 416 OwnPtr<TestingThread> m_thread; | 365 OwnPtr<Thread> m_thread; |
| 417 OwnPtr<WebDataConsumerHandle::Reader> m_reader; | 366 OwnPtr<WebDataConsumerHandle::Reader> m_reader; |
| 418 String m_readString; | 367 String m_readString; |
| 419 Result m_finalResult; | 368 Result m_finalResult; |
| 420 OwnPtr<WebWaitableEvent> m_waitableEvent; | 369 OwnPtr<WebWaitableEvent> m_waitableEvent; |
| 421 }; | 370 }; |
| 422 | 371 |
| 423 class TeeCreationThread { | 372 class TeeCreationThread { |
| 424 public: | 373 public: |
| 425 void run(PassOwnPtr<WebDataConsumerHandle> src, OwnPtr<WebDataConsumerHandle
>* dest1, OwnPtr<WebDataConsumerHandle>* dest2) | 374 void run(PassOwnPtr<WebDataConsumerHandle> src, OwnPtr<WebDataConsumerHandle
>* dest1, OwnPtr<WebDataConsumerHandle>* dest2) |
| 426 { | 375 { |
| 427 m_thread = adoptPtr(new TestingThread("src thread")); | 376 m_thread = adoptPtr(new Thread("src thread", Thread::WithExecutionContex
t)); |
| 428 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent()); | 377 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent()); |
| 429 m_thread->thread()->postTask(FROM_HERE, new Task(threadSafeBind(&TeeCrea
tionThread::runInternal, AllowCrossThreadAccess(this), src, AllowCrossThreadAcce
ss(dest1), AllowCrossThreadAccess(dest2)))); | 378 m_thread->thread()->postTask(FROM_HERE, new Task(threadSafeBind(&TeeCrea
tionThread::runInternal, AllowCrossThreadAccess(this), src, AllowCrossThreadAcce
ss(dest1), AllowCrossThreadAccess(dest2)))); |
| 430 m_waitableEvent->wait(); | 379 m_waitableEvent->wait(); |
| 431 } | 380 } |
| 432 | 381 |
| 433 TestingThread* thread() { return m_thread.get(); } | 382 Thread* thread() { return m_thread.get(); } |
| 434 | 383 |
| 435 private: | 384 private: |
| 436 void runInternal(PassOwnPtr<WebDataConsumerHandle> src, OwnPtr<WebDataConsum
erHandle>* dest1, OwnPtr<WebDataConsumerHandle>* dest2) | 385 void runInternal(PassOwnPtr<WebDataConsumerHandle> src, OwnPtr<WebDataConsum
erHandle>* dest1, OwnPtr<WebDataConsumerHandle>* dest2) |
| 437 { | 386 { |
| 438 DataConsumerTee::create(m_thread->executionContext(), src, dest1, dest2)
; | 387 DataConsumerTee::create(m_thread->executionContext(), src, dest1, dest2)
; |
| 439 m_waitableEvent->signal(); | 388 m_waitableEvent->signal(); |
| 440 } | 389 } |
| 441 | 390 |
| 442 OwnPtr<TestingThread> m_thread; | 391 OwnPtr<Thread> m_thread; |
| 443 OwnPtr<WebWaitableEvent> m_waitableEvent; | 392 OwnPtr<WebWaitableEvent> m_waitableEvent; |
| 444 }; | 393 }; |
| 445 | 394 |
| 446 TEST(DataConsumerTeeTest, CreateDone) | 395 TEST(DataConsumerTeeTest, CreateDone) |
| 447 { | 396 { |
| 448 OwnPtr<Handle> src(adoptPtr(new Handle)); | 397 OwnPtr<Handle> src(adoptPtr(new Handle)); |
| 449 OwnPtr<WebDataConsumerHandle> dest1, dest2; | 398 OwnPtr<WebDataConsumerHandle> dest1, dest2; |
| 450 | 399 |
| 451 src->add(Command(Command::Done)); | 400 src->add(Command(Command::Done)); |
| 452 | 401 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 r1.start(dest1.release()); | 505 r1.start(dest1.release()); |
| 557 r2.start(dest2.release()); | 506 r2.start(dest2.release()); |
| 558 | 507 |
| 559 r1.waitableEvent()->wait(); | 508 r1.waitableEvent()->wait(); |
| 560 r2.waitableEvent()->wait(); | 509 r2.waitableEvent()->wait(); |
| 561 | 510 |
| 562 EXPECT_EQ(kUnexpectedError, r1.finalResult()); | 511 EXPECT_EQ(kUnexpectedError, r1.finalResult()); |
| 563 EXPECT_EQ(kUnexpectedError, r2.finalResult()); | 512 EXPECT_EQ(kUnexpectedError, r2.finalResult()); |
| 564 } | 513 } |
| 565 | 514 |
| 566 void postStop(TestingThread* thread) | 515 void postStop(Thread* thread) |
| 567 { | 516 { |
| 568 thread->executionContext()->stopActiveDOMObjects(); | 517 thread->executionContext()->stopActiveDOMObjects(); |
| 569 } | 518 } |
| 570 | 519 |
| 571 TEST(DataConsumerTeeTest, StopSource) | 520 TEST(DataConsumerTeeTest, StopSource) |
| 572 { | 521 { |
| 573 OwnPtr<Handle> src(adoptPtr(new Handle)); | 522 OwnPtr<Handle> src(adoptPtr(new Handle)); |
| 574 OwnPtr<WebDataConsumerHandle> dest1, dest2; | 523 OwnPtr<WebDataConsumerHandle> dest1, dest2; |
| 575 | 524 |
| 576 src->add(Command(Command::Data, "hello, ")); | 525 src->add(Command(Command::Data, "hello, ")); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 dest1 = nullptr; | 647 dest1 = nullptr; |
| 699 dest2 = nullptr; | 648 dest2 = nullptr; |
| 700 | 649 |
| 701 // Collect garbage to finalize the source reader. | 650 // Collect garbage to finalize the source reader. |
| 702 Heap::collectAllGarbage(); | 651 Heap::collectAllGarbage(); |
| 703 context->detached()->wait(); | 652 context->detached()->wait(); |
| 704 } | 653 } |
| 705 | 654 |
| 706 } // namespace | 655 } // namespace |
| 707 } // namespace blink | 656 } // namespace blink |
| OLD | NEW |