Commit a9855b5c authored by dgrogan@chromium.org's avatar dgrogan@chromium.org

Track webcore worker message loops in chromium.

BUG=106265
TEST=


Review URL: http://codereview.chromium.org/8785013

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114157 0039d316-1c4b-4281-b951-d872f2087c98
parent 4f29a590
...@@ -436,6 +436,8 @@ ...@@ -436,6 +436,8 @@
'web_io_operators.h', 'web_io_operators.h',
'window_open_disposition.h', 'window_open_disposition.h',
'window_open_disposition.cc', 'window_open_disposition.cc',
'worker_task_runner.cc',
'worker_task_runner.h',
# These files used to be built in the webcore target, but moved here # These files used to be built in the webcore target, but moved here
# since part of glue. # since part of glue.
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "webkit/glue/websocketstreamhandle_impl.h" #include "webkit/glue/websocketstreamhandle_impl.h"
#include "webkit/glue/webthread_impl.h" #include "webkit/glue/webthread_impl.h"
#include "webkit/glue/weburlloader_impl.h" #include "webkit/glue/weburlloader_impl.h"
#include "webkit/glue/worker_task_runner.h"
#include "webkit/media/audio_decoder.h" #include "webkit/media/audio_decoder.h"
#include "webkit/plugins/npapi/plugin_instance.h" #include "webkit/plugins/npapi/plugin_instance.h"
#include "webkit/plugins/webplugininfo.h" #include "webkit/plugins/webplugininfo.h"
...@@ -686,4 +687,16 @@ void WebKitPlatformSupportImpl::DestroyCurrentThread(void* thread) { ...@@ -686,4 +687,16 @@ void WebKitPlatformSupportImpl::DestroyCurrentThread(void* thread) {
delete impl; delete impl;
} }
void WebKitPlatformSupportImpl::didStartWorkerRunLoop(
const WebKit::WebWorkerRunLoop& runLoop) {
WorkerTaskRunner* worker_task_runner = WorkerTaskRunner::Instance();
worker_task_runner->OnWorkerRunLoopStarted(runLoop);
}
void WebKitPlatformSupportImpl::didStopWorkerRunLoop(
const WebKit::WebWorkerRunLoop& runLoop) {
WorkerTaskRunner* worker_task_runner = WorkerTaskRunner::Instance();
worker_task_runner->OnWorkerRunLoopStopped(runLoop);
}
} // namespace webkit_glue } // namespace webkit_glue
...@@ -124,6 +124,11 @@ class WEBKIT_GLUE_EXPORT WebKitPlatformSupportImpl : ...@@ -124,6 +124,11 @@ class WEBKIT_GLUE_EXPORT WebKitPlatformSupportImpl :
void SuspendSharedTimer(); void SuspendSharedTimer();
void ResumeSharedTimer(); void ResumeSharedTimer();
virtual void didStartWorkerRunLoop(
const WebKit::WebWorkerRunLoop& runLoop) OVERRIDE;
virtual void didStopWorkerRunLoop(
const WebKit::WebWorkerRunLoop& runLoop) OVERRIDE;
private: private:
void DoTimeout() { void DoTimeout() {
if (shared_timer_func_ && !shared_timer_suspended_) if (shared_timer_func_ && !shared_timer_suspended_)
......
// Copyright (c) 2011 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 "base/callback.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "webkit/glue/worker_task_runner.h"
using WebKit::WebWorkerRunLoop;
namespace {
class RunClosureTask : public WebWorkerRunLoop::Task {
public:
RunClosureTask(const base::Closure& task) : task_(task) {}
virtual ~RunClosureTask() {}
virtual void Run() {
task_.Run();
}
private:
base::Closure task_;
};
} // unnamed namespace
namespace webkit_glue {
struct WorkerTaskRunner::ThreadLocalState {
ThreadLocalState(int id, const WebWorkerRunLoop& loop)
: id_(id), run_loop_(loop) {
}
int id_;
WebWorkerRunLoop run_loop_;
ObserverList<WorkerTaskRunner::Observer> stop_observers_;
};
WorkerTaskRunner::WorkerTaskRunner() {
// Start worker ids at 1, 0 is reserved for the main thread.
int id = id_sequence_.GetNext();
DCHECK(!id);
}
void WorkerTaskRunner::PostTask(
int id, const base::Closure& closure) {
DCHECK(id > 0);
base::AutoLock locker(loop_map_lock_);
IDToLoopMap::iterator found = loop_map_.find(id);
if (found != loop_map_.end())
found->second.postTask(new RunClosureTask(closure));
}
int WorkerTaskRunner::CurrentWorkerId() {
if (!current_tls_.Get())
return 0;
return current_tls_.Get()->id_;
}
WorkerTaskRunner* WorkerTaskRunner::Instance() {
static base::LazyInstance<WorkerTaskRunner,
base::LeakyLazyInstanceTraits<WorkerTaskRunner> >
worker_task_runner = LAZY_INSTANCE_INITIALIZER;
return worker_task_runner.Pointer();
}
void WorkerTaskRunner::AddStopObserver(Observer* obs) {
DCHECK(CurrentWorkerId() > 0);
current_tls_.Get()->stop_observers_.AddObserver(obs);
}
void WorkerTaskRunner::RemoveStopObserver(Observer* obs) {
DCHECK(CurrentWorkerId() > 0);
current_tls_.Get()->stop_observers_.RemoveObserver(obs);
}
WorkerTaskRunner::~WorkerTaskRunner() {
}
void WorkerTaskRunner::OnWorkerRunLoopStarted(const WebWorkerRunLoop& loop) {
DCHECK(!current_tls_.Get());
int id = id_sequence_.GetNext();
current_tls_.Set(new ThreadLocalState(id, loop));
base::AutoLock locker_(loop_map_lock_);
loop_map_[id] = loop;
}
void WorkerTaskRunner::OnWorkerRunLoopStopped(const WebWorkerRunLoop& loop) {
DCHECK(current_tls_.Get());
FOR_EACH_OBSERVER(Observer, current_tls_.Get()->stop_observers_,
OnWorkerRunLoopStopped());
{
base::AutoLock locker(loop_map_lock_);
DCHECK(loop_map_[CurrentWorkerId()] == loop);
loop_map_.erase(CurrentWorkerId());
}
delete current_tls_.Get();
current_tls_.Set(NULL);
}
} // namespace webkit_glue
// Copyright (c) 2011 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.
#ifndef WEBKIT_GLUE_WORKER_TASK_RUNNER_H_
#define WEBKIT_GLUE_WORKER_TASK_RUNNER_H_
#pragma once
#include <map>
#include "base/atomic_sequence_num.h"
#include "base/callback_forward.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_local.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebWorkerRunLoop.h"
namespace webkit_glue {
class WorkerTaskRunner {
public:
WorkerTaskRunner();
void PostTask(int id, const base::Closure& task);
int CurrentWorkerId();
static WorkerTaskRunner* Instance();
class Observer {
public:
virtual ~Observer() {}
virtual void OnWorkerRunLoopStopped() = 0;
};
// Add/Remove an observer that will get notified when the current worker run
// loop is stopping. This observer will not get notified when other threads
// are stopping. It's only valid to call these on a worker thread.
void AddStopObserver(Observer* observer);
void RemoveStopObserver(Observer* observer);
private:
friend class WebKitPlatformSupportImpl;
friend class WorkerTaskRunnerTest;
typedef std::map<int, WebKit::WebWorkerRunLoop> IDToLoopMap;
~WorkerTaskRunner();
void OnWorkerRunLoopStarted(const WebKit::WebWorkerRunLoop& loop);
void OnWorkerRunLoopStopped(const WebKit::WebWorkerRunLoop& loop);
struct ThreadLocalState;
base::ThreadLocalPointer<ThreadLocalState> current_tls_;
base::AtomicSequenceNumber id_sequence_;
IDToLoopMap loop_map_;
base::Lock loop_map_lock_;
};
} // namespace webkit_glue
#endif // WEBKIT_GLUE_WORKER_TASK_RUNNER_H_
// Copyright (c) 2011 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 "base/logging.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/glue/worker_task_runner.h"
namespace webkit_glue {
class WorkerTaskRunnerTest : public testing::Test {
public:
void FakeStart() {
task_runner_.OnWorkerRunLoopStarted(WebKit::WebWorkerRunLoop());
}
void FakeStop() {
task_runner_.OnWorkerRunLoopStopped(WebKit::WebWorkerRunLoop());
}
WorkerTaskRunner task_runner_;
};
class MockObserver : public WorkerTaskRunner::Observer {
public:
MOCK_METHOD0(OnWorkerRunLoopStopped, void());
void RemoveSelfOnNotify() {
ON_CALL(*this, OnWorkerRunLoopStopped()).WillByDefault(
testing::Invoke(this, &MockObserver::RemoveSelf));
}
void RemoveSelf() {
runner_->RemoveStopObserver(this);
}
WorkerTaskRunner* runner_;
};
TEST_F(WorkerTaskRunnerTest, BasicObservingAndWorkerId) {
ASSERT_EQ(0, task_runner_.CurrentWorkerId());
MockObserver o;
EXPECT_CALL(o, OnWorkerRunLoopStopped()).Times(1);
FakeStart();
task_runner_.AddStopObserver(&o);
ASSERT_LT(0, task_runner_.CurrentWorkerId());
FakeStop();
}
TEST_F(WorkerTaskRunnerTest, CanRemoveSelfDuringNotification) {
MockObserver o;
o.RemoveSelfOnNotify();
o.runner_ = &task_runner_;
EXPECT_CALL(o, OnWorkerRunLoopStopped()).Times(1);
FakeStart();
task_runner_.AddStopObserver(&o);
FakeStop();
}
}
...@@ -429,6 +429,7 @@ ...@@ -429,6 +429,7 @@
'../../glue/webframe_unittest.cc', '../../glue/webframe_unittest.cc',
'../../glue/webkit_glue_unittest.cc', '../../glue/webkit_glue_unittest.cc',
'../../glue/webview_unittest.cc', '../../glue/webview_unittest.cc',
'../../glue/worker_task_runner_unittest.cc',
'../../media/buffered_data_source_unittest.cc', '../../media/buffered_data_source_unittest.cc',
'../../media/buffered_resource_loader_unittest.cc', '../../media/buffered_resource_loader_unittest.cc',
'../../media/simple_data_source_unittest.cc', '../../media/simple_data_source_unittest.cc',
......
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