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 |