1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "bindings/core/v8/ScriptStreamerThread.h"
#include "bindings/core/v8/ScriptStreamer.h"
#include "platform/Task.h"
#include "platform/TraceEvent.h"
#include "public/platform/Platform.h"
#include "wtf/MainThread.h"
#include "wtf/PassOwnPtr.h"
namespace blink {
static ScriptStreamerThread* s_sharedThread = 0;
// Guards s_sharedThread. s_sharedThread is initialized and deleted in the main
// thread, but also used by the streamer thread. Races can occur during
// shutdown.
static Mutex* s_mutex = 0;
void ScriptStreamerThread::init()
{
ASSERT(!s_sharedThread);
ASSERT(isMainThread());
// This is called in the main thread before any tasks are created, so no
// locking is needed.
s_mutex = new Mutex();
s_sharedThread = new ScriptStreamerThread();
}
void ScriptStreamerThread::shutdown()
{
ASSERT(s_sharedThread);
ScriptStreamerThread* toDelete;
{
MutexLocker locker(*s_mutex);
toDelete = s_sharedThread;
// The background thread can now safely check s_sharedThread; if it's
// not 0, we're not shutting down.
s_sharedThread = 0;
}
// This will run the pending tasks into completion. We shouldn't hold the
// mutex while doing that.
delete toDelete;
// Now it's safe to delete s_mutex, since there are no tasks that could
// access it later.
delete s_mutex;
}
ScriptStreamerThread* ScriptStreamerThread::shared()
{
return s_sharedThread;
}
void ScriptStreamerThread::postTask(WebThread::Task* task)
{
ASSERT(isMainThread());
MutexLocker locker(m_mutex);
ASSERT(!m_runningTask);
m_runningTask = true;
platformThread().postTask(task);
}
void ScriptStreamerThread::taskDone()
{
MutexLocker locker(m_mutex);
ASSERT(m_runningTask);
m_runningTask = false;
}
blink::WebThread& ScriptStreamerThread::platformThread()
{
if (!isRunning())
m_thread = adoptPtr(blink::Platform::current()->createThread("ScriptStreamerThread"));
return *m_thread;
}
ScriptStreamingTask::ScriptStreamingTask(WTF::PassOwnPtr<v8::ScriptCompiler::ScriptStreamingTask> task, ScriptStreamer* streamer)
: m_v8Task(task), m_streamer(streamer) { }
void ScriptStreamingTask::run()
{
TRACE_EVENT0("v8", "v8.parseOnBackground");
// Running the task can and will block: SourceStream::GetSomeData will get
// called and it will block and wait for data from the network.
m_v8Task->Run();
m_streamer->streamingCompleteOnBackgroundThread();
MutexLocker locker(*s_mutex);
ScriptStreamerThread* thread = ScriptStreamerThread::shared();
if (thread)
thread->taskDone();
// If thread is 0, we're shutting down.
}
} // namespace blink
|