| 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 "core/testing/NullExecutionContext.h" |
| 8 #include "modules/fetch/DataConsumerHandleUtil.h" | 9 #include "modules/fetch/DataConsumerHandleUtil.h" |
| 9 #include "modules/fetch/FetchDataConsumerHandle.h" | 10 #include "modules/fetch/FetchDataConsumerHandle.h" |
| 10 #include "platform/Task.h" | 11 #include "platform/Task.h" |
| 11 #include "platform/ThreadSafeFunctional.h" | 12 #include "platform/ThreadSafeFunctional.h" |
| 13 #include "platform/WebThreadSupportingGC.h" |
| 12 #include "platform/heap/Handle.h" | 14 #include "platform/heap/Handle.h" |
| 13 #include "public/platform/Platform.h" | 15 #include "public/platform/Platform.h" |
| 14 #include "public/platform/WebDataConsumerHandle.h" | 16 #include "public/platform/WebDataConsumerHandle.h" |
| 15 #include "public/platform/WebThread.h" | |
| 16 #include "public/platform/WebTraceLocation.h" | 17 #include "public/platform/WebTraceLocation.h" |
| 17 #include "public/platform/WebWaitableEvent.h" | 18 #include "public/platform/WebWaitableEvent.h" |
| 18 #include "wtf/Locker.h" | 19 #include "wtf/Locker.h" |
| 19 | 20 |
| 20 #include <gmock/gmock.h> | 21 #include <gmock/gmock.h> |
| 21 #include <gtest/gtest.h> | 22 #include <gtest/gtest.h> |
| 23 #include <v8.h> |
| 22 | 24 |
| 23 namespace blink { | 25 namespace blink { |
| 24 | 26 |
| 25 class DataConsumerHandleTestUtil { | 27 class DataConsumerHandleTestUtil { |
| 26 public: | 28 public: |
| 27 class NoopClient final : public WebDataConsumerHandle::Client { | 29 class NoopClient final : public WebDataConsumerHandle::Client { |
| 28 public: | 30 public: |
| 29 void didGetReadable() override { } | 31 void didGetReadable() override { } |
| 30 }; | 32 }; |
| 31 | 33 |
| 34 // TestingThread has a WebThreadSupportingGC. It initializes / shutdowns |
| 35 // additional objects based on the given policy. The constructor and the |
| 36 // destructor blocks during the setup and the teardown. |
| 37 class TestingThread final { |
| 38 public: |
| 39 // Initialization policy of a thread. |
| 40 enum InitializationPolicy { |
| 41 // Only garbage collection is supported. |
| 42 GarbageCollection, |
| 43 // Creating an isolate in addition to GarbageCollection. |
| 44 ScriptExecution, |
| 45 // Creating an execution context in addition to ScriptExecution. |
| 46 WithExecutionContext, |
| 47 }; |
| 48 |
| 49 TestingThread(const char* name, InitializationPolicy = GarbageCollection
); |
| 50 ~TestingThread(); |
| 51 |
| 52 WebThreadSupportingGC* thread() { return m_thread.get(); } |
| 53 ExecutionContext* executionContext() { return m_executionContext.get();
} |
| 54 |
| 55 private: |
| 56 void initialize(); |
| 57 void shutdown(); |
| 58 |
| 59 OwnPtr<WebThreadSupportingGC> m_thread; |
| 60 const InitializationPolicy m_initializationPolicy; |
| 61 OwnPtr<WebWaitableEvent> m_waitableEvent; |
| 62 RefPtrWillBePersistent<NullExecutionContext> m_executionContext; |
| 63 v8::Isolate* m_isolate; |
| 64 }; |
| 65 |
| 32 class ThreadingTestBase : public ThreadSafeRefCounted<ThreadingTestBase> { | 66 class ThreadingTestBase : public ThreadSafeRefCounted<ThreadingTestBase> { |
| 33 public: | 67 public: |
| 34 class Context : public ThreadSafeRefCounted<Context> { | 68 class Context : public ThreadSafeRefCounted<Context> { |
| 35 public: | 69 public: |
| 36 static PassRefPtr<Context> create() { return adoptRef(new Context);
} | 70 static PassRefPtr<Context> create() { return adoptRef(new Context);
} |
| 37 void recordAttach(const String& handle) | 71 void recordAttach(const String& handle) |
| 38 { | 72 { |
| 39 MutexLocker locker(m_loggingMutex); | 73 MutexLocker locker(m_loggingMutex); |
| 40 m_result.append("A reader is attached to " + handle + " on " + c
urrentThreadName() + ".\n"); | 74 m_result.append("A reader is attached to " + handle + " on " + c
urrentThreadName() + ".\n"); |
| 41 } | 75 } |
| 42 void recordDetach(const String& handle) | 76 void recordDetach(const String& handle) |
| 43 { | 77 { |
| 44 MutexLocker locker(m_loggingMutex); | 78 MutexLocker locker(m_loggingMutex); |
| 45 m_result.append("A reader is detached from " + handle + " on " +
currentThreadName() + ".\n"); | 79 m_result.append("A reader is detached from " + handle + " on " +
currentThreadName() + ".\n"); |
| 46 } | 80 } |
| 47 | 81 |
| 48 const String& result() | 82 const String& result() |
| 49 { | 83 { |
| 50 MutexLocker locker(m_loggingMutex); | 84 MutexLocker locker(m_loggingMutex); |
| 51 return m_result; | 85 return m_result; |
| 52 } | 86 } |
| 53 WebThread* readingThread() { return m_readingThread.get(); } | 87 WebThreadSupportingGC* readingThread() { return m_readingThread->thr
ead(); } |
| 54 WebThread* updatingThread() { return m_updatingThread.get(); } | 88 WebThreadSupportingGC* updatingThread() { return m_updatingThread->t
hread(); } |
| 55 | 89 |
| 56 private: | 90 private: |
| 57 Context() | 91 Context() |
| 58 : m_readingThread(adoptPtr(Platform::current()->createThread("re
ading thread"))) | 92 : m_readingThread(adoptPtr(new TestingThread("reading thread"))) |
| 59 , m_updatingThread(adoptPtr(Platform::current()->createThread("u
pdating thread"))) | 93 , m_updatingThread(adoptPtr(new TestingThread("updating thread")
)) |
| 60 { | 94 { |
| 61 } | 95 } |
| 62 String currentThreadName() | 96 String currentThreadName() |
| 63 { | 97 { |
| 64 if (m_readingThread->isCurrentThread()) | 98 if (m_readingThread->thread()->isCurrentThread()) |
| 65 return "the reading thread"; | 99 return "the reading thread"; |
| 66 if (m_updatingThread->isCurrentThread()) | 100 if (m_updatingThread->thread()->isCurrentThread()) |
| 67 return "the updating thread"; | 101 return "the updating thread"; |
| 68 return "an unknown thread"; | 102 return "an unknown thread"; |
| 69 } | 103 } |
| 70 | 104 |
| 71 OwnPtr<WebThread> m_readingThread; | 105 OwnPtr<TestingThread> m_readingThread; |
| 72 OwnPtr<WebThread> m_updatingThread; | 106 OwnPtr<TestingThread> m_updatingThread; |
| 73 Mutex m_loggingMutex; | 107 Mutex m_loggingMutex; |
| 74 String m_result; | 108 String m_result; |
| 75 }; | 109 }; |
| 76 | 110 |
| 77 class ReaderImpl final : public WebDataConsumerHandle::Reader { | 111 class ReaderImpl final : public WebDataConsumerHandle::Reader { |
| 78 public: | 112 public: |
| 79 ReaderImpl(const String& name, PassRefPtr<Context> context) : m_name
(name.isolatedCopy()), m_context(context) | 113 ReaderImpl(const String& name, PassRefPtr<Context> context) : m_name
(name.isolatedCopy()), m_context(context) |
| 80 { | 114 { |
| 81 m_context->recordAttach(m_name.isolatedCopy()); | 115 m_context->recordAttach(m_name.isolatedCopy()); |
| 82 } | 116 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 98 | 132 |
| 99 private: | 133 private: |
| 100 Reader* obtainReaderInternal(Client*) { return new ReaderImpl(m_name
, m_context); } | 134 Reader* obtainReaderInternal(Client*) { return new ReaderImpl(m_name
, m_context); } |
| 101 const String m_name; | 135 const String m_name; |
| 102 RefPtr<Context> m_context; | 136 RefPtr<Context> m_context; |
| 103 }; | 137 }; |
| 104 | 138 |
| 105 void resetReader() { m_reader = nullptr; } | 139 void resetReader() { m_reader = nullptr; } |
| 106 void signalDone() { m_waitableEvent->signal(); } | 140 void signalDone() { m_waitableEvent->signal(); } |
| 107 const String& result() { return m_context->result(); } | 141 const String& result() { return m_context->result(); } |
| 108 WebThread* readingThread() { return m_context->readingThread(); } | 142 WebThreadSupportingGC* readingThread() { return m_context->readingThread
(); } |
| 109 WebThread* updatingThread() { return m_context->updatingThread(); } | 143 WebThreadSupportingGC* updatingThread() { return m_context->updatingThre
ad(); } |
| 144 void postTaskAndWait(WebThreadSupportingGC* thread, const WebTraceLocati
on& location, Task* task) |
| 145 { |
| 146 thread->postTask(location, task); |
| 147 m_waitableEvent->wait(); |
| 148 } |
| 110 | 149 |
| 111 protected: | 150 protected: |
| 112 RefPtr<Context> m_context; | 151 RefPtr<Context> m_context; |
| 113 OwnPtr<WebDataConsumerHandle::Reader> m_reader; | 152 OwnPtr<WebDataConsumerHandle::Reader> m_reader; |
| 114 OwnPtr<WebWaitableEvent> m_waitableEvent; | 153 OwnPtr<WebWaitableEvent> m_waitableEvent; |
| 115 NoopClient m_client; | 154 NoopClient m_client; |
| 116 }; | 155 }; |
| 117 | 156 |
| 118 class ThreadingHandleNotificationTest : public ThreadingTestBase, public Web
DataConsumerHandle::Client { | 157 class ThreadingHandleNotificationTest : public ThreadingTestBase, public Web
DataConsumerHandle::Client { |
| 119 public: | 158 public: |
| 120 using Self = ThreadingHandleNotificationTest; | 159 using Self = ThreadingHandleNotificationTest; |
| 121 void run(PassOwnPtr<WebDataConsumerHandle> handle) | 160 void run(PassOwnPtr<WebDataConsumerHandle> handle) |
| 122 { | 161 { |
| 123 m_context = Context::create(); | 162 m_context = Context::create(); |
| 124 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent(
)); | 163 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent(
)); |
| 125 m_handle = handle; | 164 m_handle = handle; |
| 126 | 165 |
| 127 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self::
obtainReader, this))); | 166 postTaskAndWait(readingThread(), FROM_HERE, new Task(threadSafeBind(
&Self::obtainReader, this))); |
| 128 | |
| 129 m_waitableEvent->wait(); | |
| 130 } | 167 } |
| 131 | 168 |
| 132 private: | 169 private: |
| 133 void obtainReader() | 170 void obtainReader() |
| 134 { | 171 { |
| 135 m_reader = m_handle->obtainReader(this); | 172 m_reader = m_handle->obtainReader(this); |
| 136 } | 173 } |
| 137 void didGetReadable() override | 174 void didGetReadable() override |
| 138 { | 175 { |
| 139 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self::
resetReader, this))); | 176 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self::
resetReader, this))); |
| 140 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self::
signalDone, this))); | 177 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self::
signalDone, this))); |
| 141 } | 178 } |
| 142 | 179 |
| 143 OwnPtr<WebDataConsumerHandle> m_handle; | 180 OwnPtr<WebDataConsumerHandle> m_handle; |
| 144 }; | 181 }; |
| 145 | 182 |
| 146 class ThreadingHandleNoNotificationTest : public ThreadingTestBase, public W
ebDataConsumerHandle::Client { | 183 class ThreadingHandleNoNotificationTest : public ThreadingTestBase, public W
ebDataConsumerHandle::Client { |
| 147 public: | 184 public: |
| 148 using Self = ThreadingHandleNoNotificationTest; | 185 using Self = ThreadingHandleNoNotificationTest; |
| 149 void run(PassOwnPtr<WebDataConsumerHandle> handle) | 186 void run(PassOwnPtr<WebDataConsumerHandle> handle) |
| 150 { | 187 { |
| 151 m_context = Context::create(); | 188 m_context = Context::create(); |
| 152 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent(
)); | 189 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent(
)); |
| 153 m_handle = handle; | 190 m_handle = handle; |
| 154 | 191 |
| 155 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self::
obtainReader, this))); | 192 postTaskAndWait(readingThread(), FROM_HERE, new Task(threadSafeBind(
&Self::obtainReader, this))); |
| 156 | |
| 157 m_waitableEvent->wait(); | |
| 158 } | 193 } |
| 159 | 194 |
| 160 private: | 195 private: |
| 161 void obtainReader() | 196 void obtainReader() |
| 162 { | 197 { |
| 163 m_reader = m_handle->obtainReader(this); | 198 m_reader = m_handle->obtainReader(this); |
| 164 m_reader = nullptr; | 199 m_reader = nullptr; |
| 165 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self::
signalDone, this))); | 200 readingThread()->postTask(FROM_HERE, new Task(threadSafeBind(&Self::
signalDone, this))); |
| 166 } | 201 } |
| 167 void didGetReadable() override | 202 void didGetReadable() override |
| 168 { | 203 { |
| 169 ASSERT_NOT_REACHED(); | 204 ASSERT_NOT_REACHED(); |
| 170 } | 205 } |
| 171 | 206 |
| 172 OwnPtr<WebDataConsumerHandle> m_handle; | 207 OwnPtr<WebDataConsumerHandle> m_handle; |
| 173 }; | 208 }; |
| 174 }; | 209 }; |
| 175 | 210 |
| 176 } // namespace blink | 211 } // namespace blink |
| 177 | 212 |
| 178 #endif // DataConsumerHandleTestUtil_h | 213 #endif // DataConsumerHandleTestUtil_h |
| OLD | NEW |