Index: chrome/browser/extensions/extension_message_service.cc |
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc |
index bdd56209374b4e57dc0ea07076e0ae77130a7040..c4189b1485b51a47ee997fb71d59fca702a54f50 100644 |
--- a/chrome/browser/extensions/extension_message_service.cc |
+++ b/chrome/browser/extensions/extension_message_service.cc |
@@ -4,12 +4,11 @@ |
#include "chrome/browser/extensions/extension_message_service.h" |
+#include "base/atomic_sequence_num.h" |
#include "base/json/json_writer.h" |
-#include "base/singleton.h" |
#include "base/stl_util-inl.h" |
#include "base/values.h" |
#include "chrome/browser/child_process_security_policy.h" |
-#include "chrome/browser/chrome_thread.h" |
#include "chrome/browser/extensions/extension_process_manager.h" |
#include "chrome/browser/extensions/extension_tabs_module.h" |
#include "chrome/browser/profile.h" |
@@ -37,15 +36,9 @@ |
struct ExtensionMessageService::MessagePort { |
IPC::Message::Sender* sender; |
int routing_id; |
- // TODO(mpcomplete): remove this when I track down the crasher. Hopefully |
- // this guy will show up in some stack traces and potentially give some |
- // insight. |
- // http://code.google.com/p/chromium/issues/detail?id=21201 |
- int debug_info; |
- |
MessagePort(IPC::Message::Sender* sender = NULL, |
int routing_id = MSG_ROUTING_CONTROL) : |
- sender(sender), routing_id(routing_id), debug_info(0) {} |
+ sender(sender), routing_id(routing_id) {} |
}; |
struct ExtensionMessageService::MessageChannel { |
@@ -53,9 +46,19 @@ struct ExtensionMessageService::MessageChannel { |
ExtensionMessageService::MessagePort receiver; |
}; |
+const char ExtensionMessageService::kDispatchOnConnect[] = |
+ "Port.dispatchOnConnect"; |
+const char ExtensionMessageService::kDispatchOnDisconnect[] = |
+ "Port.dispatchOnDisconnect"; |
+const char ExtensionMessageService::kDispatchOnMessage[] = |
+ "Port.dispatchOnMessage"; |
+const char ExtensionMessageService::kDispatchEvent[] = |
+ "Event.dispatchJSON"; |
namespace { |
+static base::AtomicSequenceNumber g_next_channel_id(base::LINKER_INITIALIZED); |
+ |
static void DispatchOnConnect(const ExtensionMessageService::MessagePort& port, |
int dest_port_id, |
const std::string& channel_name, |
@@ -105,15 +108,6 @@ static void DispatchEvent(const ExtensionMessageService::MessagePort& port, |
} // namespace |
-const char ExtensionMessageService::kDispatchOnConnect[] = |
- "Port.dispatchOnConnect"; |
-const char ExtensionMessageService::kDispatchOnDisconnect[] = |
- "Port.dispatchOnDisconnect"; |
-const char ExtensionMessageService::kDispatchOnMessage[] = |
- "Port.dispatchOnMessage"; |
-const char ExtensionMessageService::kDispatchEvent[] = |
- "Event.dispatchJSON"; |
- |
// static |
std::string ExtensionMessageService::GetPerExtensionEventName( |
const std::string& event_name, const std::string& extension_id) { |
@@ -122,10 +116,28 @@ std::string ExtensionMessageService::GetPerExtensionEventName( |
return event_name + "/" + extension_id; |
} |
+// static |
+void ExtensionMessageService::AllocatePortIdPair(int* port1, int* port2) { |
+ int channel_id = g_next_channel_id.GetNext(); |
+ int port1_id = channel_id * 2; |
+ int port2_id = channel_id * 2 + 1; |
+ |
+ // Sanity checks to make sure our channel<->port converters are correct. |
+ DCHECK(IS_OPENER_PORT_ID(port1_id)); |
+ DCHECK(GET_OPPOSITE_PORT_ID(port1_id) == port2_id); |
+ DCHECK(GET_OPPOSITE_PORT_ID(port2_id) == port1_id); |
+ DCHECK(GET_CHANNEL_ID(port1_id) == GET_CHANNEL_ID(port2_id)); |
+ DCHECK(GET_CHANNEL_ID(port1_id) == channel_id); |
+ DCHECK(GET_CHANNEL_OPENER_ID(channel_id) == port1_id); |
+ DCHECK(GET_CHANNEL_RECEIVERS_ID(channel_id) == port2_id); |
+ |
+ *port1 = port1_id; |
+ *port2 = port2_id; |
+} |
+ |
ExtensionMessageService::ExtensionMessageService(Profile* profile) |
: profile_(profile), |
- extension_devtools_manager_(NULL), |
- next_port_id_(0) { |
+ extension_devtools_manager_(NULL) { |
registrar_.Add(this, NotificationType::RENDERER_PROCESS_TERMINATED, |
NotificationService::AllSources()); |
registrar_.Add(this, NotificationType::RENDERER_PROCESS_CLOSED, |
@@ -143,10 +155,8 @@ ExtensionMessageService::~ExtensionMessageService() { |
void ExtensionMessageService::ProfileDestroyed() { |
profile_ = NULL; |
- if (!registrar_.IsEmpty()) { |
- CHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
+ if (!registrar_.IsEmpty()) |
registrar_.RemoveAll(); |
- } |
} |
void ExtensionMessageService::AddEventListener(const std::string& event_name, |
@@ -157,7 +167,6 @@ void ExtensionMessageService::AddEventListener(const std::string& event_name, |
if (!rph || rph->ListenersIterator().IsAtEnd()) |
return; |
- DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
DCHECK_EQ(listeners_[event_name].count(render_process_id), 0u) << event_name; |
listeners_[event_name].insert(render_process_id); |
@@ -174,7 +183,6 @@ void ExtensionMessageService::RemoveEventListener(const std::string& event_name, |
if (!rph || rph->ListenersIterator().IsAtEnd()) |
return; |
- DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
DCHECK_EQ(listeners_[event_name].count(render_process_id), 1u) |
<< " PID=" << render_process_id << " event=" << event_name; |
listeners_[event_name].erase(render_process_id); |
@@ -191,74 +199,7 @@ bool ExtensionMessageService::HasEventListener( |
!listeners_[event_name].empty()); |
} |
-void ExtensionMessageService::AllocatePortIdPair(int* port1, int* port2) { |
- AutoLock lock(next_port_id_lock_); |
- |
- // TODO(mpcomplete): what happens when this wraps? |
- int port1_id = next_port_id_++; |
- int port2_id = next_port_id_++; |
- |
- DCHECK(IS_OPENER_PORT_ID(port1_id)); |
- DCHECK(GET_OPPOSITE_PORT_ID(port1_id) == port2_id); |
- DCHECK(GET_OPPOSITE_PORT_ID(port2_id) == port1_id); |
- DCHECK(GET_CHANNEL_ID(port1_id) == GET_CHANNEL_ID(port2_id)); |
- |
- int channel_id = GET_CHANNEL_ID(port1_id); |
- DCHECK(GET_CHANNEL_OPENER_ID(channel_id) == port1_id); |
- DCHECK(GET_CHANNEL_RECEIVERS_ID(channel_id) == port2_id); |
- |
- *port1 = port1_id; |
- *port2 = port2_id; |
-} |
- |
-int ExtensionMessageService::OpenChannelToExtension( |
- int routing_id, const std::string& source_extension_id, |
- const std::string& target_extension_id, |
- const std::string& channel_name, ResourceMessageFilter* source) { |
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
- |
- // Create a channel ID for both sides of the channel. |
- int port1_id = -1; |
- int port2_id = -1; |
- AllocatePortIdPair(&port1_id, &port2_id); |
- |
- // Each side of the port is given his own port ID. When they send messages, |
- // we convert to the opposite port ID. See PostMessageFromRenderer. |
- ChromeThread::PostTask( |
- ChromeThread::UI, FROM_HERE, |
- NewRunnableMethod( |
- this, &ExtensionMessageService::OpenChannelToExtensionOnUIThread, |
- source->id(), routing_id, port2_id, source_extension_id, |
- target_extension_id, channel_name)); |
- |
- return port1_id; |
-} |
- |
-int ExtensionMessageService::OpenChannelToTab(int routing_id, |
- int tab_id, |
- const std::string& extension_id, |
- const std::string& channel_name, |
- ResourceMessageFilter* source) { |
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
- |
- // Create a channel ID for both sides of the channel. |
- int port1_id = -1; |
- int port2_id = -1; |
- AllocatePortIdPair(&port1_id, &port2_id); |
- |
- // Each side of the port is given his own port ID. When they send messages, |
- // we convert to the opposite port ID. See PostMessageFromRenderer. |
- ChromeThread::PostTask( |
- ChromeThread::UI, FROM_HERE, |
- NewRunnableMethod( |
- this, &ExtensionMessageService::OpenChannelToTabOnUIThread, |
- source->id(), routing_id, port2_id, tab_id, extension_id, |
- channel_name)); |
- |
- return port1_id; |
-} |
- |
-void ExtensionMessageService::OpenChannelToExtensionOnUIThread( |
+void ExtensionMessageService::OpenChannelToExtension( |
int source_process_id, int source_routing_id, int receiver_port_id, |
const std::string& source_extension_id, |
const std::string& target_extension_id, |
@@ -274,7 +215,6 @@ void ExtensionMessageService::OpenChannelToExtensionOnUIThread( |
profile_->GetExtensionProcessManager()->GetExtensionProcess( |
target_extension_id), |
MSG_ROUTING_CONTROL); |
- receiver.debug_info = 1; |
TabContents* source_contents = tab_util::GetTabContentsByID( |
source_process_id, source_routing_id); |
@@ -286,13 +226,11 @@ void ExtensionMessageService::OpenChannelToExtensionOnUIThread( |
base::JSONWriter::Write(tab_value.get(), false, &tab_json); |
} |
- OpenChannelOnUIThreadImpl(source, tab_json, |
- receiver, receiver_port_id, |
- source_extension_id, target_extension_id, |
- channel_name); |
+ OpenChannelImpl(source, tab_json, receiver, receiver_port_id, |
+ source_extension_id, target_extension_id, channel_name); |
} |
-void ExtensionMessageService::OpenChannelToTabOnUIThread( |
+void ExtensionMessageService::OpenChannelToTab( |
int source_process_id, int source_routing_id, int receiver_port_id, |
int tab_id, const std::string& extension_id, |
const std::string& channel_name) { |
@@ -302,12 +240,10 @@ void ExtensionMessageService::OpenChannelToTabOnUIThread( |
TabContents* contents = NULL; |
MessagePort receiver; |
- receiver.debug_info = 2; |
if (ExtensionTabUtil::GetTabById(tab_id, source->profile(), true, |
NULL, NULL, &contents, NULL)) { |
receiver.sender = contents->render_view_host(); |
receiver.routing_id = contents->render_view_host()->routing_id(); |
- receiver.debug_info = 3; |
} |
if (contents && contents->controller().needs_reload()) { |
@@ -329,20 +265,17 @@ void ExtensionMessageService::OpenChannelToTabOnUIThread( |
base::JSONWriter::Write(tab_value.get(), false, &tab_json); |
} |
- OpenChannelOnUIThreadImpl(source, tab_json, |
- receiver, receiver_port_id, |
- extension_id, extension_id, channel_name); |
+ OpenChannelImpl(source, tab_json, receiver, receiver_port_id, |
+ extension_id, extension_id, channel_name); |
} |
-bool ExtensionMessageService::OpenChannelOnUIThreadImpl( |
+bool ExtensionMessageService::OpenChannelImpl( |
IPC::Message::Sender* source, |
const std::string& tab_json, |
const MessagePort& receiver, int receiver_port_id, |
const std::string& source_extension_id, |
const std::string& target_extension_id, |
const std::string& channel_name) { |
- DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
- |
// TODO(mpcomplete): notify source if receiver doesn't exist |
if (!source) |
return false; // Closed while in flight. |
@@ -380,7 +313,6 @@ bool ExtensionMessageService::OpenChannelOnUIThreadImpl( |
int ExtensionMessageService::OpenSpecialChannelToExtension( |
const std::string& extension_id, const std::string& channel_name, |
const std::string& tab_json, IPC::Message::Sender* source) { |
- DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
DCHECK(profile_); |
int port1_id = -1; |
@@ -392,10 +324,8 @@ int ExtensionMessageService::OpenSpecialChannelToExtension( |
profile_->GetExtensionProcessManager()-> |
GetExtensionProcess(extension_id), |
MSG_ROUTING_CONTROL); |
- receiver.debug_info = 4; |
- if (!OpenChannelOnUIThreadImpl( |
- source, tab_json, receiver, port2_id, extension_id, extension_id, |
- channel_name)) |
+ if (!OpenChannelImpl(source, tab_json, receiver, port2_id, |
+ extension_id, extension_id, channel_name)) |
return -1; |
return port1_id; |
@@ -404,7 +334,6 @@ int ExtensionMessageService::OpenSpecialChannelToExtension( |
int ExtensionMessageService::OpenSpecialChannelToTab( |
const std::string& extension_id, const std::string& channel_name, |
TabContents* target_tab_contents, IPC::Message::Sender* source) { |
- DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
DCHECK(target_tab_contents); |
if (target_tab_contents->controller().needs_reload()) { |
@@ -420,18 +349,14 @@ int ExtensionMessageService::OpenSpecialChannelToTab( |
MessagePort receiver( |
target_tab_contents->render_view_host(), |
target_tab_contents->render_view_host()->routing_id()); |
- receiver.debug_info = 5; |
- if (!OpenChannelOnUIThreadImpl(source, "null", |
- receiver, port2_id, |
- extension_id, extension_id, channel_name)) |
+ if (!OpenChannelImpl(source, "null", receiver, port2_id, |
+ extension_id, extension_id, channel_name)) |
return -1; |
return port1_id; |
} |
void ExtensionMessageService::CloseChannel(int port_id) { |
- DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
- |
// Note: The channel might be gone already, if the other side closed first. |
MessageChannelMap::iterator it = channels_.find(GET_CHANNEL_ID(port_id)); |
if (it != channels_.end()) |
@@ -441,8 +366,6 @@ void ExtensionMessageService::CloseChannel(int port_id) { |
void ExtensionMessageService::CloseChannelImpl( |
MessageChannelMap::iterator channel_iter, int closing_port_id, |
bool notify_other_port) { |
- DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
- |
// Notify the other side. |
const MessagePort& port = IS_OPENER_PORT_ID(closing_port_id) ? |
channel_iter->second->receiver : channel_iter->second->opener; |
@@ -455,8 +378,6 @@ void ExtensionMessageService::CloseChannelImpl( |
void ExtensionMessageService::PostMessageFromRenderer( |
int source_port_id, const std::string& message) { |
- DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
- |
MessageChannelMap::iterator iter = |
channels_.find(GET_CHANNEL_ID(source_port_id)); |
if (iter == channels_.end()) |
@@ -473,7 +394,6 @@ void ExtensionMessageService::PostMessageFromRenderer( |
void ExtensionMessageService::DispatchEventToRenderers( |
const std::string& event_name, const std::string& event_args, |
bool has_incognito_data, const GURL& event_url) { |
- DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
ListenerMap::iterator it = listeners_.find(event_name); |
if (it == listeners_.end()) |
return; |
@@ -507,8 +427,6 @@ void ExtensionMessageService::DispatchEventToExtension( |
void ExtensionMessageService::Observe(NotificationType type, |
const NotificationSource& source, |
const NotificationDetails& details) { |
- DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
- |
switch (type.value) { |
case NotificationType::RENDERER_PROCESS_TERMINATED: |
case NotificationType::RENDERER_PROCESS_CLOSED: { |
@@ -527,26 +445,6 @@ void ExtensionMessageService::Observe(NotificationType type, |
case NotificationType::RENDER_VIEW_HOST_DELETED: |
OnSenderClosed(Details<RenderViewHost>(details).ptr()); |
break; |
- |
- // We should already have removed this guy from our channel map by this |
- // point. |
- case NotificationType::EXTENSION_PORT_DELETED_DEBUG: { |
- IPC::Message::Sender* sender = |
- Details<IPC::Message::Sender>(details).ptr(); |
- for (MessageChannelMap::iterator it = channels_.begin(); |
- it != channels_.end(); ) { |
- MessageChannelMap::iterator current = it++; |
- int debug_info = current->second->receiver.debug_info; |
- if (current->second->opener.sender == sender) { |
- LOG(FATAL) << "Shouldn't happen:" << debug_info; |
- } else if (current->second->receiver.sender == sender) { |
- LOG(FATAL) << "Shouldn't happen either: " << debug_info; |
- } |
- } |
- OnSenderClosed(sender); |
- break; |
- } |
- |
default: |
NOTREACHED(); |
return; |
@@ -561,11 +459,8 @@ void ExtensionMessageService::OnSenderClosed(IPC::Message::Sender* sender) { |
MessageChannelMap::iterator current = it++; |
// If both sides are the same renderer, and it is closing, there is no |
// "other" port, so there's no need to notify it. |
- int debug_info = current->second->receiver.debug_info; |
- bool debug_check = debug_info == 4 || debug_info == 5; |
bool notify_other_port = |
- current->second->opener.sender != current->second->receiver.sender || |
- debug_check; |
+ current->second->opener.sender != current->second->receiver.sender; |
if (current->second->opener.sender == sender) { |
CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), |