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