summaryrefslogtreecommitdiffstats
path: root/ipc/ipc_channel_posix.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/ipc_channel_posix.cc')
-rw-r--r--ipc/ipc_channel_posix.cc50
1 files changed, 32 insertions, 18 deletions
diff --git a/ipc/ipc_channel_posix.cc b/ipc/ipc_channel_posix.cc
index a88506c..27c62f5 100644
--- a/ipc/ipc_channel_posix.cc
+++ b/ipc/ipc_channel_posix.cc
@@ -102,15 +102,9 @@ class PipeMap {
// Remove the mapping for the given channel id. No error is signaled if the
// channel_id doesn't exist
- void RemoveAndClose(const std::string& channel_id) {
+ void Remove(const std::string& channel_id) {
base::AutoLock locked(lock_);
-
- ChannelToFDMap::iterator i = map_.find(channel_id);
- if (i != map_.end()) {
- if (HANDLE_EINTR(close(i->second)) < 0)
- PLOG(ERROR) << "close " << channel_id;
- map_.erase(i);
- }
+ map_.erase(channel_id);
}
// Insert a mapping from @channel_id to @fd. It's a fatal error to insert a
@@ -403,7 +397,7 @@ bool Channel::ChannelImpl::CreatePipe(
// Case 3 from comment above.
// We only allow one connection.
local_pipe = HANDLE_EINTR(dup(local_pipe));
- PipeMap::GetInstance()->RemoveAndClose(pipe_name_);
+ PipeMap::GetInstance()->Remove(pipe_name_);
} else {
// Case 4a from comment above.
// Guard against inappropriate reuse of the initial IPC channel. If
@@ -426,6 +420,7 @@ bool Channel::ChannelImpl::CreatePipe(
LOG(ERROR) << "Server already exists for " << pipe_name_;
return false;
}
+ base::AutoLock lock(client_pipe_lock_);
if (!SocketPair(&local_pipe, &client_pipe_))
return false;
PipeMap::GetInstance()->Insert(pipe_name_, client_pipe_);
@@ -529,10 +524,7 @@ bool Channel::ChannelImpl::ProcessIncomingMessages() {
}
DCHECK(bytes_read);
- if (client_pipe_ != -1) {
- PipeMap::GetInstance()->RemoveAndClose(pipe_name_);
- client_pipe_ = -1;
- }
+ CloseClientFileDescriptor();
// a pointer to an array of |num_wire_fds| file descriptors from the read
const int* wire_fds = NULL;
@@ -916,10 +908,31 @@ bool Channel::ChannelImpl::Send(Message* message) {
return true;
}
-int Channel::ChannelImpl::GetClientFileDescriptor() const {
+int Channel::ChannelImpl::GetClientFileDescriptor() {
+ base::AutoLock lock(client_pipe_lock_);
return client_pipe_;
}
+int Channel::ChannelImpl::TakeClientFileDescriptor() {
+ base::AutoLock lock(client_pipe_lock_);
+ int fd = client_pipe_;
+ if (client_pipe_ != -1) {
+ PipeMap::GetInstance()->Remove(pipe_name_);
+ client_pipe_ = -1;
+ }
+ return fd;
+}
+
+void Channel::ChannelImpl::CloseClientFileDescriptor() {
+ base::AutoLock lock(client_pipe_lock_);
+ if (client_pipe_ != -1) {
+ PipeMap::GetInstance()->Remove(pipe_name_);
+ if (HANDLE_EINTR(close(client_pipe_)) < 0)
+ PLOG(ERROR) << "close " << pipe_name_;
+ client_pipe_ = -1;
+ }
+}
+
bool Channel::ChannelImpl::AcceptsConnections() const {
return server_listen_pipe_ != -1;
}
@@ -1173,10 +1186,7 @@ void Channel::ChannelImpl::Close() {
server_listen_connection_watcher_.StopWatchingFileDescriptor();
}
- if (client_pipe_ != -1) {
- PipeMap::GetInstance()->RemoveAndClose(pipe_name_);
- client_pipe_ = -1;
- }
+ CloseClientFileDescriptor();
}
//------------------------------------------------------------------------------
@@ -1210,6 +1220,10 @@ int Channel::GetClientFileDescriptor() const {
return channel_impl_->GetClientFileDescriptor();
}
+int Channel::TakeClientFileDescriptor() {
+ return channel_impl_->TakeClientFileDescriptor();
+}
+
bool Channel::AcceptsConnections() const {
return channel_impl_->AcceptsConnections();
}