Commit e7035fac authored by horo@chromium.org's avatar horo@chromium.org

Refactor SharedWorkerHost and SharedWorkerInstance.

In this CL, I move the status variables of SharedWorker from SharedWorkerInstance to SharedWorkerHost.

The main purpose of this change is to make it possible to pass SharedWorkerInstance to SharedWorkerDevToolsManager and store it in WorkerInfo in http://crrev.com/196503005.

BUG=327256

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@260489 0039d316-1c4b-4281-b951-d872f2087c98
parent 0ce6f89b
......@@ -10,6 +10,7 @@
#include "content/browser/message_port_service.h"
#include "content/browser/shared_worker/shared_worker_instance.h"
#include "content/browser/shared_worker/shared_worker_message_filter.h"
#include "content/browser/worker_host/worker_document_set.h"
#include "content/common/view_messages.h"
#include "content/common/worker_messages.h"
#include "content/public/browser/browser_thread.h"
......@@ -31,8 +32,11 @@ void WorkerCrashCallback(int render_process_unique_id, int render_frame_id) {
SharedWorkerHost::SharedWorkerHost(SharedWorkerInstance* instance)
: instance_(instance),
worker_document_set_(new WorkerDocumentSet()),
container_render_filter_(NULL),
worker_route_id_(MSG_ROUTING_NONE),
load_failed_(false),
closed_(false),
creation_time_(base::TimeTicks::Now()) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
}
......@@ -42,9 +46,9 @@ SharedWorkerHost::~SharedWorkerHost() {
UMA_HISTOGRAM_LONG_TIMES("SharedWorker.TimeToDeleted",
base::TimeTicks::Now() - creation_time_);
// If we crashed, tell the RenderViewHosts.
if (instance_ && !instance_->load_failed()) {
if (instance_ && !load_failed_) {
const WorkerDocumentSet::DocumentInfoSet& parents =
instance_->worker_document_set()->documents();
worker_document_set_->documents();
for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter =
parents.begin();
parent_iter != parents.end();
......@@ -80,9 +84,8 @@ void SharedWorkerHost::Init(SharedWorkerMessageFilter* filter) {
params.route_id = worker_route_id_;
Send(new WorkerProcessMsg_CreateWorker(params));
for (SharedWorkerInstance::FilterList::const_iterator i =
instance_->filters().begin();
i != instance_->filters().end(); ++i) {
for (FilterList::const_iterator i = filters_.begin(); i != filters_.end();
++i) {
i->filter()->Send(new ViewMsg_WorkerCreated(i->route_id()));
}
}
......@@ -92,8 +95,7 @@ bool SharedWorkerHost::FilterMessage(const IPC::Message& message,
if (!instance_)
return false;
if (!instance_->closed() &&
instance_->HasFilter(filter, message.routing_id())) {
if (!closed_ && HasFilter(filter, message.routing_id())) {
RelayMessage(message, filter);
return true;
}
......@@ -104,9 +106,9 @@ bool SharedWorkerHost::FilterMessage(const IPC::Message& message,
void SharedWorkerHost::FilterShutdown(SharedWorkerMessageFilter* filter) {
if (!instance_)
return;
instance_->RemoveFilters(filter);
instance_->worker_document_set()->RemoveAll(filter);
if (instance_->worker_document_set()->IsEmpty()) {
RemoveFilters(filter);
worker_document_set_->RemoveAll(filter);
if (worker_document_set_->IsEmpty()) {
// This worker has no more associated documents - shut it down.
Send(new WorkerMsg_TerminateWorkerContext(worker_route_id_));
}
......@@ -117,8 +119,8 @@ void SharedWorkerHost::DocumentDetached(SharedWorkerMessageFilter* filter,
if (!instance_)
return;
// Walk all instances and remove the document from their document set.
instance_->worker_document_set()->Remove(filter, document_id);
if (instance_->worker_document_set()->IsEmpty()) {
worker_document_set_->Remove(filter, document_id);
if (worker_document_set_->IsEmpty()) {
// This worker has no more associated documents - shut it down.
Send(new WorkerMsg_TerminateWorkerContext(worker_route_id_));
}
......@@ -130,13 +132,14 @@ void SharedWorkerHost::WorkerContextClosed() {
// Set the closed flag - this will stop any further messages from
// being sent to the worker (messages can still be sent from the worker,
// for exception reporting, etc).
instance_->set_closed(true);
closed_ = true;
}
void SharedWorkerHost::WorkerContextDestroyed() {
if (!instance_)
return;
instance_.reset();
worker_document_set_ = NULL;
}
void SharedWorkerHost::WorkerScriptLoaded() {
......@@ -150,10 +153,9 @@ void SharedWorkerHost::WorkerScriptLoadFailed() {
base::TimeTicks::Now() - creation_time_);
if (!instance_)
return;
instance_->set_load_failed(true);
for (SharedWorkerInstance::FilterList::const_iterator i =
instance_->filters().begin();
i != instance_->filters().end(); ++i) {
load_failed_ = true;
for (FilterList::const_iterator i = filters_.begin(); i != filters_.end();
++i) {
i->filter()->Send(new ViewMsg_WorkerScriptLoadFailed(i->route_id()));
}
}
......@@ -161,9 +163,8 @@ void SharedWorkerHost::WorkerScriptLoadFailed() {
void SharedWorkerHost::WorkerConnected(int message_port_id) {
if (!instance_)
return;
for (SharedWorkerInstance::FilterList::const_iterator i =
instance_->filters().begin();
i != instance_->filters().end(); ++i) {
for (FilterList::const_iterator i = filters_.begin(); i != filters_.end();
++i) {
if (i->message_port_id() != message_port_id)
continue;
i->filter()->Send(new ViewMsg_WorkerConnected(i->route_id()));
......@@ -223,9 +224,8 @@ void SharedWorkerHost::RelayMessage(
sent_message_port_id,
container_render_filter_->message_port_message_filter(),
new_routing_id);
instance_->SetMessagePortID(incoming_filter,
message.routing_id(),
sent_message_port_id);
SetMessagePortID(
incoming_filter, message.routing_id(), sent_message_port_id);
// Resend the message with the new routing id.
Send(new WorkerMsg_Connect(
worker_route_id_, sent_message_port_id, new_routing_id));
......@@ -251,7 +251,7 @@ SharedWorkerHost::GetRenderFrameIDsForWorker() {
if (!instance_)
return result;
const WorkerDocumentSet::DocumentInfoSet& documents =
instance_->worker_document_set()->documents();
worker_document_set_->documents();
for (WorkerDocumentSet::DocumentInfoSet::const_iterator doc =
documents.begin();
doc != documents.end();
......@@ -262,4 +262,43 @@ SharedWorkerHost::GetRenderFrameIDsForWorker() {
return result;
}
void SharedWorkerHost::AddFilter(SharedWorkerMessageFilter* filter,
int route_id) {
CHECK(filter);
if (!HasFilter(filter, route_id)) {
FilterInfo info(filter, route_id);
filters_.push_back(info);
}
}
void SharedWorkerHost::RemoveFilters(SharedWorkerMessageFilter* filter) {
for (FilterList::iterator i = filters_.begin(); i != filters_.end();) {
if (i->filter() == filter)
i = filters_.erase(i);
else
++i;
}
}
bool SharedWorkerHost::HasFilter(SharedWorkerMessageFilter* filter,
int route_id) const {
for (FilterList::const_iterator i = filters_.begin(); i != filters_.end();
++i) {
if (i->filter() == filter && i->route_id() == route_id)
return true;
}
return false;
}
void SharedWorkerHost::SetMessagePortID(SharedWorkerMessageFilter* filter,
int route_id,
int message_port_id) {
for (FilterList::iterator i = filters_.begin(); i != filters_.end(); ++i) {
if (i->filter() == filter && i->route_id() == route_id) {
i->set_message_port_id(message_port_id);
return;
}
}
}
} // namespace content
......@@ -5,12 +5,14 @@
#ifndef CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_HOST_H_
#define CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_HOST_H_
#include <list>
#include <vector>
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "content/browser/shared_worker/shared_worker_message_filter.h"
#include "content/browser/worker_host/worker_document_set.h"
class GURL;
......@@ -68,7 +70,12 @@ class SharedWorkerHost {
// Terminates the given worker, i.e. based on a UI action.
void TerminateWorker();
void AddFilter(SharedWorkerMessageFilter* filter, int route_id);
SharedWorkerInstance* instance() { return instance_.get(); }
WorkerDocumentSet* worker_document_set() const {
return worker_document_set_.get();
}
SharedWorkerMessageFilter* container_render_filter() const {
return container_render_filter_;
}
......@@ -76,8 +83,28 @@ class SharedWorkerHost {
return container_render_filter_->render_process_id();
}
int worker_route_id() const { return worker_route_id_; }
bool load_failed() const { return load_failed_; }
bool closed() const { return closed_; }
private:
// Unique identifier for a worker client.
class FilterInfo {
public:
FilterInfo(SharedWorkerMessageFilter* filter, int route_id)
: filter_(filter), route_id_(route_id), message_port_id_(0) {}
SharedWorkerMessageFilter* filter() const { return filter_; }
int route_id() const { return route_id_; }
int message_port_id() const { return message_port_id_; }
void set_message_port_id(int id) { message_port_id_ = id; }
private:
SharedWorkerMessageFilter* filter_;
int route_id_;
int message_port_id_;
};
typedef std::list<FilterInfo> FilterList;
// Relays |message| to the SharedWorker. Takes care of parsing the message if
// it contains a message port and sending it a valid route id.
void RelayMessage(const IPC::Message& message,
......@@ -86,9 +113,19 @@ class SharedWorkerHost {
// Return a vector of all the render process/render frame IDs.
std::vector<std::pair<int, int> > GetRenderFrameIDsForWorker();
void RemoveFilters(SharedWorkerMessageFilter* filter);
bool HasFilter(SharedWorkerMessageFilter* filter, int route_id) const;
void SetMessagePortID(SharedWorkerMessageFilter* filter,
int route_id,
int message_port_id);
scoped_ptr<SharedWorkerInstance> instance_;
scoped_refptr<WorkerDocumentSet> worker_document_set_;
FilterList filters_;
SharedWorkerMessageFilter* container_render_filter_;
int worker_route_id_;
bool load_failed_;
bool closed_;
const base::TimeTicks creation_time_;
DISALLOW_COPY_AND_ASSIGN(SharedWorkerHost);
};
......
......@@ -5,7 +5,6 @@
#include "content/browser/shared_worker/shared_worker_instance.h"
#include "base/logging.h"
#include "content/browser/worker_host/worker_document_set.h"
namespace content {
......@@ -17,40 +16,21 @@ SharedWorkerInstance::SharedWorkerInstance(
ResourceContext* resource_context,
const WorkerStoragePartition& partition)
: url_(url),
closed_(false),
name_(name),
content_security_policy_(content_security_policy),
security_policy_type_(security_policy_type),
worker_document_set_(new WorkerDocumentSet()),
resource_context_(resource_context),
partition_(partition),
load_failed_(false) {
partition_(partition) {
DCHECK(resource_context_);
}
SharedWorkerInstance::~SharedWorkerInstance() {
}
void SharedWorkerInstance::SetMessagePortID(
SharedWorkerMessageFilter* filter,
int route_id,
int message_port_id) {
for (FilterList::iterator i = filters_.begin(); i != filters_.end(); ++i) {
if (i->filter() == filter && i->route_id() == route_id) {
i->set_message_port_id(message_port_id);
return;
}
}
}
bool SharedWorkerInstance::Matches(const GURL& match_url,
const base::string16& match_name,
const WorkerStoragePartition& partition,
ResourceContext* resource_context) const {
// Only match open shared workers.
if (closed_)
return false;
// ResourceContext equivalence is being used as a proxy to ensure we only
// matched shared workers within the same BrowserContext.
if (resource_context_ != resource_context)
......@@ -70,32 +50,4 @@ bool SharedWorkerInstance::Matches(const GURL& match_url,
return name_ == match_name;
}
void SharedWorkerInstance::AddFilter(SharedWorkerMessageFilter* filter,
int route_id) {
CHECK(filter);
if (!HasFilter(filter, route_id)) {
FilterInfo info(filter, route_id);
filters_.push_back(info);
}
}
void SharedWorkerInstance::RemoveFilters(SharedWorkerMessageFilter* filter) {
for (FilterList::iterator i = filters_.begin(); i != filters_.end();) {
if (i->filter() == filter)
i = filters_.erase(i);
else
++i;
}
}
bool SharedWorkerInstance::HasFilter(SharedWorkerMessageFilter* filter,
int route_id) const {
for (FilterList::const_iterator i = filters_.begin(); i != filters_.end();
++i) {
if (i->filter() == filter && i->route_id() == route_id)
return true;
}
return false;
}
} // namespace content
......@@ -5,11 +5,9 @@
#ifndef CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_INSTANCE_H_
#define CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_INSTANCE_H_
#include <list>
#include <string>
#include "base/basictypes.h"
#include "content/browser/worker_host/worker_document_set.h"
#include "content/browser/worker_host/worker_storage_partition.h"
#include "content/common/content_export.h"
#include "third_party/WebKit/public/web/WebContentSecurityPolicy.h"
......@@ -17,28 +15,9 @@
namespace content {
class ResourceContext;
class SharedWorkerMessageFilter;
class CONTENT_EXPORT SharedWorkerInstance {
public:
// Unique identifier for a worker client.
class FilterInfo {
public:
FilterInfo(SharedWorkerMessageFilter* filter, int route_id)
: filter_(filter), route_id_(route_id), message_port_id_(0) { }
SharedWorkerMessageFilter* filter() const { return filter_; }
int route_id() const { return route_id_; }
int message_port_id() const { return message_port_id_; }
void set_message_port_id(int id) { message_port_id_ = id; }
private:
SharedWorkerMessageFilter* filter_;
int route_id_;
int message_port_id_;
};
typedef std::list<FilterInfo> FilterList;
SharedWorkerInstance(const GURL& url,
const base::string16& name,
const base::string16& content_security_policy,
......@@ -47,14 +26,6 @@ class CONTENT_EXPORT SharedWorkerInstance {
const WorkerStoragePartition& partition);
~SharedWorkerInstance();
void AddFilter(SharedWorkerMessageFilter* filter, int route_id);
void RemoveFilters(SharedWorkerMessageFilter* filter);
bool HasFilter(SharedWorkerMessageFilter* filter, int route_id) const;
void SetMessagePortID(SharedWorkerMessageFilter* filter,
int route_id,
int message_port_id);
const FilterList& filters() const { return filters_; }
// Checks if this SharedWorkerInstance matches the passed url/name params
// based on the algorithm in the WebWorkers spec - an instance matches if the
// origins of the URLs match, and:
......@@ -68,8 +39,6 @@ class CONTENT_EXPORT SharedWorkerInstance {
ResourceContext* resource_context) const;
// Accessors.
bool closed() const { return closed_; }
void set_closed(bool closed) { closed_ = closed; }
const GURL& url() const { return url_; }
const base::string16 name() const { return name_; }
const base::string16 content_security_policy() const {
......@@ -78,29 +47,20 @@ class CONTENT_EXPORT SharedWorkerInstance {
blink::WebContentSecurityPolicyType security_policy_type() const {
return security_policy_type_;
}
WorkerDocumentSet* worker_document_set() const {
return worker_document_set_.get();
}
ResourceContext* resource_context() const {
return resource_context_;
}
const WorkerStoragePartition& partition() const {
return partition_;
}
void set_load_failed(bool failed) { load_failed_ = failed; }
bool load_failed() { return load_failed_; }
private:
GURL url_;
bool closed_;
base::string16 name_;
base::string16 content_security_policy_;
blink::WebContentSecurityPolicyType security_policy_type_;
FilterList filters_;
scoped_refptr<WorkerDocumentSet> worker_document_set_;
const GURL url_;
const base::string16 name_;
const base::string16 content_security_policy_;
const blink::WebContentSecurityPolicyType security_policy_type_;
ResourceContext* const resource_context_;
WorkerStoragePartition partition_;
bool load_failed_;
const WorkerStoragePartition partition_;
};
} // namespace content
......
......@@ -129,21 +129,21 @@ void SharedWorkerServiceImpl::CreateWorker(
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
ScopedWorkerDependencyChecker checker(this);
*url_mismatch = false;
SharedWorkerInstance* existing_instance =
FindSharedWorkerInstance(
SharedWorkerHost* existing_host = FindSharedWorkerHost(
params.url, params.name, partition, resource_context);
if (existing_instance) {
if (params.url != existing_instance->url()) {
if (existing_host) {
if (params.url != existing_host->instance()->url()) {
*url_mismatch = true;
return;
}
if (existing_instance->load_failed()) {
if (existing_host->load_failed()) {
filter->Send(new ViewMsg_WorkerScriptLoadFailed(route_id));
return;
}
existing_instance->AddFilter(filter, route_id);
existing_instance->worker_document_set()->Add(
filter, params.document_id, filter->render_process_id(),
existing_host->AddFilter(filter, route_id);
existing_host->worker_document_set()->Add(filter,
params.document_id,
filter->render_process_id(),
params.render_frame_route_id);
filter->Send(new ViewMsg_WorkerCreated(route_id));
return;
......@@ -156,12 +156,13 @@ void SharedWorkerServiceImpl::CreateWorker(
params.security_policy_type,
resource_context,
partition));
instance->AddFilter(filter, route_id);
instance->worker_document_set()->Add(
filter, params.document_id, filter->render_process_id(),
scoped_ptr<SharedWorkerHost> host(new SharedWorkerHost(instance.release()));
host->AddFilter(filter, route_id);
host->worker_document_set()->Add(filter,
params.document_id,
filter->render_process_id(),
params.render_frame_route_id);
scoped_ptr<SharedWorkerHost> host(new SharedWorkerHost(instance.release()));
host->Init(filter);
const int worker_route_id = host->worker_route_id();
worker_hosts_.set(std::make_pair(filter->render_process_id(),
......@@ -298,7 +299,7 @@ SharedWorkerHost* SharedWorkerServiceImpl::FindSharedWorkerHost(
worker_route_id));
}
SharedWorkerInstance* SharedWorkerServiceImpl::FindSharedWorkerInstance(
SharedWorkerHost* SharedWorkerServiceImpl::FindSharedWorkerHost(
const GURL& url,
const base::string16& name,
const WorkerStoragePartition& partition,
......@@ -307,8 +308,9 @@ SharedWorkerInstance* SharedWorkerServiceImpl::FindSharedWorkerInstance(
iter != worker_hosts_.end();
++iter) {
SharedWorkerInstance* instance = iter->second->instance();
if (instance && instance->Matches(url, name, partition, resource_context))
return instance;
if (instance && !iter->second->closed() &&
instance->Matches(url, name, partition, resource_context))
return iter->second;
}
return NULL;
}
......@@ -322,9 +324,9 @@ SharedWorkerServiceImpl::GetRenderersWithWorkerDependency() {
const int process_id = host_iter->first.first;
if (dependent_renderers.count(process_id))
continue;
SharedWorkerInstance* instance = host_iter->second->instance();
if (instance &&
instance->worker_document_set()->ContainsExternalRenderer(process_id)) {
if (host_iter->second->instance() &&
host_iter->second->worker_document_set()->ContainsExternalRenderer(
process_id)) {
dependent_renderers.insert(process_id);
}
}
......
......@@ -108,7 +108,7 @@ class CONTENT_EXPORT SharedWorkerServiceImpl
SharedWorkerMessageFilter* filter,
int worker_route_id);
SharedWorkerInstance* FindSharedWorkerInstance(
SharedWorkerHost* FindSharedWorkerHost(
const GURL& url,
const base::string16& name,
const WorkerStoragePartition& worker_partition,
......
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