Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
|
yhirano
2015/06/17 09:10:16
+ include guard
hiroshige
2015/06/17 09:25:26
Done.
| |
| 5 #include "modules/fetch/DataConsumerHandleUtil.h" | |
| 6 #include "modules/fetch/FetchDataConsumerHandle.h" | |
| 7 #include "platform/Task.h" | |
| 8 #include "platform/ThreadSafeFunctional.h" | |
| 9 #include "platform/heap/Handle.h" | |
| 10 #include "public/platform/Platform.h" | |
| 11 #include "public/platform/WebDataConsumerHandle.h" | |
| 12 #include "public/platform/WebThread.h" | |
| 13 #include "public/platform/WebTraceLocation.h" | |
| 14 #include "public/platform/WebWaitableEvent.h" | |
| 15 #include "wtf/Locker.h" | |
| 16 | |
| 17 #include <gmock/gmock.h> | |
| 18 #include <gtest/gtest.h> | |
| 19 | |
| 20 namespace blink { | |
| 21 | |
| 22 class DataConsumerHandleTestUtil { | |
| 23 public: | |
| 24 class NoopClient final : public WebDataConsumerHandle::Client { | |
| 25 public: | |
| 26 void didGetReadable() override { } | |
| 27 }; | |
| 28 | |
| 29 class ThreadingTestBase : public ThreadSafeRefCounted<ThreadingTestBase> { | |
| 30 public: | |
| 31 class Context : public ThreadSafeRefCounted<Context> { | |
| 32 public: | |
| 33 static PassRefPtr<Context> create() { return adoptRef(new Context); } | |
| 34 void recordAttach(const String& handle) | |
| 35 { | |
| 36 MutexLocker locker(m_loggingMutex); | |
| 37 m_result.append("A reader is attached to " + handle + " on " + c urrentThreadName() + ".\n"); | |
| 38 } | |
| 39 void recordDetach(const String& handle) | |
| 40 { | |
| 41 MutexLocker locker(m_loggingMutex); | |
| 42 m_result.append("A reader is detached from " + handle + " on " + currentThreadName() + ".\n"); | |
| 43 } | |
| 44 | |
| 45 const String& result() | |
| 46 { | |
| 47 MutexLocker locker(m_loggingMutex); | |
| 48 return m_result; | |
| 49 } | |
| 50 WebThread* readingThread() { return m_readingThread.get(); } | |
| 51 WebThread* updatingThread() { return m_updatingThread.get(); } | |
| 52 | |
| 53 private: | |
| 54 Context() | |
| 55 : m_readingThread(adoptPtr(Platform::current()->createThread("re ading thread"))) | |
| 56 , m_updatingThread(adoptPtr(Platform::current()->createThread("u pdating thread"))) | |
| 57 { | |
| 58 } | |
| 59 String currentThreadName() | |
| 60 { | |
| 61 if (m_readingThread->isCurrentThread()) | |
| 62 return "the reading thread"; | |
| 63 if (m_updatingThread->isCurrentThread()) | |
| 64 return "the updating thread"; | |
| 65 return "an unknown thread"; | |
| 66 } | |
| 67 | |
| 68 OwnPtr<WebThread> m_readingThread; | |
| 69 OwnPtr<WebThread> m_updatingThread; | |
| 70 Mutex m_loggingMutex; | |
| 71 String m_result; | |
| 72 }; | |
| 73 | |
| 74 class ReaderImpl final : public WebDataConsumerHandle::Reader { | |
| 75 public: | |
| 76 ReaderImpl(const String& name, PassRefPtr<Context> context) : m_name (name.isolatedCopy()), m_context(context) | |
| 77 { | |
| 78 m_context->recordAttach(m_name.isolatedCopy()); | |
| 79 } | |
| 80 ~ReaderImpl() override { m_context->recordDetach(m_name.isolatedCopy ()); } | |
| 81 | |
| 82 using Result = WebDataConsumerHandle::Result; | |
| 83 using Flags = WebDataConsumerHandle::Flags; | |
| 84 Result read(void*, size_t, Flags, size_t*) override { return WebData ConsumerHandle::ShouldWait; } | |
| 85 Result beginRead(const void**, Flags, size_t*) override { return Web DataConsumerHandle::ShouldWait; } | |
| 86 Result endRead(size_t) override { return WebDataConsumerHandle::Unex pectedError; } | |
| 87 | |
| 88 private: | |
| 89 const String m_name; | |
| 90 RefPtr<Context> m_context; | |
| 91 }; | |
| 92 class DataConsumerHandle final : public WebDataConsumerHandle { | |
| 93 public: | |
| 94 DataConsumerHandle(const String& name, PassRefPtr<Context> context) : m_name(name.isolatedCopy()), m_context(context) { } | |
| 95 | |
| 96 private: | |
| 97 Reader* obtainReaderInternal(Client*) { return new ReaderImpl(m_name , m_context); } | |
| 98 const String m_name; | |
| 99 RefPtr<Context> m_context; | |
| 100 }; | |
| 101 | |
| 102 void resetReader() { m_reader = nullptr; } | |
| 103 void signalDone() { m_waitableEvent->signal(); } | |
| 104 const String& result() { return m_context->result(); } | |
| 105 WebThread* readingThread() { return m_context->readingThread(); } | |
| 106 WebThread* updatingThread() { return m_context->updatingThread(); } | |
| 107 | |
| 108 protected: | |
| 109 RefPtr<Context> m_context; | |
| 110 OwnPtr<WebDataConsumerHandle::Reader> m_reader; | |
| 111 OwnPtr<WebWaitableEvent> m_waitableEvent; | |
| 112 NoopClient m_client; | |
| 113 }; | |
| 114 | |
| 115 class ThreadingHandleNotificationTest : public ThreadingTestBase, public Web DataConsumerHandle::Client { | |
| 116 public: | |
| 117 using Self = ThreadingHandleNotificationTest; | |
| 118 void run(PassOwnPtr<WebDataConsumerHandle> handle) | |
| 119 { | |
| 120 m_context = Context::create(); | |
| 121 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent( )); | |
| 122 m_handle = handle; | |
| 123 | |
| 124 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self:: obtainReader, this))); | |
| 125 | |
| 126 m_waitableEvent->wait(); | |
| 127 } | |
| 128 | |
| 129 private: | |
| 130 void obtainReader() | |
| 131 { | |
| 132 m_reader = m_handle->obtainReader(this); | |
| 133 } | |
| 134 void didGetReadable() override | |
| 135 { | |
| 136 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self:: resetReader, this))); | |
| 137 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self:: signalDone, this))); | |
| 138 } | |
| 139 | |
| 140 OwnPtr<WebDataConsumerHandle> m_handle; | |
| 141 }; | |
| 142 | |
| 143 class ThreadingHandleNoNotificationTest : public ThreadingTestBase, public W ebDataConsumerHandle::Client { | |
| 144 public: | |
| 145 using Self = ThreadingHandleNoNotificationTest; | |
| 146 void run(PassOwnPtr<WebDataConsumerHandle> handle) | |
| 147 { | |
| 148 m_context = Context::create(); | |
| 149 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent( )); | |
| 150 m_handle = handle; | |
| 151 | |
| 152 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self:: obtainReader, this))); | |
| 153 | |
| 154 m_waitableEvent->wait(); | |
| 155 } | |
| 156 | |
| 157 private: | |
| 158 void obtainReader() | |
| 159 { | |
| 160 m_reader = m_handle->obtainReader(this); | |
| 161 m_reader = nullptr; | |
| 162 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self:: signalDone, this))); | |
| 163 } | |
| 164 void didGetReadable() override | |
| 165 { | |
| 166 ASSERT_NOT_REACHED(); | |
| 167 } | |
| 168 | |
| 169 OwnPtr<WebDataConsumerHandle> m_handle; | |
| 170 }; | |
| 171 }; | |
| 172 | |
| 173 } // namespace blink | |
| OLD | NEW |