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

Side by Side Diff: ipc/ipc_channel_posix.cc

Issue 7870008: Wait properly for renderer crashes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixes Created 9 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "ipc/ipc_channel_posix.h" 5 #include "ipc/ipc_channel_posix.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <stddef.h> 9 #include <stddef.h>
10 #include <sys/types.h> 10 #include <sys/types.h>
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 base::AutoLock locked(lock_); 95 base::AutoLock locked(lock_);
96 96
97 ChannelToFDMap::const_iterator i = map_.find(channel_id); 97 ChannelToFDMap::const_iterator i = map_.find(channel_id);
98 if (i == map_.end()) 98 if (i == map_.end())
99 return -1; 99 return -1;
100 return i->second; 100 return i->second;
101 } 101 }
102 102
103 // Remove the mapping for the given channel id. No error is signaled if the 103 // Remove the mapping for the given channel id. No error is signaled if the
104 // channel_id doesn't exist 104 // channel_id doesn't exist
105 void RemoveAndClose(const std::string& channel_id) { 105 void Remove(const std::string& channel_id) {
106 base::AutoLock locked(lock_); 106 base::AutoLock locked(lock_);
107 107 map_.erase(channel_id);
108 ChannelToFDMap::iterator i = map_.find(channel_id);
109 if (i != map_.end()) {
110 if (HANDLE_EINTR(close(i->second)) < 0)
111 PLOG(ERROR) << "close " << channel_id;
112 map_.erase(i);
113 }
114 } 108 }
115 109
116 // Insert a mapping from @channel_id to @fd. It's a fatal error to insert a 110 // Insert a mapping from @channel_id to @fd. It's a fatal error to insert a
117 // mapping if one already exists for the given channel_id 111 // mapping if one already exists for the given channel_id
118 void Insert(const std::string& channel_id, int fd) { 112 void Insert(const std::string& channel_id, int fd) {
119 base::AutoLock locked(lock_); 113 base::AutoLock locked(lock_);
120 DCHECK_NE(-1, fd); 114 DCHECK_NE(-1, fd);
121 115
122 ChannelToFDMap::const_iterator i = map_.find(channel_id); 116 ChannelToFDMap::const_iterator i = map_.find(channel_id);
123 CHECK(i == map_.end()) << "Creating second IPC server (fd " << fd << ") " 117 CHECK(i == map_.end()) << "Creating second IPC server (fd " << fd << ") "
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 LOG(ERROR) << "Bad mode: " << mode_; 390 LOG(ERROR) << "Bad mode: " << mode_;
397 return false; 391 return false;
398 } 392 }
399 } else { 393 } else {
400 local_pipe = PipeMap::GetInstance()->Lookup(pipe_name_); 394 local_pipe = PipeMap::GetInstance()->Lookup(pipe_name_);
401 if (mode_ & MODE_CLIENT_FLAG) { 395 if (mode_ & MODE_CLIENT_FLAG) {
402 if (local_pipe != -1) { 396 if (local_pipe != -1) {
403 // Case 3 from comment above. 397 // Case 3 from comment above.
404 // We only allow one connection. 398 // We only allow one connection.
405 local_pipe = HANDLE_EINTR(dup(local_pipe)); 399 local_pipe = HANDLE_EINTR(dup(local_pipe));
406 PipeMap::GetInstance()->RemoveAndClose(pipe_name_); 400 PipeMap::GetInstance()->Remove(pipe_name_);
407 } else { 401 } else {
408 // Case 4a from comment above. 402 // Case 4a from comment above.
409 // Guard against inappropriate reuse of the initial IPC channel. If 403 // Guard against inappropriate reuse of the initial IPC channel. If
410 // an IPC channel closes and someone attempts to reuse it by name, the 404 // an IPC channel closes and someone attempts to reuse it by name, the
411 // initial channel must not be recycled here. http://crbug.com/26754. 405 // initial channel must not be recycled here. http://crbug.com/26754.
412 static bool used_initial_channel = false; 406 static bool used_initial_channel = false;
413 if (used_initial_channel) { 407 if (used_initial_channel) {
414 LOG(FATAL) << "Denying attempt to reuse initial IPC channel for " 408 LOG(FATAL) << "Denying attempt to reuse initial IPC channel for "
415 << pipe_name_; 409 << pipe_name_;
416 return false; 410 return false;
417 } 411 }
418 used_initial_channel = true; 412 used_initial_channel = true;
419 413
420 local_pipe = 414 local_pipe =
421 base::GlobalDescriptors::GetInstance()->Get(kPrimaryIPCChannel); 415 base::GlobalDescriptors::GetInstance()->Get(kPrimaryIPCChannel);
422 } 416 }
423 } else if (mode_ & MODE_SERVER_FLAG) { 417 } else if (mode_ & MODE_SERVER_FLAG) {
424 // Case 4b from comment above. 418 // Case 4b from comment above.
425 if (local_pipe != -1) { 419 if (local_pipe != -1) {
426 LOG(ERROR) << "Server already exists for " << pipe_name_; 420 LOG(ERROR) << "Server already exists for " << pipe_name_;
427 return false; 421 return false;
428 } 422 }
423 base::AutoLock lock(client_pipe_lock_);
429 if (!SocketPair(&local_pipe, &client_pipe_)) 424 if (!SocketPair(&local_pipe, &client_pipe_))
430 return false; 425 return false;
431 PipeMap::GetInstance()->Insert(pipe_name_, client_pipe_); 426 PipeMap::GetInstance()->Insert(pipe_name_, client_pipe_);
432 } else { 427 } else {
433 LOG(ERROR) << "Bad mode: " << mode_; 428 LOG(ERROR) << "Bad mode: " << mode_;
434 return false; 429 return false;
435 } 430 }
436 } 431 }
437 432
438 #if defined(IPC_USES_READWRITE) 433 #if defined(IPC_USES_READWRITE)
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 PLOG(ERROR) << "pipe error (" << pipe_ << ")"; 517 PLOG(ERROR) << "pipe error (" << pipe_ << ")";
523 return false; 518 return false;
524 } 519 }
525 } else if (bytes_read == 0) { 520 } else if (bytes_read == 0) {
526 // The pipe has closed... 521 // The pipe has closed...
527 return false; 522 return false;
528 } 523 }
529 } 524 }
530 DCHECK(bytes_read); 525 DCHECK(bytes_read);
531 526
532 if (client_pipe_ != -1) { 527 CloseClientFileDescriptor();
533 PipeMap::GetInstance()->RemoveAndClose(pipe_name_);
534 client_pipe_ = -1;
535 }
536 528
537 // a pointer to an array of |num_wire_fds| file descriptors from the read 529 // a pointer to an array of |num_wire_fds| file descriptors from the read
538 const int* wire_fds = NULL; 530 const int* wire_fds = NULL;
539 unsigned num_wire_fds = 0; 531 unsigned num_wire_fds = 0;
540 532
541 // walk the list of control messages and, if we find an array of file 533 // walk the list of control messages and, if we find an array of file
542 // descriptors, save a pointer to the array 534 // descriptors, save a pointer to the array
543 535
544 // This next if statement is to work around an OSX issue where 536 // This next if statement is to work around an OSX issue where
545 // CMSG_FIRSTHDR will return non-NULL in the case that controllen == 0. 537 // CMSG_FIRSTHDR will return non-NULL in the case that controllen == 0.
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 #endif // IPC_MESSAGE_LOG_ENABLED 901 #endif // IPC_MESSAGE_LOG_ENABLED
910 902
911 output_queue_.push(message); 903 output_queue_.push(message);
912 if (!is_blocked_on_write_ && !waiting_connect_) { 904 if (!is_blocked_on_write_ && !waiting_connect_) {
913 return ProcessOutgoingMessages(); 905 return ProcessOutgoingMessages();
914 } 906 }
915 907
916 return true; 908 return true;
917 } 909 }
918 910
919 int Channel::ChannelImpl::GetClientFileDescriptor() const { 911 int Channel::ChannelImpl::GetClientFileDescriptor() {
912 base::AutoLock lock(client_pipe_lock_);
920 return client_pipe_; 913 return client_pipe_;
921 } 914 }
922 915
916 int Channel::ChannelImpl::TakeClientFileDescriptor() {
917 base::AutoLock lock(client_pipe_lock_);
918 int fd = client_pipe_;
919 if (client_pipe_ != -1) {
920 PipeMap::GetInstance()->Remove(pipe_name_);
921 client_pipe_ = -1;
922 }
923 return fd;
924 }
925
926 void Channel::ChannelImpl::CloseClientFileDescriptor() {
927 base::AutoLock lock(client_pipe_lock_);
928 if (client_pipe_ != -1) {
929 PipeMap::GetInstance()->Remove(pipe_name_);
930 if (HANDLE_EINTR(close(client_pipe_)) < 0)
931 PLOG(ERROR) << "close " << pipe_name_;
932 client_pipe_ = -1;
933 }
934 }
935
923 bool Channel::ChannelImpl::AcceptsConnections() const { 936 bool Channel::ChannelImpl::AcceptsConnections() const {
924 return server_listen_pipe_ != -1; 937 return server_listen_pipe_ != -1;
925 } 938 }
926 939
927 bool Channel::ChannelImpl::HasAcceptedConnection() const { 940 bool Channel::ChannelImpl::HasAcceptedConnection() const {
928 return AcceptsConnections() && pipe_ != -1; 941 return AcceptsConnections() && pipe_ != -1;
929 } 942 }
930 943
931 bool Channel::ChannelImpl::GetClientEuid(uid_t* client_euid) const { 944 bool Channel::ChannelImpl::GetClientEuid(uid_t* client_euid) const {
932 DCHECK(HasAcceptedConnection()); 945 DCHECK(HasAcceptedConnection());
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 must_unlink_ = false; 1179 must_unlink_ = false;
1167 } 1180 }
1168 if (server_listen_pipe_ != -1) { 1181 if (server_listen_pipe_ != -1) {
1169 if (HANDLE_EINTR(close(server_listen_pipe_)) < 0) 1182 if (HANDLE_EINTR(close(server_listen_pipe_)) < 0)
1170 PLOG(ERROR) << "close " << server_listen_pipe_; 1183 PLOG(ERROR) << "close " << server_listen_pipe_;
1171 server_listen_pipe_ = -1; 1184 server_listen_pipe_ = -1;
1172 // Unregister libevent for the listening socket and close it. 1185 // Unregister libevent for the listening socket and close it.
1173 server_listen_connection_watcher_.StopWatchingFileDescriptor(); 1186 server_listen_connection_watcher_.StopWatchingFileDescriptor();
1174 } 1187 }
1175 1188
1176 if (client_pipe_ != -1) { 1189 CloseClientFileDescriptor();
1177 PipeMap::GetInstance()->RemoveAndClose(pipe_name_);
1178 client_pipe_ = -1;
1179 }
1180 } 1190 }
1181 1191
1182 //------------------------------------------------------------------------------ 1192 //------------------------------------------------------------------------------
1183 // Channel's methods simply call through to ChannelImpl. 1193 // Channel's methods simply call through to ChannelImpl.
1184 Channel::Channel(const IPC::ChannelHandle& channel_handle, Mode mode, 1194 Channel::Channel(const IPC::ChannelHandle& channel_handle, Mode mode,
1185 Listener* listener) 1195 Listener* listener)
1186 : channel_impl_(new ChannelImpl(channel_handle, mode, listener)) { 1196 : channel_impl_(new ChannelImpl(channel_handle, mode, listener)) {
1187 } 1197 }
1188 1198
1189 Channel::~Channel() { 1199 Channel::~Channel() {
(...skipping 13 matching lines...) Expand all
1203 } 1213 }
1204 1214
1205 bool Channel::Send(Message* message) { 1215 bool Channel::Send(Message* message) {
1206 return channel_impl_->Send(message); 1216 return channel_impl_->Send(message);
1207 } 1217 }
1208 1218
1209 int Channel::GetClientFileDescriptor() const { 1219 int Channel::GetClientFileDescriptor() const {
1210 return channel_impl_->GetClientFileDescriptor(); 1220 return channel_impl_->GetClientFileDescriptor();
1211 } 1221 }
1212 1222
1223 int Channel::TakeClientFileDescriptor() {
1224 return channel_impl_->TakeClientFileDescriptor();
1225 }
1226
1213 bool Channel::AcceptsConnections() const { 1227 bool Channel::AcceptsConnections() const {
1214 return channel_impl_->AcceptsConnections(); 1228 return channel_impl_->AcceptsConnections();
1215 } 1229 }
1216 1230
1217 bool Channel::HasAcceptedConnection() const { 1231 bool Channel::HasAcceptedConnection() const {
1218 return channel_impl_->HasAcceptedConnection(); 1232 return channel_impl_->HasAcceptedConnection();
1219 } 1233 }
1220 1234
1221 bool Channel::GetClientEuid(uid_t* client_euid) const { 1235 bool Channel::GetClientEuid(uid_t* client_euid) const {
1222 return channel_impl_->GetClientEuid(client_euid); 1236 return channel_impl_->GetClientEuid(client_euid);
1223 } 1237 }
1224 1238
1225 void Channel::ResetToAcceptingConnectionState() { 1239 void Channel::ResetToAcceptingConnectionState() {
1226 channel_impl_->ResetToAcceptingConnectionState(); 1240 channel_impl_->ResetToAcceptingConnectionState();
1227 } 1241 }
1228 1242
1229 // static 1243 // static
1230 bool Channel::IsNamedServerInitialized(const std::string& channel_id) { 1244 bool Channel::IsNamedServerInitialized(const std::string& channel_id) {
1231 return ChannelImpl::IsNamedServerInitialized(channel_id); 1245 return ChannelImpl::IsNamedServerInitialized(channel_id);
1232 } 1246 }
1233 1247
1234 #if defined(OS_LINUX) 1248 #if defined(OS_LINUX)
1235 // static 1249 // static
1236 void Channel::SetGlobalPid(int pid) { 1250 void Channel::SetGlobalPid(int pid) {
1237 ChannelImpl::SetGlobalPid(pid); 1251 ChannelImpl::SetGlobalPid(pid);
1238 } 1252 }
1239 #endif // OS_LINUX 1253 #endif // OS_LINUX
1240 1254
1241 } // namespace IPC 1255 } // namespace IPC
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698