Commit 7a2c92ce authored by nasko@chromium.org's avatar nasko@chromium.org

Add WorkerThread based methods for start/stop of worker threads.

This patch adds notification methods for start/stop of worker threads which accept a WorkerThread parameter. This is needed in order to move the worker threads in blink to use WebThread instead of its own version.
It also adds support for shared timer to WebThreadImpl.

BUG=301515

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284008 0039d316-1c4b-4281-b951-d872f2087c98
parent 91464ea3
......@@ -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())
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;
return found->second.postTask(new RunClosureTask(closure));
}
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