OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extension_message_service.h" | 5 #include "chrome/browser/extensions/extension_message_service.h" |
6 | 6 |
7 #include "base/atomic_sequence_num.h" | 7 #include "base/atomic_sequence_num.h" |
8 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
(...skipping 21 matching lines...) Expand all Loading... | |
32 #define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2) | 32 #define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2) |
33 #define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1) | 33 #define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1) |
34 | 34 |
35 // Port1 is always even, port2 is always odd. | 35 // Port1 is always even, port2 is always odd. |
36 #define IS_OPENER_PORT_ID(port_id) (((port_id) & 1) == 0) | 36 #define IS_OPENER_PORT_ID(port_id) (((port_id) & 1) == 0) |
37 | 37 |
38 // Change even to odd and vice versa, to get the other side of a given channel. | 38 // Change even to odd and vice versa, to get the other side of a given channel. |
39 #define GET_OPPOSITE_PORT_ID(source_port_id) ((source_port_id) ^ 1) | 39 #define GET_OPPOSITE_PORT_ID(source_port_id) ((source_port_id) ^ 1) |
40 | 40 |
41 struct ExtensionMessageService::MessagePort { | 41 struct ExtensionMessageService::MessagePort { |
42 IPC::Message::Sender* sender; | 42 content::RenderProcessHost* process; |
43 int routing_id; | 43 int routing_id; |
44 explicit MessagePort(IPC::Message::Sender* sender = NULL, | 44 explicit MessagePort(content::RenderProcessHost* process = NULL, |
45 int routing_id = MSG_ROUTING_CONTROL) | 45 int routing_id = MSG_ROUTING_CONTROL) |
46 : sender(sender), routing_id(routing_id) {} | 46 : process(process), routing_id(routing_id) {} |
47 }; | 47 }; |
48 | 48 |
49 struct ExtensionMessageService::MessageChannel { | 49 struct ExtensionMessageService::MessageChannel { |
50 ExtensionMessageService::MessagePort opener; | 50 ExtensionMessageService::MessagePort opener; |
51 ExtensionMessageService::MessagePort receiver; | 51 ExtensionMessageService::MessagePort receiver; |
52 }; | 52 }; |
53 | 53 |
54 const char ExtensionMessageService::kDispatchOnConnect[] = | 54 const char ExtensionMessageService::kDispatchOnConnect[] = |
55 "Port.dispatchOnConnect"; | 55 "Port.dispatchOnConnect"; |
56 const char ExtensionMessageService::kDispatchOnDisconnect[] = | 56 const char ExtensionMessageService::kDispatchOnDisconnect[] = |
57 "Port.dispatchOnDisconnect"; | 57 "Port.dispatchOnDisconnect"; |
58 | 58 |
59 namespace { | 59 namespace { |
60 | 60 |
61 static base::AtomicSequenceNumber g_next_channel_id(base::LINKER_INITIALIZED); | 61 static base::AtomicSequenceNumber g_next_channel_id(base::LINKER_INITIALIZED); |
62 | 62 |
63 static void DispatchOnConnect(const ExtensionMessageService::MessagePort& port, | 63 static void DispatchOnConnect(const ExtensionMessageService::MessagePort& port, |
64 int dest_port_id, | 64 int dest_port_id, |
65 const std::string& channel_name, | 65 const std::string& channel_name, |
66 const std::string& tab_json, | 66 const std::string& tab_json, |
67 const std::string& source_extension_id, | 67 const std::string& source_extension_id, |
68 const std::string& target_extension_id) { | 68 const std::string& target_extension_id) { |
69 ListValue args; | 69 ListValue args; |
70 args.Set(0, Value::CreateIntegerValue(dest_port_id)); | 70 args.Set(0, Value::CreateIntegerValue(dest_port_id)); |
71 args.Set(1, Value::CreateStringValue(channel_name)); | 71 args.Set(1, Value::CreateStringValue(channel_name)); |
72 args.Set(2, Value::CreateStringValue(tab_json)); | 72 args.Set(2, Value::CreateStringValue(tab_json)); |
73 args.Set(3, Value::CreateStringValue(source_extension_id)); | 73 args.Set(3, Value::CreateStringValue(source_extension_id)); |
74 args.Set(4, Value::CreateStringValue(target_extension_id)); | 74 args.Set(4, Value::CreateStringValue(target_extension_id)); |
75 CHECK(port.sender); | 75 CHECK(port.process); |
76 port.sender->Send( | 76 port.process->Send( |
77 new ExtensionMsg_MessageInvoke( | 77 new ExtensionMsg_MessageInvoke( |
78 port.routing_id, | 78 port.routing_id, |
79 target_extension_id, | 79 target_extension_id, |
80 ExtensionMessageService::kDispatchOnConnect, args, GURL(), | 80 ExtensionMessageService::kDispatchOnConnect, args, GURL(), |
81 false)); // Not a user gesture | 81 false)); // Not a user gesture |
82 } | 82 } |
83 | 83 |
84 static void DispatchOnDisconnect( | 84 static void DispatchOnDisconnect( |
85 const ExtensionMessageService::MessagePort& port, int source_port_id, | 85 const ExtensionMessageService::MessagePort& port, int source_port_id, |
86 bool connection_error) { | 86 bool connection_error) { |
87 ListValue args; | 87 ListValue args; |
88 args.Set(0, Value::CreateIntegerValue(source_port_id)); | 88 args.Set(0, Value::CreateIntegerValue(source_port_id)); |
89 args.Set(1, Value::CreateBooleanValue(connection_error)); | 89 args.Set(1, Value::CreateBooleanValue(connection_error)); |
90 port.sender->Send(new ExtensionMsg_MessageInvoke(port.routing_id, | 90 port.process->Send(new ExtensionMsg_MessageInvoke(port.routing_id, |
91 "", ExtensionMessageService::kDispatchOnDisconnect, args, GURL(), | 91 "", ExtensionMessageService::kDispatchOnDisconnect, args, GURL(), |
92 false)); // Not a user gesture | 92 false)); // Not a user gesture |
93 } | 93 } |
94 | 94 |
95 static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port, | 95 static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port, |
96 const std::string& message, int target_port_id) { | 96 const std::string& message, int target_port_id) { |
97 port.sender->Send( | 97 port.process->Send( |
98 new ExtensionMsg_DeliverMessage( | 98 new ExtensionMsg_DeliverMessage( |
99 port.routing_id, target_port_id, message)); | 99 port.routing_id, target_port_id, message)); |
100 } | 100 } |
101 | 101 |
102 static content::RenderProcessHost* GetExtensionProcess(Profile* profile, | 102 static content::RenderProcessHost* GetExtensionProcess(Profile* profile, |
103 const std::string& extension_id) { | 103 const std::string& extension_id) { |
104 SiteInstance* site_instance = | 104 SiteInstance* site_instance = |
105 profile->GetExtensionProcessManager()->GetSiteInstanceForURL( | 105 profile->GetExtensionProcessManager()->GetSiteInstanceForURL( |
106 Extension::GetBaseURLFromExtensionId(extension_id)); | 106 Extension::GetBaseURLFromExtensionId(extension_id)); |
107 | 107 |
(...skipping 17 matching lines...) Expand all Loading... | |
125 DCHECK(GET_OPPOSITE_PORT_ID(port2_id) == port1_id); | 125 DCHECK(GET_OPPOSITE_PORT_ID(port2_id) == port1_id); |
126 DCHECK(GET_CHANNEL_ID(port1_id) == GET_CHANNEL_ID(port2_id)); | 126 DCHECK(GET_CHANNEL_ID(port1_id) == GET_CHANNEL_ID(port2_id)); |
127 DCHECK(GET_CHANNEL_ID(port1_id) == channel_id); | 127 DCHECK(GET_CHANNEL_ID(port1_id) == channel_id); |
128 DCHECK(GET_CHANNEL_OPENER_ID(channel_id) == port1_id); | 128 DCHECK(GET_CHANNEL_OPENER_ID(channel_id) == port1_id); |
129 DCHECK(GET_CHANNEL_RECEIVERS_ID(channel_id) == port2_id); | 129 DCHECK(GET_CHANNEL_RECEIVERS_ID(channel_id) == port2_id); |
130 | 130 |
131 *port1 = port1_id; | 131 *port1 = port1_id; |
132 *port2 = port2_id; | 132 *port2 = port2_id; |
133 } | 133 } |
134 | 134 |
135 ExtensionMessageService::ExtensionMessageService(Profile* profile) | 135 ExtensionMessageService::ExtensionMessageService(Profile* profile) { |
Yoyo Zhou
2012/03/10 01:36:54
Apparently you no longer need this argument.
| |
136 : profile_(profile) { | |
137 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 136 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
138 content::NotificationService::AllBrowserContextsAndSources()); | 137 content::NotificationService::AllBrowserContextsAndSources()); |
139 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | 138 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
140 content::NotificationService::AllBrowserContextsAndSources()); | 139 content::NotificationService::AllBrowserContextsAndSources()); |
141 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_DELETED, | |
142 content::NotificationService::AllBrowserContextsAndSources()); | |
143 } | 140 } |
144 | 141 |
145 ExtensionMessageService::~ExtensionMessageService() { | 142 ExtensionMessageService::~ExtensionMessageService() { |
146 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); | 143 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); |
147 channels_.clear(); | 144 channels_.clear(); |
148 } | 145 } |
149 | 146 |
150 void ExtensionMessageService::DestroyingProfile() { | |
151 profile_ = NULL; | |
152 if (!registrar_.IsEmpty()) | |
153 registrar_.RemoveAll(); | |
154 } | |
155 | |
156 void ExtensionMessageService::OpenChannelToExtension( | 147 void ExtensionMessageService::OpenChannelToExtension( |
157 int source_process_id, int source_routing_id, int receiver_port_id, | 148 int source_process_id, int source_routing_id, int receiver_port_id, |
158 const std::string& source_extension_id, | 149 const std::string& source_extension_id, |
159 const std::string& target_extension_id, | 150 const std::string& target_extension_id, |
160 const std::string& channel_name) { | 151 const std::string& channel_name) { |
161 content::RenderProcessHost* source = | 152 content::RenderProcessHost* source = |
162 content::RenderProcessHost::FromID(source_process_id); | 153 content::RenderProcessHost::FromID(source_process_id); |
163 if (!source) | 154 if (!source) |
164 return; | 155 return; |
165 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); | 156 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); |
(...skipping 26 matching lines...) Expand all Loading... | |
192 content::RenderProcessHost* source = | 183 content::RenderProcessHost* source = |
193 content::RenderProcessHost::FromID(source_process_id); | 184 content::RenderProcessHost::FromID(source_process_id); |
194 if (!source) | 185 if (!source) |
195 return; | 186 return; |
196 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); | 187 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); |
197 | 188 |
198 TabContentsWrapper* contents = NULL; | 189 TabContentsWrapper* contents = NULL; |
199 MessagePort receiver; | 190 MessagePort receiver; |
200 if (ExtensionTabUtil::GetTabById(tab_id, profile, true, | 191 if (ExtensionTabUtil::GetTabById(tab_id, profile, true, |
201 NULL, NULL, &contents, NULL)) { | 192 NULL, NULL, &contents, NULL)) { |
202 receiver.sender = contents->web_contents()->GetRenderViewHost(); | 193 receiver.process = contents->web_contents()->GetRenderProcessHost(); |
203 receiver.routing_id = | 194 receiver.routing_id = |
204 contents->web_contents()->GetRenderViewHost()->GetRoutingID(); | 195 contents->web_contents()->GetRenderViewHost()->GetRoutingID(); |
205 } | 196 } |
206 | 197 |
207 if (contents && contents->web_contents()->GetController().NeedsReload()) { | 198 if (contents && contents->web_contents()->GetController().NeedsReload()) { |
208 // The tab isn't loaded yet. Don't attempt to connect. Treat this as a | 199 // The tab isn't loaded yet. Don't attempt to connect. Treat this as a |
209 // disconnect. | 200 // disconnect. |
210 DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL), | 201 DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL), |
211 GET_OPPOSITE_PORT_ID(receiver_port_id), true); | 202 GET_OPPOSITE_PORT_ID(receiver_port_id), true); |
212 return; | 203 return; |
213 } | 204 } |
214 | 205 |
215 WebContents* source_contents = tab_util::GetWebContentsByID( | 206 WebContents* source_contents = tab_util::GetWebContentsByID( |
216 source_process_id, source_routing_id); | 207 source_process_id, source_routing_id); |
217 | 208 |
218 // Include info about the opener's tab (if it was a tab). | 209 // Include info about the opener's tab (if it was a tab). |
219 std::string tab_json = "null"; | 210 std::string tab_json = "null"; |
220 if (source_contents) { | 211 if (source_contents) { |
221 scoped_ptr<DictionaryValue> tab_value( | 212 scoped_ptr<DictionaryValue> tab_value( |
222 ExtensionTabUtil::CreateTabValue(source_contents)); | 213 ExtensionTabUtil::CreateTabValue(source_contents)); |
223 base::JSONWriter::Write(tab_value.get(), false, &tab_json); | 214 base::JSONWriter::Write(tab_value.get(), false, &tab_json); |
224 } | 215 } |
225 | 216 |
226 OpenChannelImpl(source, tab_json, receiver, receiver_port_id, | 217 OpenChannelImpl(source, tab_json, receiver, receiver_port_id, |
227 extension_id, extension_id, channel_name); | 218 extension_id, extension_id, channel_name); |
228 } | 219 } |
229 | 220 |
230 bool ExtensionMessageService::OpenChannelImpl( | 221 bool ExtensionMessageService::OpenChannelImpl( |
231 IPC::Message::Sender* source, | 222 content::RenderProcessHost* source, |
232 const std::string& tab_json, | 223 const std::string& tab_json, |
233 const MessagePort& receiver, int receiver_port_id, | 224 const MessagePort& receiver, int receiver_port_id, |
234 const std::string& source_extension_id, | 225 const std::string& source_extension_id, |
235 const std::string& target_extension_id, | 226 const std::string& target_extension_id, |
236 const std::string& channel_name) { | 227 const std::string& channel_name) { |
237 if (!source) | 228 if (!source) |
238 return false; // Closed while in flight. | 229 return false; // Closed while in flight. |
239 | 230 |
240 if (!receiver.sender) { | 231 if (!receiver.process) { |
241 // Treat it as a disconnect. | 232 // Treat it as a disconnect. |
242 DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL), | 233 DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL), |
243 GET_OPPOSITE_PORT_ID(receiver_port_id), true); | 234 GET_OPPOSITE_PORT_ID(receiver_port_id), true); |
244 return false; | 235 return false; |
245 } | 236 } |
246 | 237 |
247 // Add extra paranoid CHECKs, since we have crash reports of this being NULL. | 238 // Add extra paranoid CHECKs, since we have crash reports of this being NULL. |
248 // http://code.google.com/p/chromium/issues/detail?id=19067 | 239 // http://code.google.com/p/chromium/issues/detail?id=19067 |
249 CHECK(receiver.sender); | 240 CHECK(receiver.process); |
250 | 241 |
251 MessageChannel* channel(new MessageChannel); | 242 MessageChannel* channel(new MessageChannel); |
252 channel->opener = MessagePort(source, MSG_ROUTING_CONTROL); | 243 channel->opener = MessagePort(source, MSG_ROUTING_CONTROL); |
253 channel->receiver = receiver; | 244 channel->receiver = receiver; |
254 | 245 |
255 CHECK(receiver.sender); | 246 CHECK(receiver.process); |
256 | 247 |
257 CHECK(channels_.find(GET_CHANNEL_ID(receiver_port_id)) == channels_.end()); | 248 CHECK(channels_.find(GET_CHANNEL_ID(receiver_port_id)) == channels_.end()); |
258 channels_[GET_CHANNEL_ID(receiver_port_id)] = channel; | 249 channels_[GET_CHANNEL_ID(receiver_port_id)] = channel; |
259 | 250 |
260 CHECK(receiver.sender); | 251 CHECK(receiver.process); |
261 | 252 |
262 // Send the connect event to the receiver. Give it the opener's port ID (the | 253 // Send the connect event to the receiver. Give it the opener's port ID (the |
263 // opener has the opposite port ID). | 254 // opener has the opposite port ID). |
264 DispatchOnConnect(receiver, receiver_port_id, channel_name, tab_json, | 255 DispatchOnConnect(receiver, receiver_port_id, channel_name, tab_json, |
265 source_extension_id, target_extension_id); | 256 source_extension_id, target_extension_id); |
266 | 257 |
267 return true; | 258 return true; |
268 } | 259 } |
269 | 260 |
270 int ExtensionMessageService::OpenSpecialChannelToExtension( | |
271 const std::string& extension_id, const std::string& channel_name, | |
272 const std::string& tab_json, IPC::Message::Sender* source) { | |
273 DCHECK(profile_); | |
274 | |
275 int port1_id = -1; | |
276 int port2_id = -1; | |
277 // Create a channel ID for both sides of the channel. | |
278 AllocatePortIdPair(&port1_id, &port2_id); | |
279 | |
280 MessagePort receiver( | |
281 GetExtensionProcess(profile_, extension_id), | |
282 MSG_ROUTING_CONTROL); | |
283 if (!OpenChannelImpl(source, tab_json, receiver, port2_id, | |
284 extension_id, extension_id, channel_name)) | |
285 return -1; | |
286 | |
287 return port1_id; | |
288 } | |
289 | |
290 int ExtensionMessageService::OpenSpecialChannelToTab( | |
291 const std::string& extension_id, const std::string& channel_name, | |
292 WebContents* target_web_contents, IPC::Message::Sender* source) { | |
293 DCHECK(target_web_contents); | |
294 | |
295 if (target_web_contents->GetController().NeedsReload()) { | |
296 // The tab isn't loaded yet. Don't attempt to connect. | |
297 return -1; | |
298 } | |
299 | |
300 int port1_id = -1; | |
301 int port2_id = -1; | |
302 // Create a channel ID for both sides of the channel. | |
303 AllocatePortIdPair(&port1_id, &port2_id); | |
304 | |
305 MessagePort receiver( | |
306 target_web_contents->GetRenderViewHost(), | |
307 target_web_contents->GetRenderViewHost()->GetRoutingID()); | |
308 if (!OpenChannelImpl(source, "null", receiver, port2_id, | |
309 extension_id, extension_id, channel_name)) | |
310 return -1; | |
311 | |
312 return port1_id; | |
313 } | |
314 | |
315 void ExtensionMessageService::CloseChannel(int port_id) { | 261 void ExtensionMessageService::CloseChannel(int port_id) { |
316 // Note: The channel might be gone already, if the other side closed first. | 262 // Note: The channel might be gone already, if the other side closed first. |
317 MessageChannelMap::iterator it = channels_.find(GET_CHANNEL_ID(port_id)); | 263 MessageChannelMap::iterator it = channels_.find(GET_CHANNEL_ID(port_id)); |
318 if (it != channels_.end()) | 264 if (it != channels_.end()) |
319 CloseChannelImpl(it, port_id, true); | 265 CloseChannelImpl(it, port_id, true); |
320 } | 266 } |
321 | 267 |
322 void ExtensionMessageService::CloseChannelImpl( | 268 void ExtensionMessageService::CloseChannelImpl( |
323 MessageChannelMap::iterator channel_iter, int closing_port_id, | 269 MessageChannelMap::iterator channel_iter, int closing_port_id, |
324 bool notify_other_port) { | 270 bool notify_other_port) { |
(...skipping 14 matching lines...) Expand all Loading... | |
339 if (iter == channels_.end()) | 285 if (iter == channels_.end()) |
340 return; | 286 return; |
341 | 287 |
342 // Figure out which port the ID corresponds to. | 288 // Figure out which port the ID corresponds to. |
343 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); | 289 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); |
344 const MessagePort& port = IS_OPENER_PORT_ID(dest_port_id) ? | 290 const MessagePort& port = IS_OPENER_PORT_ID(dest_port_id) ? |
345 iter->second->opener : iter->second->receiver; | 291 iter->second->opener : iter->second->receiver; |
346 | 292 |
347 DispatchOnMessage(port, message, dest_port_id); | 293 DispatchOnMessage(port, message, dest_port_id); |
348 } | 294 } |
295 | |
349 void ExtensionMessageService::Observe( | 296 void ExtensionMessageService::Observe( |
350 int type, | 297 int type, |
351 const content::NotificationSource& source, | 298 const content::NotificationSource& source, |
352 const content::NotificationDetails& details) { | 299 const content::NotificationDetails& details) { |
353 switch (type) { | 300 switch (type) { |
354 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: | 301 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: |
355 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { | 302 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { |
356 content::RenderProcessHost* renderer = | 303 content::RenderProcessHost* renderer = |
357 content::Source<content::RenderProcessHost>(source).ptr(); | 304 content::Source<content::RenderProcessHost>(source).ptr(); |
358 OnSenderClosed(renderer); | 305 OnProcessClosed(renderer); |
359 break; | 306 break; |
360 } | 307 } |
361 case content::NOTIFICATION_RENDER_VIEW_HOST_DELETED: | |
362 OnSenderClosed(content::Source<content::RenderViewHost>(source).ptr()); | |
363 break; | |
364 default: | 308 default: |
365 NOTREACHED(); | 309 NOTREACHED(); |
366 return; | 310 return; |
367 } | 311 } |
368 } | 312 } |
369 | 313 |
370 void ExtensionMessageService::OnSenderClosed(IPC::Message::Sender* sender) { | 314 void ExtensionMessageService::OnProcessClosed( |
315 content::RenderProcessHost* process) { | |
371 // Close any channels that share this renderer. We notify the opposite | 316 // Close any channels that share this renderer. We notify the opposite |
372 // port that his pair has closed. | 317 // port that his pair has closed. |
373 for (MessageChannelMap::iterator it = channels_.begin(); | 318 for (MessageChannelMap::iterator it = channels_.begin(); |
374 it != channels_.end(); ) { | 319 it != channels_.end(); ) { |
375 MessageChannelMap::iterator current = it++; | 320 MessageChannelMap::iterator current = it++; |
376 // If both sides are the same renderer, and it is closing, there is no | 321 // If both sides are the same renderer, and it is closing, there is no |
377 // "other" port, so there's no need to notify it. | 322 // "other" port, so there's no need to notify it. |
378 bool notify_other_port = | 323 bool notify_other_port = |
379 current->second->opener.sender != current->second->receiver.sender; | 324 current->second->opener.process != current->second->receiver.process; |
380 | 325 |
381 if (current->second->opener.sender == sender) { | 326 if (current->second->opener.process == process) { |
382 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), | 327 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), |
383 notify_other_port); | 328 notify_other_port); |
384 } else if (current->second->receiver.sender == sender) { | 329 } else if (current->second->receiver.process == process) { |
385 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), | 330 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), |
386 notify_other_port); | 331 notify_other_port); |
387 } | 332 } |
388 } | 333 } |
389 } | 334 } |
OLD | NEW |