Commit a04e692f authored by nasko@chromium.org's avatar nasko@chromium.org

Prepare chromium for WorkerThread migration to WebThread.

This patch is reland of https://codereview.chromium.org/393283003/ with some fixes.
The corresponding Blink work is at https://codereview.chromium.org/400153002/.

BUG=301515

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284113 0039d316-1c4b-4281-b951-d872f2087c98
parent 0587b9be
......@@ -922,6 +922,16 @@ void BlinkPlatformImpl::didStopWorkerRunLoop(
worker_task_runner->OnWorkerRunLoopStopped(runLoop);
}
void BlinkPlatformImpl::didStartWorkerThread(blink::WebThread* thread) {
WorkerTaskRunner* worker_task_runner = WorkerTaskRunner::Instance();
worker_task_runner->OnWorkerThreadStarted(thread);
}
void BlinkPlatformImpl::didStopWorkerThread(blink::WebThread* thread) {
WorkerTaskRunner* worker_task_runner = WorkerTaskRunner::Instance();
worker_task_runner->OnWorkerThreadStopped(thread);
}
blink::WebCrypto* BlinkPlatformImpl::crypto() {
WebCryptoImpl::EnsureInit();
return &web_crypto_;
......
......@@ -148,6 +148,10 @@ class CONTENT_EXPORT BlinkPlatformImpl
const blink::WebWorkerRunLoop& runLoop) OVERRIDE;
virtual void didStopWorkerRunLoop(
const blink::WebWorkerRunLoop& runLoop) OVERRIDE;
virtual void didStartWorkerThread(
blink::WebThread* thread);
virtual void didStopWorkerThread(
blink::WebThread* thread);
virtual blink::WebCrypto* crypto() OVERRIDE;
void SetFlingCurveParameters(const std::vector<float>& new_touchpad,
......
......@@ -5,6 +5,8 @@
// An implementation of WebThread in terms of base::MessageLoop and
// base::Thread
#include <math.h>
#include "content/child/webthread_impl.h"
#include "base/bind.h"
......@@ -88,6 +90,30 @@ bool WebThreadImpl::isCurrentThread() const {
return thread_->thread_id() == base::PlatformThread::CurrentId();
}
void WebThreadImpl::setSharedTimerFiredFunction(
SharedTimerFunction timerFunction) {
shared_timer_function_ = timerFunction;
}
void WebThreadImpl::setSharedTimerFireInterval(double interval_seconds) {
// See BlinkPlatformImpl::setSharedTimerFireInterval for explanation of
// why ceil is used in the interval calculation.
int64 interval = static_cast<int64>(
ceil(interval_seconds * base::Time::kMillisecondsPerSecond)
* base::Time::kMicrosecondsPerMillisecond);
if (interval < 0)
interval = 0;
shared_timer_.Stop();
shared_timer_.Start(FROM_HERE, base::TimeDelta::FromMicroseconds(interval),
this, &WebThreadImpl::OnTimeout);
}
void WebThreadImpl::stopSharedTimer() {
shared_timer_.Stop();
}
WebThreadImpl::~WebThreadImpl() {
thread_->Stop();
}
......
......@@ -9,6 +9,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread.h"
#include "base/timer/timer.h"
#include "content/common/content_export.h"
#include "third_party/WebKit/public/platform/WebThread.h"
......@@ -23,6 +24,11 @@ class CONTENT_EXPORT WebThreadBase : public blink::WebThread {
virtual bool isCurrentThread() const = 0;
typedef void (*SharedTimerFunction)();
virtual void setSharedTimerFiredFunction(SharedTimerFunction timerFunction) {}
virtual void setSharedTimerFireInterval(double) {}
virtual void stopSharedTimer() {}
protected:
WebThreadBase();
......@@ -48,7 +54,19 @@ class CONTENT_EXPORT WebThreadImpl : public WebThreadBase {
virtual bool isCurrentThread() const OVERRIDE;
virtual void setSharedTimerFiredFunction(
SharedTimerFunction timerFunction) OVERRIDE;
virtual void setSharedTimerFireInterval(double interval_seconds) OVERRIDE;
virtual void stopSharedTimer() OVERRIDE;
private:
void OnTimeout() {
if (shared_timer_function_)
shared_timer_function_();
}
base::OneShotTimer<WebThreadImpl> shared_timer_;
SharedTimerFunction shared_timer_function_;
scoped_ptr<base::Thread> thread_;
};
......
......@@ -16,11 +16,22 @@ namespace content {
namespace {
class RunClosureTask : public WebWorkerRunLoop::Task {
class RunLoopRunClosureTask : public WebWorkerRunLoop::Task {
public:
RunLoopRunClosureTask(const base::Closure& task) : task_(task) {}
virtual ~RunLoopRunClosureTask() {}
virtual void Run() {
task_.Run();
}
private:
base::Closure task_;
};
class RunClosureTask : public blink::WebThread::Task {
public:
RunClosureTask(const base::Closure& task) : task_(task) {}
virtual ~RunClosureTask() {}
virtual void Run() {
virtual void run() {
task_.Run();
}
private:
......@@ -31,10 +42,14 @@ class RunClosureTask : public WebWorkerRunLoop::Task {
struct WorkerTaskRunner::ThreadLocalState {
ThreadLocalState(int id, const WebWorkerRunLoop& loop)
: id_(id), run_loop_(loop) {
: id_(id), run_loop_(loop), thread_(0) {
}
ThreadLocalState(int id, blink::WebThread* thread)
: id_(id), thread_(thread) {
}
int id_;
WebWorkerRunLoop run_loop_;
blink::WebThread* thread_;
ObserverList<WorkerTaskRunner::Observer> stop_observers_;
};
......@@ -48,18 +63,31 @@ bool 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())
return false;
return found->second.postTask(new RunClosureTask(closure));
if (found != loop_map_.end())
return found->second.postTask(new RunLoopRunClosureTask(closure));
IDToThreadMap::iterator thread_found = thread_map_.find(id);
if (thread_found != thread_map_.end()) {
thread_found->second->postTask(new RunClosureTask(closure));
return true;
}
return false;
}
int WorkerTaskRunner::PostTaskToAllThreads(const base::Closure& closure) {
base::AutoLock locker(loop_map_lock_);
IDToLoopMap::iterator it;
for (it = loop_map_.begin(); it != loop_map_.end(); ++it)
it->second.postTask(new RunClosureTask(closure));
return static_cast<int>(loop_map_.size());
it->second.postTask(new RunLoopRunClosureTask(closure));
IDToThreadMap::iterator iter;
for (iter = thread_map_.begin(); iter != thread_map_.end(); ++iter)
iter->second->postTask(new RunClosureTask(closure));
return static_cast<int>(loop_map_.size() + thread_map_.size());
}
int WorkerTaskRunner::CurrentWorkerId() {
......@@ -109,4 +137,26 @@ void WorkerTaskRunner::OnWorkerRunLoopStopped(const WebWorkerRunLoop& loop) {
current_tls_.Set(NULL);
}
void WorkerTaskRunner::OnWorkerThreadStarted(blink::WebThread* thread) {
DCHECK(!current_tls_.Get());
int id = id_sequence_.GetNext();
current_tls_.Set(new ThreadLocalState(id, thread));
base::AutoLock locker_(loop_map_lock_);
thread_map_[id] = thread;
}
void WorkerTaskRunner::OnWorkerThreadStopped(blink::WebThread* thread) {
DCHECK(current_tls_.Get());
FOR_EACH_OBSERVER(Observer, current_tls_.Get()->stop_observers_,
OnWorkerRunLoopStopped());
{
base::AutoLock locker(loop_map_lock_);
DCHECK(thread_map_[CurrentWorkerId()] == thread);
thread_map_.erase(CurrentWorkerId());
}
delete current_tls_.Get();
current_tls_.Set(NULL);
}
} // namespace content
......@@ -12,6 +12,7 @@
#include "base/synchronization/lock.h"
#include "base/threading/thread_local.h"
#include "content/common/content_export.h"
#include "third_party/WebKit/public/platform/WebThread.h"
#include "third_party/WebKit/public/platform/WebWorkerRunLoop.h"
namespace content {
......@@ -39,10 +40,14 @@ class CONTENT_EXPORT WorkerTaskRunner {
void OnWorkerRunLoopStarted(const blink::WebWorkerRunLoop& loop);
void OnWorkerRunLoopStopped(const blink::WebWorkerRunLoop& loop);
void OnWorkerThreadStarted(blink::WebThread* thread);
void OnWorkerThreadStopped(blink::WebThread* thread);
private:
friend class WorkerTaskRunnerTest;
typedef std::map<int, blink::WebWorkerRunLoop> IDToLoopMap;
typedef std::map<int, blink::WebThread*> IDToThreadMap;
~WorkerTaskRunner();
......@@ -51,6 +56,7 @@ class CONTENT_EXPORT WorkerTaskRunner {
base::AtomicSequenceNumber id_sequence_;
IDToLoopMap loop_map_;
IDToThreadMap thread_map_;
base::Lock loop_map_lock_;
};
......
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