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( ...@@ -922,6 +922,16 @@ void BlinkPlatformImpl::didStopWorkerRunLoop(
worker_task_runner->OnWorkerRunLoopStopped(runLoop); 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() { blink::WebCrypto* BlinkPlatformImpl::crypto() {
WebCryptoImpl::EnsureInit(); WebCryptoImpl::EnsureInit();
return &web_crypto_; return &web_crypto_;
......
...@@ -148,6 +148,10 @@ class CONTENT_EXPORT BlinkPlatformImpl ...@@ -148,6 +148,10 @@ class CONTENT_EXPORT BlinkPlatformImpl
const blink::WebWorkerRunLoop& runLoop) OVERRIDE; const blink::WebWorkerRunLoop& runLoop) OVERRIDE;
virtual void didStopWorkerRunLoop( virtual void didStopWorkerRunLoop(
const blink::WebWorkerRunLoop& runLoop) OVERRIDE; const blink::WebWorkerRunLoop& runLoop) OVERRIDE;
virtual void didStartWorkerThread(
blink::WebThread* thread);
virtual void didStopWorkerThread(
blink::WebThread* thread);
virtual blink::WebCrypto* crypto() OVERRIDE; virtual blink::WebCrypto* crypto() OVERRIDE;
void SetFlingCurveParameters(const std::vector<float>& new_touchpad, void SetFlingCurveParameters(const std::vector<float>& new_touchpad,
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
// An implementation of WebThread in terms of base::MessageLoop and // An implementation of WebThread in terms of base::MessageLoop and
// base::Thread // base::Thread
#include <math.h>
#include "content/child/webthread_impl.h" #include "content/child/webthread_impl.h"
#include "base/bind.h" #include "base/bind.h"
...@@ -88,6 +90,30 @@ bool WebThreadImpl::isCurrentThread() const { ...@@ -88,6 +90,30 @@ bool WebThreadImpl::isCurrentThread() const {
return thread_->thread_id() == base::PlatformThread::CurrentId(); 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() { WebThreadImpl::~WebThreadImpl() {
thread_->Stop(); thread_->Stop();
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "base/timer/timer.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "third_party/WebKit/public/platform/WebThread.h" #include "third_party/WebKit/public/platform/WebThread.h"
...@@ -23,6 +24,11 @@ class CONTENT_EXPORT WebThreadBase : public blink::WebThread { ...@@ -23,6 +24,11 @@ class CONTENT_EXPORT WebThreadBase : public blink::WebThread {
virtual bool isCurrentThread() const = 0; virtual bool isCurrentThread() const = 0;
typedef void (*SharedTimerFunction)();
virtual void setSharedTimerFiredFunction(SharedTimerFunction timerFunction) {}
virtual void setSharedTimerFireInterval(double) {}
virtual void stopSharedTimer() {}
protected: protected:
WebThreadBase(); WebThreadBase();
...@@ -48,7 +54,19 @@ class CONTENT_EXPORT WebThreadImpl : public WebThreadBase { ...@@ -48,7 +54,19 @@ class CONTENT_EXPORT WebThreadImpl : public WebThreadBase {
virtual bool isCurrentThread() const OVERRIDE; virtual bool isCurrentThread() const OVERRIDE;
virtual void setSharedTimerFiredFunction(
SharedTimerFunction timerFunction) OVERRIDE;
virtual void setSharedTimerFireInterval(double interval_seconds) OVERRIDE;
virtual void stopSharedTimer() OVERRIDE;
private: private:
void OnTimeout() {
if (shared_timer_function_)
shared_timer_function_();
}
base::OneShotTimer<WebThreadImpl> shared_timer_;
SharedTimerFunction shared_timer_function_;
scoped_ptr<base::Thread> thread_; scoped_ptr<base::Thread> thread_;
}; };
......
...@@ -16,11 +16,22 @@ namespace content { ...@@ -16,11 +16,22 @@ namespace content {
namespace { 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: public:
RunClosureTask(const base::Closure& task) : task_(task) {} RunClosureTask(const base::Closure& task) : task_(task) {}
virtual ~RunClosureTask() {} virtual ~RunClosureTask() {}
virtual void Run() { virtual void run() {
task_.Run(); task_.Run();
} }
private: private:
...@@ -31,10 +42,14 @@ class RunClosureTask : public WebWorkerRunLoop::Task { ...@@ -31,10 +42,14 @@ class RunClosureTask : public WebWorkerRunLoop::Task {
struct WorkerTaskRunner::ThreadLocalState { struct WorkerTaskRunner::ThreadLocalState {
ThreadLocalState(int id, const WebWorkerRunLoop& loop) 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_; int id_;
WebWorkerRunLoop run_loop_; WebWorkerRunLoop run_loop_;
blink::WebThread* thread_;
ObserverList<WorkerTaskRunner::Observer> stop_observers_; ObserverList<WorkerTaskRunner::Observer> stop_observers_;
}; };
...@@ -48,18 +63,31 @@ bool WorkerTaskRunner::PostTask( ...@@ -48,18 +63,31 @@ bool WorkerTaskRunner::PostTask(
int id, const base::Closure& closure) { int id, const base::Closure& closure) {
DCHECK(id > 0); DCHECK(id > 0);
base::AutoLock locker(loop_map_lock_); base::AutoLock locker(loop_map_lock_);
IDToLoopMap::iterator found = loop_map_.find(id); IDToLoopMap::iterator found = loop_map_.find(id);
if (found == loop_map_.end()) if (found != loop_map_.end())
return false; return found->second.postTask(new RunLoopRunClosureTask(closure));
return found->second.postTask(new RunClosureTask(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) { int WorkerTaskRunner::PostTaskToAllThreads(const base::Closure& closure) {
base::AutoLock locker(loop_map_lock_); base::AutoLock locker(loop_map_lock_);
IDToLoopMap::iterator it; IDToLoopMap::iterator it;
for (it = loop_map_.begin(); it != loop_map_.end(); ++it) for (it = loop_map_.begin(); it != loop_map_.end(); ++it)
it->second.postTask(new RunClosureTask(closure)); it->second.postTask(new RunLoopRunClosureTask(closure));
return static_cast<int>(loop_map_.size());
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() { int WorkerTaskRunner::CurrentWorkerId() {
...@@ -109,4 +137,26 @@ void WorkerTaskRunner::OnWorkerRunLoopStopped(const WebWorkerRunLoop& loop) { ...@@ -109,4 +137,26 @@ void WorkerTaskRunner::OnWorkerRunLoopStopped(const WebWorkerRunLoop& loop) {
current_tls_.Set(NULL); 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 } // namespace content
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/threading/thread_local.h" #include "base/threading/thread_local.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "third_party/WebKit/public/platform/WebThread.h"
#include "third_party/WebKit/public/platform/WebWorkerRunLoop.h" #include "third_party/WebKit/public/platform/WebWorkerRunLoop.h"
namespace content { namespace content {
...@@ -39,10 +40,14 @@ class CONTENT_EXPORT WorkerTaskRunner { ...@@ -39,10 +40,14 @@ class CONTENT_EXPORT WorkerTaskRunner {
void OnWorkerRunLoopStarted(const blink::WebWorkerRunLoop& loop); void OnWorkerRunLoopStarted(const blink::WebWorkerRunLoop& loop);
void OnWorkerRunLoopStopped(const blink::WebWorkerRunLoop& loop); void OnWorkerRunLoopStopped(const blink::WebWorkerRunLoop& loop);
void OnWorkerThreadStarted(blink::WebThread* thread);
void OnWorkerThreadStopped(blink::WebThread* thread);
private: private:
friend class WorkerTaskRunnerTest; friend class WorkerTaskRunnerTest;
typedef std::map<int, blink::WebWorkerRunLoop> IDToLoopMap; typedef std::map<int, blink::WebWorkerRunLoop> IDToLoopMap;
typedef std::map<int, blink::WebThread*> IDToThreadMap;
~WorkerTaskRunner(); ~WorkerTaskRunner();
...@@ -51,6 +56,7 @@ class CONTENT_EXPORT WorkerTaskRunner { ...@@ -51,6 +56,7 @@ class CONTENT_EXPORT WorkerTaskRunner {
base::AtomicSequenceNumber id_sequence_; base::AtomicSequenceNumber id_sequence_;
IDToLoopMap loop_map_; IDToLoopMap loop_map_;
IDToThreadMap thread_map_;
base::Lock loop_map_lock_; 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