| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 // connects. Once the client connects, the server will close the original | 68 // connects. Once the client connects, the server will close the original |
| 69 // copy of the client socket and remove the mapping. Thus, when the client | 69 // copy of the client socket and remove the mapping. Thus, when the client |
| 70 // object closes, it will close the only remaining copy of the client socket | 70 // object closes, it will close the only remaining copy of the client socket |
| 71 // in the fd table and the server will see EOF on its side. | 71 // in the fd table and the server will see EOF on its side. |
| 72 // | 72 // |
| 73 // TODO(port): a client process cannot connect to multiple IPC channels with | 73 // TODO(port): a client process cannot connect to multiple IPC channels with |
| 74 // this scheme. | 74 // this scheme. |
| 75 | 75 |
| 76 class PipeMap { | 76 class PipeMap { |
| 77 public: | 77 public: |
| 78 static PipeMap* GetInstance() { |
| 79 return Singleton<PipeMap>::get(); |
| 80 } |
| 81 |
| 78 // Lookup a given channel id. Return -1 if not found. | 82 // Lookup a given channel id. Return -1 if not found. |
| 79 int Lookup(const std::string& channel_id) { | 83 int Lookup(const std::string& channel_id) { |
| 80 AutoLock locked(lock_); | 84 AutoLock locked(lock_); |
| 81 | 85 |
| 82 ChannelToFDMap::const_iterator i = map_.find(channel_id); | 86 ChannelToFDMap::const_iterator i = map_.find(channel_id); |
| 83 if (i == map_.end()) | 87 if (i == map_.end()) |
| 84 return -1; | 88 return -1; |
| 85 return i->second; | 89 return i->second; |
| 86 } | 90 } |
| 87 | 91 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 108 CHECK(i == map_.end()) << "Creating second IPC server (fd " << fd << ") " | 112 CHECK(i == map_.end()) << "Creating second IPC server (fd " << fd << ") " |
| 109 << "for '" << channel_id << "' while first " | 113 << "for '" << channel_id << "' while first " |
| 110 << "(fd " << i->second << ") still exists"; | 114 << "(fd " << i->second << ") still exists"; |
| 111 map_[channel_id] = fd; | 115 map_[channel_id] = fd; |
| 112 } | 116 } |
| 113 | 117 |
| 114 private: | 118 private: |
| 115 Lock lock_; | 119 Lock lock_; |
| 116 typedef std::map<std::string, int> ChannelToFDMap; | 120 typedef std::map<std::string, int> ChannelToFDMap; |
| 117 ChannelToFDMap map_; | 121 ChannelToFDMap map_; |
| 122 |
| 123 friend struct DefaultSingletonTraits<PipeMap>; |
| 118 }; | 124 }; |
| 119 | 125 |
| 120 // Used to map a channel name to the equivalent FD # in the current process. | 126 // Used to map a channel name to the equivalent FD # in the current process. |
| 121 // Returns -1 if the channel is unknown. | 127 // Returns -1 if the channel is unknown. |
| 122 int ChannelNameToFD(const std::string& channel_id) { | 128 int ChannelNameToFD(const std::string& channel_id) { |
| 123 // See the large block comment above PipeMap for the reasoning here. | 129 // See the large block comment above PipeMap for the reasoning here. |
| 124 const int fd = Singleton<PipeMap>()->Lookup(channel_id); | 130 const int fd = PipeMap::GetInstance()->Lookup(channel_id); |
| 125 | 131 |
| 126 if (fd != -1) { | 132 if (fd != -1) { |
| 127 int dup_fd = dup(fd); | 133 int dup_fd = dup(fd); |
| 128 if (dup_fd < 0) | 134 if (dup_fd < 0) |
| 129 PLOG(FATAL) << "dup(" << fd << ")"; | 135 PLOG(FATAL) << "dup(" << fd << ")"; |
| 130 return dup_fd; | 136 return dup_fd; |
| 131 } | 137 } |
| 132 | 138 |
| 133 return fd; | 139 return fd; |
| 134 } | 140 } |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 << " mode"; | 304 << " mode"; |
| 299 } | 305 } |
| 300 } | 306 } |
| 301 | 307 |
| 302 Channel::ChannelImpl::~ChannelImpl() { | 308 Channel::ChannelImpl::~ChannelImpl() { |
| 303 Close(); | 309 Close(); |
| 304 } | 310 } |
| 305 | 311 |
| 306 // static | 312 // static |
| 307 void AddChannelSocket(const std::string& name, int socket) { | 313 void AddChannelSocket(const std::string& name, int socket) { |
| 308 Singleton<PipeMap>()->Insert(name, socket); | 314 PipeMap::GetInstance()->Insert(name, socket); |
| 309 } | 315 } |
| 310 | 316 |
| 311 // static | 317 // static |
| 312 void RemoveAndCloseChannelSocket(const std::string& name) { | 318 void RemoveAndCloseChannelSocket(const std::string& name) { |
| 313 Singleton<PipeMap>()->RemoveAndClose(name); | 319 PipeMap::GetInstance()->RemoveAndClose(name); |
| 314 } | 320 } |
| 315 | 321 |
| 316 // static | 322 // static |
| 317 bool ChannelSocketExists(const std::string& name) { | 323 bool ChannelSocketExists(const std::string& name) { |
| 318 return Singleton<PipeMap>()->Lookup(name) != -1; | 324 return PipeMap::GetInstance()->Lookup(name) != -1; |
| 319 } | 325 } |
| 320 | 326 |
| 321 // static | 327 // static |
| 322 bool SocketPair(int* fd1, int* fd2) { | 328 bool SocketPair(int* fd1, int* fd2) { |
| 323 int pipe_fds[2]; | 329 int pipe_fds[2]; |
| 324 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { | 330 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { |
| 325 PLOG(ERROR) << "socketpair()"; | 331 PLOG(ERROR) << "socketpair()"; |
| 326 return false; | 332 return false; |
| 327 } | 333 } |
| 328 | 334 |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 return false; | 511 return false; |
| 506 } | 512 } |
| 507 } else if (bytes_read == 0) { | 513 } else if (bytes_read == 0) { |
| 508 // The pipe has closed... | 514 // The pipe has closed... |
| 509 return false; | 515 return false; |
| 510 } | 516 } |
| 511 } | 517 } |
| 512 DCHECK(bytes_read); | 518 DCHECK(bytes_read); |
| 513 | 519 |
| 514 if (client_pipe_ != -1) { | 520 if (client_pipe_ != -1) { |
| 515 Singleton<PipeMap>()->RemoveAndClose(pipe_name_); | 521 PipeMap::GetInstance()->RemoveAndClose(pipe_name_); |
| 516 client_pipe_ = -1; | 522 client_pipe_ = -1; |
| 517 } | 523 } |
| 518 | 524 |
| 519 // a pointer to an array of |num_wire_fds| file descriptors from the read | 525 // a pointer to an array of |num_wire_fds| file descriptors from the read |
| 520 const int* wire_fds = NULL; | 526 const int* wire_fds = NULL; |
| 521 unsigned num_wire_fds = 0; | 527 unsigned num_wire_fds = 0; |
| 522 | 528 |
| 523 // walk the list of control messages and, if we find an array of file | 529 // walk the list of control messages and, if we find an array of file |
| 524 // descriptors, save a pointer to the array | 530 // descriptors, save a pointer to the array |
| 525 | 531 |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1014 | 1020 |
| 1015 // Unregister libevent for the FIFO and close it. | 1021 // Unregister libevent for the FIFO and close it. |
| 1016 read_watcher_.StopWatchingFileDescriptor(); | 1022 read_watcher_.StopWatchingFileDescriptor(); |
| 1017 write_watcher_.StopWatchingFileDescriptor(); | 1023 write_watcher_.StopWatchingFileDescriptor(); |
| 1018 if (pipe_ != -1) { | 1024 if (pipe_ != -1) { |
| 1019 if (HANDLE_EINTR(close(pipe_)) < 0) | 1025 if (HANDLE_EINTR(close(pipe_)) < 0) |
| 1020 PLOG(ERROR) << "close"; | 1026 PLOG(ERROR) << "close"; |
| 1021 pipe_ = -1; | 1027 pipe_ = -1; |
| 1022 } | 1028 } |
| 1023 if (client_pipe_ != -1) { | 1029 if (client_pipe_ != -1) { |
| 1024 Singleton<PipeMap>()->RemoveAndClose(pipe_name_); | 1030 PipeMap::GetInstance()->RemoveAndClose(pipe_name_); |
| 1025 client_pipe_ = -1; | 1031 client_pipe_ = -1; |
| 1026 } | 1032 } |
| 1027 #if !defined(OS_MACOSX) | 1033 #if !defined(OS_MACOSX) |
| 1028 if (fd_pipe_ != -1) { | 1034 if (fd_pipe_ != -1) { |
| 1029 if (HANDLE_EINTR(close(fd_pipe_)) < 0) | 1035 if (HANDLE_EINTR(close(fd_pipe_)) < 0) |
| 1030 PLOG(ERROR) << "close"; | 1036 PLOG(ERROR) << "close"; |
| 1031 fd_pipe_ = -1; | 1037 fd_pipe_ = -1; |
| 1032 } | 1038 } |
| 1033 if (remote_fd_pipe_ != -1) { | 1039 if (remote_fd_pipe_ != -1) { |
| 1034 if (HANDLE_EINTR(close(remote_fd_pipe_)) < 0) | 1040 if (HANDLE_EINTR(close(remote_fd_pipe_)) < 0) |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1082 | 1088 |
| 1083 bool Channel::Send(Message* message) { | 1089 bool Channel::Send(Message* message) { |
| 1084 return channel_impl_->Send(message); | 1090 return channel_impl_->Send(message); |
| 1085 } | 1091 } |
| 1086 | 1092 |
| 1087 int Channel::GetClientFileDescriptor() const { | 1093 int Channel::GetClientFileDescriptor() const { |
| 1088 return channel_impl_->GetClientFileDescriptor(); | 1094 return channel_impl_->GetClientFileDescriptor(); |
| 1089 } | 1095 } |
| 1090 | 1096 |
| 1091 } // namespace IPC | 1097 } // namespace IPC |
| OLD | NEW |