Don't send the channel-disconnect message if the recipient is in the process

of closing.

This is an attempt to fix a crash bug.

TEST=no
BUG=21201

Review URL: http://codereview.chromium.org/197054

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25767 0039d316-1c4b-4281-b951-d872f2087c98
parent 9df9771b
...@@ -367,22 +367,23 @@ void ExtensionMessageService::CloseChannel(int port_id) { ...@@ -367,22 +367,23 @@ void ExtensionMessageService::CloseChannel(int port_id) {
// Note: The channel might be gone already, if the other side closed first. // Note: The channel might be gone already, if the other side closed first.
MessageChannelMap::iterator it = channels_.find(GET_CHANNEL_ID(port_id)); MessageChannelMap::iterator it = channels_.find(GET_CHANNEL_ID(port_id));
if (it != channels_.end()) if (it != channels_.end())
CloseChannelImpl(it, port_id); CloseChannelImpl(it, port_id, true);
} }
void ExtensionMessageService::CloseChannelImpl( void ExtensionMessageService::CloseChannelImpl(
MessageChannelMap::iterator channel_iter, int closing_port_id) { MessageChannelMap::iterator channel_iter, int closing_port_id,
bool notify_other_port) {
DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);
// Notify the other side. // Notify the other side.
const MessagePort& port = IS_OPENER_PORT_ID(closing_port_id) ? const MessagePort& port = IS_OPENER_PORT_ID(closing_port_id) ?
channel_iter->second->receiver : channel_iter->second->opener; channel_iter->second->receiver : channel_iter->second->opener;
DispatchOnDisconnect(port, GET_OPPOSITE_PORT_ID(closing_port_id)); if (notify_other_port)
DispatchOnDisconnect(port, GET_OPPOSITE_PORT_ID(closing_port_id));
channels_.erase(channel_iter); channels_.erase(channel_iter);
} }
void ExtensionMessageService::PostMessageFromRenderer( void ExtensionMessageService::PostMessageFromRenderer(
int source_port_id, const std::string& message) { int source_port_id, const std::string& message) {
DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);
...@@ -456,10 +457,16 @@ void ExtensionMessageService::OnSenderClosed(IPC::Message::Sender* sender) { ...@@ -456,10 +457,16 @@ void ExtensionMessageService::OnSenderClosed(IPC::Message::Sender* sender) {
for (MessageChannelMap::iterator it = channels_.begin(); for (MessageChannelMap::iterator it = channels_.begin();
it != channels_.end(); ) { it != channels_.end(); ) {
MessageChannelMap::iterator current = it++; 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.
bool notify_other_port =
current->second->opener.sender != current->second->receiver.sender;
if (current->second->opener.sender == sender) { if (current->second->opener.sender == sender) {
CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first)); CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first),
notify_other_port);
} else if (current->second->receiver.sender == sender) { } else if (current->second->receiver.sender == sender) {
CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first)); CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first),
notify_other_port);
} }
} }
} }
...@@ -134,7 +134,8 @@ class ExtensionMessageService ...@@ -134,7 +134,8 @@ class ExtensionMessageService
// NOTE: this can be called from any thread. // NOTE: this can be called from any thread.
void AllocatePortIdPair(int* port1, int* port2); void AllocatePortIdPair(int* port1, int* port2);
void CloseChannelImpl(MessageChannelMap::iterator channel_iter, int port_id); void CloseChannelImpl(MessageChannelMap::iterator channel_iter, int port_id,
bool notify_other_port);
// The UI message loop, used for posting tasks. // The UI message loop, used for posting tasks.
MessageLoop* ui_loop_; MessageLoop* ui_loop_;
......
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