Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Side by Side Diff: mojo/edk/system/broker_state.cc

Issue 1558643002: Fix Mojo broker crash on Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/edk/system/broker_messages.h ('k') | mojo/edk/system/child_broker.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "mojo/edk/system/broker_state.h" 5 #include "mojo/edk/system/broker_state.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 AttachMessagePipe(pending_connects_[pipe_id], pipe_id, 86 AttachMessagePipe(pending_connects_[pipe_id], pipe_id,
87 in_process_pipes_channel1_); 87 in_process_pipes_channel1_);
88 AttachMessagePipe(message_pipe, pipe_id, in_process_pipes_channel2_); 88 AttachMessagePipe(message_pipe, pipe_id, in_process_pipes_channel2_);
89 pending_connects_.erase(pipe_id); 89 pending_connects_.erase(pipe_id);
90 return; 90 return;
91 } 91 }
92 92
93 if (pending_child_connects_.find(pipe_id) != pending_child_connects_.end()) { 93 if (pending_child_connects_.find(pipe_id) != pending_child_connects_.end()) {
94 // A child process has already tried to connect. 94 // A child process has already tried to connect.
95 ChildBrokerHost* child_host = pending_child_connects_[pipe_id]; 95 ChildBrokerHost* child_host = pending_child_connects_[pipe_id];
96 AttachMessagePipe(message_pipe, pipe_id, child_host->channel()); 96 if (child_host && child_host->channel()) {
97 child_host->ConnectMessagePipe(pipe_id, 0); 97 AttachMessagePipe(message_pipe, pipe_id, child_host->channel());
98 child_host->ConnectMessagePipe(pipe_id, 0);
99 } else {
100 message_pipe->OnError(RawChannel::Delegate::ERROR_READ_SHUTDOWN);
101 }
102
98 pending_child_connects_.erase(pipe_id); 103 pending_child_connects_.erase(pipe_id);
99 return; 104 return;
100 } 105 }
101 106
102 pending_connects_[pipe_id] = message_pipe; 107 pending_connects_[pipe_id] = message_pipe;
103 } 108 }
104 109
105 void BrokerState::CloseMessagePipe(uint64_t pipe_id, 110 void BrokerState::CloseMessagePipe(uint64_t pipe_id,
106 MessagePipeDispatcher* message_pipe) { 111 MessagePipeDispatcher* message_pipe) {
107 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); 112 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread());
108 113
109 CHECK(connected_pipes_.find(message_pipe) != connected_pipes_.end()); 114 CHECK(connected_pipes_.find(message_pipe) != connected_pipes_.end());
110 connected_pipes_[message_pipe]->RemoveRoute(pipe_id); 115 connected_pipes_[message_pipe]->RemoveRoute(pipe_id);
111 connected_pipes_.erase(message_pipe); 116 connected_pipes_.erase(message_pipe);
112 } 117 }
113 118
114 void BrokerState::ChildBrokerHostCreated(ChildBrokerHost* child_broker_host) { 119 void BrokerState::ChildBrokerHostCreated(ChildBrokerHost* child_broker_host) {
115 base::AutoLock auto_lock(lock_); 120 base::AutoLock auto_lock(lock_);
116 CHECK(child_processes_.find(child_broker_host->GetProcessId()) == 121 CHECK(child_processes_.find(child_broker_host->GetProcessId()) ==
117 child_processes_.end()); 122 child_processes_.end());
118 child_processes_[child_broker_host->GetProcessId()] = child_broker_host; 123 child_processes_[child_broker_host->GetProcessId()] = child_broker_host;
119 } 124 }
120 125
121 void BrokerState::ChildBrokerHostDestructed( 126 void BrokerState::ChildBrokerHostDestructed(
122 ChildBrokerHost* child_broker_host) { 127 ChildBrokerHost* child_broker_host) {
123 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); 128 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread());
124 base::AutoLock auto_lock(lock_); 129 base::AutoLock auto_lock(lock_);
125 130
126 for (auto it = pending_child_connects_.begin(); 131 for (auto it = pending_child_connects_.begin();
127 it != pending_child_connects_.end();) { 132 it != pending_child_connects_.end(); ++it) {
128 if (it->second == child_broker_host) { 133 if (it->second == child_broker_host) {
129 // Since we can't do it = pending_child_connects_.erase(it); until 134 // Signify that the process has died. When another process tries to
130 // hash_map uses unordered_map on posix. 135 // connect to the message pipe, we will tell it that the peer has died so
131 auto cur = it++; 136 // that it can fire a peer closed notification.
132 pending_child_connects_.erase(cur); 137 it->second = nullptr;
133 } else {
134 it++;
135 } 138 }
136 } 139 }
137 140
138 base::ProcessId pid = child_broker_host->GetProcessId(); 141 base::ProcessId pid = child_broker_host->GetProcessId();
139 for (auto it = connected_processes_.begin(); 142 for (auto it = connected_processes_.begin();
140 it != connected_processes_.end();) { 143 it != connected_processes_.end();) {
141 if ((*it).first == pid || (*it).second == pid) { 144 if ((*it).first == pid || (*it).second == pid) {
142 // Since we can't do it = pending_child_connects_.erase(it); until 145 // Since we can't do it = connected_processes_.erase(it); until hash_map
143 // hash_map uses unordered_map on posix. 146 // uses unordered_map on posix.
144 auto cur = it++; 147 auto cur = it++;
145 connected_processes_.erase(cur); 148 connected_processes_.erase(cur);
146 } else { 149 } else {
147 it++; 150 it++;
148 } 151 }
149 } 152 }
150 153
151 CHECK(child_processes_.find(pid) != child_processes_.end()); 154 CHECK(child_processes_.find(pid) != child_processes_.end());
152 child_processes_.erase(pid); 155 child_processes_.erase(pid);
153 } 156 }
154 157
155 void BrokerState::HandleConnectMessagePipe(ChildBrokerHost* pipe_process, 158 void BrokerState::HandleConnectMessagePipe(ChildBrokerHost* pipe_process,
156 uint64_t pipe_id) { 159 uint64_t pipe_id) {
157 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); 160 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread());
158 base::AutoLock auto_lock(lock_); 161 base::AutoLock auto_lock(lock_);
159 if (pending_child_connects_.find(pipe_id) != pending_child_connects_.end()) { 162 if (pending_child_connects_.find(pipe_id) != pending_child_connects_.end()) {
160 // Another child process is waiting to connect to the given pipe. 163 // Another child process is waiting to connect to the given pipe.
161 ChildBrokerHost* pending_pipe_process = pending_child_connects_[pipe_id]; 164 ChildBrokerHost* pending_pipe_process = pending_child_connects_[pipe_id];
162 EnsureProcessesConnected(pipe_process->GetProcessId(), 165 if (pending_pipe_process && pending_pipe_process->channel()) {
163 pending_pipe_process->GetProcessId()); 166 EnsureProcessesConnected(pipe_process->GetProcessId(),
164 pending_pipe_process->ConnectMessagePipe( 167 pending_pipe_process->GetProcessId());
165 pipe_id, pipe_process->GetProcessId()); 168 pending_pipe_process->ConnectMessagePipe(
166 pipe_process->ConnectMessagePipe( 169 pipe_id, pipe_process->GetProcessId());
167 pipe_id, pending_pipe_process->GetProcessId()); 170 pipe_process->ConnectMessagePipe(
171 pipe_id, pending_pipe_process->GetProcessId());
172 } else {
173 pipe_process->PeerDied(pipe_id);
174 }
168 pending_child_connects_.erase(pipe_id); 175 pending_child_connects_.erase(pipe_id);
169 return; 176 return;
170 } 177 }
171 178
172 if (pending_connects_.find(pipe_id) != pending_connects_.end()) { 179 if (pending_connects_.find(pipe_id) != pending_connects_.end()) {
173 // This parent process is the other side of the given pipe. 180 // This parent process is the other side of the given pipe.
174 MessagePipeDispatcher* pending_pipe = pending_connects_[pipe_id]; 181 MessagePipeDispatcher* pending_pipe = pending_connects_[pipe_id];
175 AttachMessagePipe(pending_pipe, pipe_id, pipe_process->channel()); 182 AttachMessagePipe(pending_pipe, pipe_id, pipe_process->channel());
176 pipe_process->ConnectMessagePipe(pipe_id, 0); 183 pipe_process->ConnectMessagePipe(pipe_id, 0);
177 pending_connects_.erase(pipe_id); 184 pending_connects_.erase(pipe_id);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 // then when it's read it returns no messages because it doesn't have the 244 // then when it's read it returns no messages because it doesn't have the
238 // channel yet. 245 // channel yet.
239 message_pipe->GotNonTransferableChannel(raw_channel->channel()); 246 message_pipe->GotNonTransferableChannel(raw_channel->channel());
240 // The above call could have caused |CloseMessagePipe| to be called. 247 // The above call could have caused |CloseMessagePipe| to be called.
241 if (connected_pipes_.find(message_pipe) != connected_pipes_.end()) 248 if (connected_pipes_.find(message_pipe) != connected_pipes_.end())
242 raw_channel->AddRoute(pipe_id, message_pipe); 249 raw_channel->AddRoute(pipe_id, message_pipe);
243 } 250 }
244 251
245 } // namespace edk 252 } // namespace edk
246 } // namespace mojo 253 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/broker_messages.h ('k') | mojo/edk/system/child_broker.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698