Commit ecb14fad authored by kinuko@chromium.org's avatar kinuko@chromium.org

Makes WebThreadSupportingGC constructible for an existing thread

Alternative approach for http://crrev.com/1274023003

Add WebThreadSupportingGC::createForThread(), which takes an
existing thread and add GC support for the thread.

If a thread is not given WebThreadSupportingGC creates a new thread
and owns it, otherwise it just uses the given thread.

BUG=518708

Review URL: https://codereview.chromium.org/1319363002

git-svn-id: svn://svn.chromium.org/blink/trunk@201549 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 8c5ce1d6
...@@ -20,13 +20,13 @@ namespace { ...@@ -20,13 +20,13 @@ namespace {
static CompositorWorkerManager* s_instance = nullptr; static CompositorWorkerManager* s_instance = nullptr;
static Mutex& singletonMutex() Mutex& singletonMutex()
{ {
AtomicallyInitializedStaticReference(Mutex, mutex, new Mutex); AtomicallyInitializedStaticReference(Mutex, mutex, new Mutex);
return mutex; return mutex;
} }
static void destroyThread(WebThreadSupportingGC* thread) void destroyThread(WebThread* thread)
{ {
delete thread; delete thread;
} }
...@@ -69,7 +69,11 @@ WebThreadSupportingGC& CompositorWorkerManager::compositorWorkerThread() ...@@ -69,7 +69,11 @@ WebThreadSupportingGC& CompositorWorkerManager::compositorWorkerThread()
if (!m_thread) { if (!m_thread) {
ASSERT(isMainThread()); ASSERT(isMainThread());
ASSERT(!m_workerCount); ASSERT(!m_workerCount);
m_thread = WebThreadSupportingGC::create("CompositorWorker Thread"); // TODO(sadrul): Instead of creating a new thread, retrieve the thread from
// Platform using a more specialized function
// (e.g. Platform::compositorWorkerThread()).
m_platformThread = adoptPtr(Platform::current()->createThread("CompositorWorker Thread"));
m_thread = WebThreadSupportingGC::createForThread(m_platformThread.get());
} }
return *m_thread.get(); return *m_thread.get();
} }
...@@ -102,8 +106,8 @@ void CompositorWorkerManager::shutdownBackingThread() ...@@ -102,8 +106,8 @@ void CompositorWorkerManager::shutdownBackingThread()
--m_workerCount; --m_workerCount;
if (m_workerCount == 0) { if (m_workerCount == 0) {
m_thread->shutdown(); m_thread->shutdown();
Platform::current()->mainThread()->postTask(FROM_HERE, threadSafeBind(destroyThread, AllowCrossThreadAccess(m_thread.leakPtr())));
m_thread = nullptr; m_thread = nullptr;
Platform::current()->mainThread()->postTask(FROM_HERE, threadSafeBind(destroyThread, AllowCrossThreadAccess(m_platformThread.leakPtr())));
} }
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
namespace blink { namespace blink {
class V8IsolateInterruptor; class V8IsolateInterruptor;
class WebThread;
class WebThreadSupportingGC; class WebThreadSupportingGC;
class MODULES_EXPORT CompositorWorkerManager final { class MODULES_EXPORT CompositorWorkerManager final {
...@@ -46,6 +47,7 @@ private: ...@@ -46,6 +47,7 @@ private:
Mutex m_mutex; Mutex m_mutex;
OwnPtr<WebThreadSupportingGC> m_thread; OwnPtr<WebThreadSupportingGC> m_thread;
OwnPtr<WebThread> m_platformThread;
int m_workerCount = 0; int m_workerCount = 0;
v8::Isolate* m_isolate = nullptr; v8::Isolate* m_isolate = nullptr;
}; };
......
...@@ -13,40 +13,57 @@ namespace blink { ...@@ -13,40 +13,57 @@ namespace blink {
PassOwnPtr<WebThreadSupportingGC> WebThreadSupportingGC::create(const char* name) PassOwnPtr<WebThreadSupportingGC> WebThreadSupportingGC::create(const char* name)
{ {
#if ENABLE(ASSERT) return adoptPtr(new WebThreadSupportingGC(name, nullptr));
WTF::willCreateThread();
#endif
return adoptPtr(new WebThreadSupportingGC(name));
} }
WebThreadSupportingGC::WebThreadSupportingGC(const char* name) PassOwnPtr<WebThreadSupportingGC> WebThreadSupportingGC::createForThread(WebThread* thread)
: m_thread(adoptPtr(Platform::current()->createThread(name)))
{ {
return adoptPtr(new WebThreadSupportingGC(nullptr, thread));
}
WebThreadSupportingGC::WebThreadSupportingGC(const char* name, WebThread* thread)
: m_thread(thread)
{
#if ENABLE(ASSERT)
ASSERT(!name || !thread);
// We call this regardless of whether an existing thread is given or not,
// as it means that blink is going to run with more than one thread.
WTF::willCreateThread();
#endif
if (!m_thread) {
// If |thread| is not given, create a new one and own it.
m_owningThread = adoptPtr(Platform::current()->createThread(name));
m_thread = m_owningThread.get();
}
} }
WebThreadSupportingGC::~WebThreadSupportingGC() WebThreadSupportingGC::~WebThreadSupportingGC()
{ {
if (ThreadState::current()) { if (ThreadState::current() && m_owningThread) {
// WebThread's destructor blocks until all the tasks are processed. // WebThread's destructor blocks until all the tasks are processed.
SafePointScope scope(ThreadState::HeapPointersOnStack); SafePointScope scope(ThreadState::HeapPointersOnStack);
m_thread.clear(); m_owningThread.clear();
} }
} }
void WebThreadSupportingGC::initialize() void WebThreadSupportingGC::initialize()
{ {
m_pendingGCRunner = adoptPtr(new PendingGCRunner); m_pendingGCRunner = adoptPtr(new PendingGCRunner);
platformThread().addTaskObserver(m_pendingGCRunner.get()); m_thread->addTaskObserver(m_pendingGCRunner.get());
ThreadState::attach(); ThreadState::attach();
OwnPtr<MessageLoopInterruptor> interruptor = adoptPtr(new MessageLoopInterruptor(&platformThread())); OwnPtr<MessageLoopInterruptor> interruptor = adoptPtr(new MessageLoopInterruptor(m_thread));
ThreadState::current()->addInterruptor(interruptor.release()); ThreadState::current()->addInterruptor(interruptor.release());
} }
void WebThreadSupportingGC::shutdown() void WebThreadSupportingGC::shutdown()
{ {
// Ensure no posted tasks will run from this point on. // Ensure no posted tasks will run from this point on.
platformThread().removeTaskObserver(m_pendingGCRunner.get()); m_thread->removeTaskObserver(m_pendingGCRunner.get());
platformThread().scheduler()->shutdown();
// Shutdown the thread (via its scheduler) only when the thread is created
// and is owned by this instance.
if (m_owningThread)
m_owningThread->scheduler()->shutdown();
ThreadState::detach(); ThreadState::detach();
m_pendingGCRunner = nullptr; m_pendingGCRunner = nullptr;
......
...@@ -21,10 +21,14 @@ namespace blink { ...@@ -21,10 +21,14 @@ namespace blink {
// thread allocates any objects managed by the Blink GC. The shutdown // thread allocates any objects managed by the Blink GC. The shutdown
// method must be called on the WebThread during shutdown when the thread // method must be called on the WebThread during shutdown when the thread
// no longer needs to access objects managed by the Blink GC. // no longer needs to access objects managed by the Blink GC.
//
// WebThreadSupportingGC usually internally creates and owns WebThread unless
// an existing WebThread is given via createForThread.
class PLATFORM_EXPORT WebThreadSupportingGC final { class PLATFORM_EXPORT WebThreadSupportingGC final {
WTF_MAKE_NONCOPYABLE(WebThreadSupportingGC); WTF_MAKE_NONCOPYABLE(WebThreadSupportingGC);
public: public:
static PassOwnPtr<WebThreadSupportingGC> create(const char*); static PassOwnPtr<WebThreadSupportingGC> create(const char* name);
static PassOwnPtr<WebThreadSupportingGC> createForThread(WebThread*);
~WebThreadSupportingGC(); ~WebThreadSupportingGC();
void postTask(const WebTraceLocation& location, WebThread::Task* task) void postTask(const WebTraceLocation& location, WebThread::Task* task)
...@@ -62,10 +66,15 @@ public: ...@@ -62,10 +66,15 @@ public:
} }
private: private:
explicit WebThreadSupportingGC(const char*); WebThreadSupportingGC(const char* name, WebThread*);
OwnPtr<PendingGCRunner> m_pendingGCRunner; OwnPtr<PendingGCRunner> m_pendingGCRunner;
OwnPtr<WebThread> m_thread;
// m_thread is guaranteed to be non-null after this instance is constructed.
// m_owningThread is non-null unless this instance is constructed for an
// existing thread via createForThread().
WebThread* m_thread = nullptr;
OwnPtr<WebThread> m_owningThread;
}; };
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment